gpu: Refactor GpuMemoryBuffer framework for multi-process support.
This removes the ImageFactory interface and adjusts the buffer
allocation system for future multi-process support.
Also includes proper plumbing of internalformat to GLImage implementation
and makes sure the compositor is using the correct format.
TEST=gpu_unittests --gtest_filter=MockGpuMemoryBufferTest.Lifecycle
BUG=261649
Review URL: https://chromiumcodereview.appspot.com/20017005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@218034 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc
index 6344b1f..12288cd 100644
--- a/android_webview/lib/main/aw_main_delegate.cc
+++ b/android_webview/lib/main/aw_main_delegate.cc
@@ -46,7 +46,7 @@
bool AwMainDelegate::BasicStartupComplete(int* exit_code) {
content::SetContentClient(&content_client_);
- gpu::GLInProcessContext::SetGpuMemoryBufferFactory(
+ gpu::InProcessCommandBuffer::SetGpuMemoryBufferFactory(
gpu_memory_buffer_factory_.get());
gpu::InProcessCommandBuffer::EnableVirtualizedContext();
diff --git a/cc/resources/image_raster_worker_pool.cc b/cc/resources/image_raster_worker_pool.cc
index 408459c..7e524f6 100644
--- a/cc/resources/image_raster_worker_pool.cc
+++ b/cc/resources/image_raster_worker_pool.cc
@@ -156,6 +156,10 @@
"state", TracedValue::FromValue(StateAsValue().release()));
}
+GLenum ImageRasterWorkerPool::GetResourceFormat() const {
+ return GL_RGBA; // Only format supported by CHROMIUM_map_image
+}
+
void ImageRasterWorkerPool::OnRasterTasksFinished() {
DCHECK(raster_tasks_pending_);
raster_tasks_pending_ = false;
diff --git a/cc/resources/image_raster_worker_pool.h b/cc/resources/image_raster_worker_pool.h
index d4f4d74d..1816b27 100644
--- a/cc/resources/image_raster_worker_pool.h
+++ b/cc/resources/image_raster_worker_pool.h
@@ -21,6 +21,7 @@
// Overridden from RasterWorkerPool:
virtual void ScheduleTasks(RasterTask::Queue* queue) OVERRIDE;
+ virtual GLenum GetResourceFormat() const OVERRIDE;
virtual void OnRasterTasksFinished() OVERRIDE;
virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE;
diff --git a/cc/resources/pixel_buffer_raster_worker_pool.cc b/cc/resources/pixel_buffer_raster_worker_pool.cc
index a03ed81..7618803 100644
--- a/cc/resources/pixel_buffer_raster_worker_pool.cc
+++ b/cc/resources/pixel_buffer_raster_worker_pool.cc
@@ -236,6 +236,10 @@
"state", TracedValue::FromValue(StateAsValue().release()));
}
+GLenum PixelBufferRasterWorkerPool::GetResourceFormat() const {
+ return resource_provider()->best_texture_format();
+}
+
void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
diff --git a/cc/resources/pixel_buffer_raster_worker_pool.h b/cc/resources/pixel_buffer_raster_worker_pool.h
index d9613f7..9e966d3 100644
--- a/cc/resources/pixel_buffer_raster_worker_pool.h
+++ b/cc/resources/pixel_buffer_raster_worker_pool.h
@@ -29,6 +29,7 @@
// Overridden from RasterWorkerPool:
virtual void ScheduleTasks(RasterTask::Queue* queue) OVERRIDE;
+ virtual GLenum GetResourceFormat() const OVERRIDE;
virtual void OnRasterTasksFinished() OVERRIDE;
virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE;
diff --git a/cc/resources/raster_worker_pool.h b/cc/resources/raster_worker_pool.h
index d0e1e7c..8c4b493 100644
--- a/cc/resources/raster_worker_pool.h
+++ b/cc/resources/raster_worker_pool.h
@@ -13,6 +13,7 @@
#include "cc/resources/raster_mode.h"
#include "cc/resources/tile_priority.h"
#include "cc/resources/worker_pool.h"
+#include "third_party/khronos/GLES2/gl2.h"
class SkDevice;
@@ -183,6 +184,9 @@
// even if they later get canceled by another call to ScheduleTasks().
virtual void ScheduleTasks(RasterTask::Queue* queue) = 0;
+ // Returns the format that needs to be used for raster task resources.
+ virtual GLenum GetResourceFormat() const = 0;
+
// TODO(vmpstr): Figure out an elegant way to not pass this many parameters.
static RasterTask CreateRasterTask(
const Resource* resource,
diff --git a/cc/resources/raster_worker_pool_perftest.cc b/cc/resources/raster_worker_pool_perftest.cc
index a4a258b..9215950 100644
--- a/cc/resources/raster_worker_pool_perftest.cc
+++ b/cc/resources/raster_worker_pool_perftest.cc
@@ -38,6 +38,10 @@
virtual void ScheduleTasks(RasterTask::Queue* queue) OVERRIDE {
NOTREACHED();
}
+ virtual GLenum GetResourceFormat() const OVERRIDE {
+ NOTREACHED();
+ return GL_RGBA;
+ }
virtual void OnRasterTasksFinished() OVERRIDE {
NOTREACHED();
}
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 0db1b4c..0296dd4b 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -1350,6 +1350,7 @@
resource->allocated = true;
WebGraphicsContext3D* context3d = Context3d();
DCHECK(context3d);
+ DCHECK_EQ(static_cast<GLenum>(GL_RGBA), resource->format);
resource->image_id = context3d->createImageCHROMIUM(
resource->size.width(), resource->size.height(), GL_RGBA8_OES);
DCHECK(resource->image_id);
diff --git a/cc/resources/tile_manager.cc b/cc/resources/tile_manager.cc
index cff58830..c8d1e80 100644
--- a/cc/resources/tile_manager.cc
+++ b/cc/resources/tile_manager.cc
@@ -130,8 +130,7 @@
PixelBufferRasterWorkerPool::Create(
resource_provider, num_raster_threads),
num_raster_threads,
- rendering_stats_instrumentation,
- resource_provider->best_texture_format()));
+ rendering_stats_instrumentation));
}
TileManager::TileManager(
@@ -139,8 +138,7 @@
ResourceProvider* resource_provider,
scoped_ptr<RasterWorkerPool> raster_worker_pool,
size_t num_raster_threads,
- RenderingStatsInstrumentation* rendering_stats_instrumentation,
- GLenum texture_format)
+ RenderingStatsInstrumentation* rendering_stats_instrumentation)
: client_(client),
resource_pool_(ResourcePool::Create(resource_provider)),
raster_worker_pool_(raster_worker_pool.Pass()),
@@ -151,8 +149,7 @@
resources_releasable_(0),
ever_exceeded_memory_budget_(false),
rendering_stats_instrumentation_(rendering_stats_instrumentation),
- did_initialize_visible_tile_(false),
- texture_format_(texture_format) {
+ did_initialize_visible_tile_(false) {
raster_worker_pool_->SetClient(this);
}
@@ -732,8 +729,9 @@
ManagedTileState& mts = tile->managed_state();
scoped_ptr<ResourcePool::Resource> resource =
- resource_pool_->AcquireResource(tile->tile_size_.size(),
- texture_format_);
+ resource_pool_->AcquireResource(
+ tile->tile_size_.size(),
+ raster_worker_pool_->GetResourceFormat());
const Resource* const_resource = resource.get();
// Create and queue all image decode tasks that this tile depends on.
diff --git a/cc/resources/tile_manager.h b/cc/resources/tile_manager.h
index 97c4f08..b76bc2f 100644
--- a/cc/resources/tile_manager.h
+++ b/cc/resources/tile_manager.h
@@ -103,8 +103,7 @@
ResourceProvider* resource_provider,
scoped_ptr<RasterWorkerPool> raster_worker_pool,
size_t num_raster_threads,
- RenderingStatsInstrumentation* rendering_stats_instrumentation,
- GLenum texture_format);
+ RenderingStatsInstrumentation* rendering_stats_instrumentation);
// Methods called by Tile
friend class Tile;
@@ -176,8 +175,6 @@
bool did_initialize_visible_tile_;
- GLenum texture_format_;
-
typedef base::hash_map<uint32_t, RasterWorkerPool::Task> PixelRefTaskMap;
typedef base::hash_map<int, PixelRefTaskMap> LayerPixelRefTaskMap;
LayerPixelRefTaskMap image_decode_tasks_;
diff --git a/cc/test/fake_tile_manager.cc b/cc/test/fake_tile_manager.cc
index 9e9e48a..c4f608bb 100644
--- a/cc/test/fake_tile_manager.cc
+++ b/cc/test/fake_tile_manager.cc
@@ -32,6 +32,7 @@
completed_tasks_.pop_front();
}
}
+ virtual GLenum GetResourceFormat() const OVERRIDE { return GL_RGBA; }
virtual void OnRasterTasksFinished() OVERRIDE {}
virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE {}
@@ -47,8 +48,7 @@
NULL,
make_scoped_ptr<RasterWorkerPool>(new FakeRasterWorkerPool),
1,
- NULL,
- GL_RGBA) {}
+ NULL) {}
FakeTileManager::FakeTileManager(TileManagerClient* client,
ResourceProvider* resource_provider)
@@ -56,8 +56,7 @@
resource_provider,
make_scoped_ptr<RasterWorkerPool>(new FakeRasterWorkerPool),
1,
- NULL,
- resource_provider->best_texture_format()) {}
+ NULL) {}
FakeTileManager::~FakeTileManager() {}
diff --git a/gpu/command_buffer/client/client_test_helper.cc b/gpu/command_buffer/client/client_test_helper.cc
index cccfa3b..31a91b2 100644
--- a/gpu/command_buffer/client/client_test_helper.cc
+++ b/gpu/command_buffer/client/client_test_helper.cc
@@ -151,6 +151,12 @@
this, &MockCommandBufferBase::FlushHelper));
}
+MockClientGpuControl::MockClientGpuControl() {
+}
+
+MockClientGpuControl::~MockClientGpuControl() {
+}
+
} // namespace gpu
diff --git a/gpu/command_buffer/client/client_test_helper.h b/gpu/command_buffer/client/client_test_helper.h
index 7010704..e9d6c36 100644
--- a/gpu/command_buffer/client/client_test_helper.h
+++ b/gpu/command_buffer/client/client_test_helper.h
@@ -11,6 +11,7 @@
#include "gpu/command_buffer/common/cmd_buffer_common.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/compiler_specific.h"
+#include "gpu/command_buffer/common/gpu_control.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -81,6 +82,22 @@
void DelegateToFake();
};
+class MockClientGpuControl : public GpuControl {
+ public:
+ MockClientGpuControl();
+ virtual ~MockClientGpuControl();
+
+ MOCK_METHOD4(CreateGpuMemoryBuffer,
+ gfx::GpuMemoryBuffer*(size_t width,
+ size_t height,
+ unsigned internalformat,
+ int32* id));
+ MOCK_METHOD1(DestroyGpuMemoryBuffer, void(int32 id));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockClientGpuControl);
+};
+
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_CLIENT_CLIENT_TEST_HELPER_H_
diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc
index cdbfc9f..f778047 100644
--- a/gpu/command_buffer/client/gl_in_process_context.cc
+++ b/gpu/command_buffer/client/gl_in_process_context.cc
@@ -23,8 +23,6 @@
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gpu_memory_buffer_factory.h"
-#include "gpu/command_buffer/client/image_factory.h"
#include "gpu/command_buffer/client/transfer_buffer.h"
#include "gpu/command_buffer/common/command_buffer.h"
#include "gpu/command_buffer/common/constants.h"
@@ -43,11 +41,8 @@
const size_t kMinTransferBufferSize = 1 * 256 * 1024;
const size_t kMaxTransferBufferSize = 16 * 1024 * 1024;
-static GpuMemoryBufferFactory* g_gpu_memory_buffer_factory = NULL;
-
class GLInProcessContextImpl
: public GLInProcessContext,
- public gles2::ImageFactory,
public base::SupportsWeakPtr<GLInProcessContextImpl> {
public:
explicit GLInProcessContextImpl();
@@ -70,12 +65,6 @@
OVERRIDE;
virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE;
- // ImageFactory implementation:
- virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer(
- int width, int height, GLenum internalformat,
- unsigned* image_id) OVERRIDE;
- virtual void DeleteGpuMemoryBuffer(unsigned image_id) OVERRIDE;
-
private:
void Destroy();
void PollQueryCallbacks();
@@ -108,24 +97,6 @@
return g_all_shared_contexts.Get().size();
}
-scoped_ptr<gfx::GpuMemoryBuffer> GLInProcessContextImpl::CreateGpuMemoryBuffer(
- int width, int height, GLenum internalformat, unsigned int* image_id) {
- scoped_ptr<gfx::GpuMemoryBuffer> buffer(
- g_gpu_memory_buffer_factory->CreateGpuMemoryBuffer(width,
- height,
- internalformat));
- if (!buffer)
- return scoped_ptr<gfx::GpuMemoryBuffer>();
-
- *image_id = command_buffer_->CreateImageForGpuMemoryBuffer(
- buffer->GetHandle(), gfx::Size(width, height));
- return buffer.Pass();
-}
-
-void GLInProcessContextImpl::DeleteGpuMemoryBuffer(unsigned int image_id) {
- command_buffer_->RemoveImage(image_id);
-}
-
GLInProcessContextImpl::GLInProcessContextImpl()
: share_group_id_(0), context_lost_(false) {}
@@ -279,7 +250,7 @@
share_group,
transfer_buffer_.get(),
false,
- this));
+ command_buffer_.get()));
if (share_resources) {
g_all_shared_contexts.Get().insert(this);
@@ -421,11 +392,4 @@
return context.release();
}
-// static
-void GLInProcessContext::SetGpuMemoryBufferFactory(
- GpuMemoryBufferFactory* factory) {
- DCHECK_EQ(0u, SharedContextCount());
- g_gpu_memory_buffer_factory = factory;
-}
-
} // namespace gpu
diff --git a/gpu/command_buffer/client/gl_in_process_context.h b/gpu/command_buffer/client/gl_in_process_context.h
index 09f8140..7e924b5 100644
--- a/gpu/command_buffer/client/gl_in_process_context.h
+++ b/gpu/command_buffer/client/gl_in_process_context.h
@@ -22,8 +22,6 @@
class GLES2Implementation;
}
-class GpuMemoryBufferFactory;
-
// The default uninitialized value is -1.
struct GLES2_IMPL_EXPORT GLInProcessContextAttribs {
GLInProcessContextAttribs();
@@ -42,9 +40,6 @@
public:
virtual ~GLInProcessContext() {}
- // Must be called before any GLInProcessContext instances are created.
- static void SetGpuMemoryBufferFactory(GpuMemoryBufferFactory* factory);
-
// Create a GLInProcessContext, if |is_offscreen| is true, renders to an
// offscreen context. |attrib_list| must be NULL or a NONE-terminated list
// of attribute/value pairs.
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 9285b6d8..5a223b4d 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -86,7 +86,7 @@
ShareGroup* share_group,
TransferBufferInterface* transfer_buffer,
bool bind_generates_resource,
- ImageFactory* image_factory)
+ GpuControl* gpu_control)
: helper_(helper),
transfer_buffer_(transfer_buffer),
angle_pack_reverse_row_order_status_(kUnknownExtensionStatus),
@@ -111,7 +111,7 @@
use_count_(0),
current_query_(NULL),
error_message_callback_(NULL),
- image_factory_(image_factory) {
+ gpu_control_(gpu_control) {
GPU_DCHECK(helper);
GPU_DCHECK(transfer_buffer);
@@ -165,7 +165,7 @@
query_tracker_.reset(new QueryTracker(mapped_memory_.get()));
buffer_tracker_.reset(new BufferTracker(mapped_memory_.get()));
- gpu_memory_buffer_tracker_.reset(new GpuMemoryBufferTracker(image_factory_));
+ gpu_memory_buffer_tracker_.reset(new GpuMemoryBufferTracker(gpu_control_));
#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
GetIdHandler(id_namespaces::kBuffers)->MakeIds(
@@ -2089,7 +2089,7 @@
"GL_CHROMIUM_map_sub "
"GL_CHROMIUM_shallow_flush "
"GL_EXT_unpack_subimage";
- if (image_factory_ != NULL) {
+ if (gpu_control_ != NULL) {
// The first space character is intentional.
str += " GL_CHROMIUM_map_image";
}
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index c2bf49f4..bacb582e 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -20,7 +20,6 @@
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h"
-#include "gpu/command_buffer/client/image_factory.h"
#include "gpu/command_buffer/client/query_tracker.h"
#include "gpu/command_buffer/client/ref_counted.h"
#include "gpu/command_buffer/client/ring_buffer.h"
@@ -98,6 +97,7 @@
namespace gpu {
+class GpuControl;
class MappedMemoryManager;
class ScopedTransferBufferPtr;
class TransferBufferInterface;
@@ -177,7 +177,7 @@
ShareGroup* share_group,
TransferBufferInterface* transfer_buffer,
bool bind_generates_resource,
- ImageFactory* image_factory);
+ GpuControl* gpu_control);
virtual ~GLES2Implementation();
@@ -668,7 +668,7 @@
scoped_ptr<std::string> current_trace_name_;
- ImageFactory* image_factory_;
+ GpuControl* gpu_control_;
DISALLOW_COPY_AND_ASSIGN(GLES2Implementation);
};
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc
index e58907c..0289547b 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest.cc
+++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc
@@ -366,6 +366,8 @@
helper_.reset(new GLES2CmdHelper(command_buffer()));
helper_->Initialize(kCommandBufferSizeBytes);
+ gpu_control_.reset(new StrictMock<MockClientGpuControl>());
+
GLES2Implementation::GLStaticState state;
GLES2Implementation::GLStaticState::IntState& int_state = state.int_state;
int_state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits;
@@ -401,7 +403,7 @@
NULL,
transfer_buffer_.get(),
bind_generates_resource,
- NULL));
+ gpu_control_.get()));
ASSERT_TRUE(gl_->Initialize(
kTransferBufferSize,
kTransferBufferSize,
@@ -473,6 +475,7 @@
Sequence sequence_;
scoped_ptr<MockClientCommandBuffer> command_buffer_;
+ scoped_ptr<MockClientGpuControl> gpu_control_;
scoped_ptr<GLES2CmdHelper> helper_;
scoped_ptr<MockTransferBuffer> transfer_buffer_;
scoped_ptr<GLES2Implementation> gl_;
@@ -2476,7 +2479,8 @@
"GL_CHROMIUM_flipy "
"GL_CHROMIUM_map_sub "
"GL_CHROMIUM_shallow_flush "
- "GL_EXT_unpack_subimage";
+ "GL_EXT_unpack_subimage "
+ "GL_CHROMIUM_map_image";
const char kBad = 0x12;
struct Cmds {
cmd::SetBucketSize set_bucket_size1;
diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc
index c1c9b4d..a957cc4 100644
--- a/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc
+++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc
@@ -6,15 +6,13 @@
#include "base/memory/scoped_ptr.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/image_factory.h"
-#include "ui/gfx/gpu_memory_buffer.h"
+#include "gpu/command_buffer/common/gpu_control.h"
namespace gpu {
namespace gles2 {
-GpuMemoryBufferTracker::GpuMemoryBufferTracker(ImageFactory* factory)
- : buffers_(),
- factory_(factory) {
+GpuMemoryBufferTracker::GpuMemoryBufferTracker(GpuControl* gpu_control)
+ : gpu_control_(gpu_control) {
}
GpuMemoryBufferTracker::~GpuMemoryBufferTracker() {
@@ -23,37 +21,33 @@
}
}
-GLuint GpuMemoryBufferTracker::CreateBuffer(
- GLsizei width, GLsizei height, GLenum internalformat) {
- GLuint image_id = 0;
- DCHECK(factory_);
- scoped_ptr<gfx::GpuMemoryBuffer> buffer =
- factory_->CreateGpuMemoryBuffer(width, height, internalformat, &image_id);
-
- if (buffer.get() == NULL)
+int32 GpuMemoryBufferTracker::CreateBuffer(
+ size_t width, size_t height, int32 internalformat) {
+ int32 image_id = 0;
+ DCHECK(gpu_control_);
+ gfx::GpuMemoryBuffer* buffer = gpu_control_->CreateGpuMemoryBuffer(
+ width, height, internalformat, &image_id);
+ if (!buffer)
return 0;
std::pair<BufferMap::iterator, bool> result =
- buffers_.insert(std::make_pair(image_id, buffer.release()));
+ buffers_.insert(std::make_pair(image_id, buffer));
GPU_DCHECK(result.second);
return image_id;
}
-gfx::GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(GLuint image_id) {
+gfx::GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(int32 image_id) {
BufferMap::iterator it = buffers_.find(image_id);
return (it != buffers_.end()) ? it->second : NULL;
}
-void GpuMemoryBufferTracker::RemoveBuffer(GLuint image_id) {
+void GpuMemoryBufferTracker::RemoveBuffer(int32 image_id) {
BufferMap::iterator buffer_it = buffers_.find(image_id);
- if (buffer_it != buffers_.end()) {
- gfx::GpuMemoryBuffer* buffer = buffer_it->second;
+ if (buffer_it != buffers_.end())
buffers_.erase(buffer_it);
- delete buffer;
- }
- DCHECK(factory_);
- factory_->DeleteGpuMemoryBuffer(image_id);
+ DCHECK(gpu_control_);
+ gpu_control_->DestroyGpuMemoryBuffer(image_id);
}
} // namespace gles2
diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h
index 1192b17..0b07dd0a1 100644
--- a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h
+++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h
@@ -5,8 +5,6 @@
#ifndef GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_TRACKER_H_
#define GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_TRACKER_H_
-#include <GLES2/gl2.h>
-
#include "base/basictypes.h"
#include "gles2_impl_export.h"
#include "gpu/command_buffer/client/hash_tables.h"
@@ -16,25 +14,24 @@
}
namespace gpu {
+class GpuControl;
+
namespace gles2 {
-class ImageFactory;
// Tracks GPU memory buffer objects on the client side.
class GLES2_IMPL_EXPORT GpuMemoryBufferTracker {
public:
- // Ownership of |factory| remains with caller.
- explicit GpuMemoryBufferTracker(ImageFactory* factory);
+ explicit GpuMemoryBufferTracker(GpuControl* gpu_control);
virtual ~GpuMemoryBufferTracker();
- GLuint CreateBuffer(
- GLsizei width, GLsizei height, GLenum internalformat);
- gfx::GpuMemoryBuffer* GetBuffer(GLuint image_id);
- void RemoveBuffer(GLuint image_id);
+ int32 CreateBuffer(size_t width, size_t height, int32 internalformat);
+ gfx::GpuMemoryBuffer* GetBuffer(int32 image_id);
+ void RemoveBuffer(int32 image_id);
private:
- typedef gpu::hash_map<GLuint, gfx::GpuMemoryBuffer*> BufferMap;
+ typedef gpu::hash_map<int32, gfx::GpuMemoryBuffer*> BufferMap;
BufferMap buffers_;
- ImageFactory* factory_;
+ GpuControl* gpu_control_;
DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferTracker);
};
diff --git a/gpu/command_buffer/client/image_factory.h b/gpu/command_buffer/client/image_factory.h
deleted file mode 100644
index 449c8a4..0000000
--- a/gpu/command_buffer/client/image_factory.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef GPU_COMMAND_BUFFER_CLIENT_IMAGE_FACTORY_H_
-#define GPU_COMMAND_BUFFER_CLIENT_IMAGE_FACTORY_H_
-
-#include <GLES2/gl2.h>
-
-#include "base/memory/scoped_ptr.h"
-#include "gles2_impl_export.h"
-
-namespace gfx {
-class GpuMemoryBuffer;
-}
-
-namespace gpu {
-namespace gles2 {
-
-class GLES2_IMPL_EXPORT ImageFactory {
-
- public:
- virtual ~ImageFactory() {}
-
- // Create a GpuMemoryBuffer and makes it available to the
- // service side by inserting it to the ImageManager.
- virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer(
- int width, int height, GLenum internalformat, unsigned* image_id) = 0;
- virtual void DeleteGpuMemoryBuffer(unsigned image_id) = 0;
-};
-
-} // namespace gles2
-} // namespace gpu
-
-#endif // GPU_COMMAND_BUFFER_CLIENT_IMAGE_FACTORY_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h
index 37c7a53..76bb3fe 100644
--- a/gpu/command_buffer/common/gles2_cmd_format.h
+++ b/gpu/command_buffer/common/gles2_cmd_format.h
@@ -56,7 +56,6 @@
kTextures,
kQueries,
kVertexArrays,
- kImages,
kNumIdNamespaces
};
diff --git a/gpu/command_buffer/common/gpu_control.h b/gpu/command_buffer/common/gpu_control.h
new file mode 100644
index 0000000..5534ca78
--- /dev/null
+++ b/gpu/command_buffer/common/gpu_control.h
@@ -0,0 +1,39 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_COMMON_GPU_CONTROL_H_
+#define GPU_COMMAND_BUFFER_COMMON_GPU_CONTROL_H_
+
+#include "gpu/gpu_export.h"
+
+namespace gfx {
+class GpuMemoryBuffer;
+}
+
+namespace gpu {
+
+// Common interface for GpuControl implementations.
+class GPU_EXPORT GpuControl {
+ public:
+ GpuControl() {}
+ virtual ~GpuControl() {}
+
+ // Create a gpu memory buffer of the given dimensions and format. Returns
+ // its ID or -1 on error.
+ virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
+ size_t width,
+ size_t height,
+ unsigned internalformat,
+ int32* id) = 0;
+
+ // Destroy a gpu memory buffer. The ID must be positive.
+ virtual void DestroyGpuMemoryBuffer(int32 id) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GpuControl);
+};
+
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_COMMON_GPU_CONTROL_H_
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index 0cf991a..90932fb 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -67,7 +67,6 @@
id_namespaces_[id_namespaces::kTextures].reset(new IdAllocator);
id_namespaces_[id_namespaces::kQueries].reset(new IdAllocator);
id_namespaces_[id_namespaces::kVertexArrays].reset(new IdAllocator);
- id_namespaces_[id_namespaces::kImages].reset(new IdAllocator);
}
static void GetIntegerv(GLenum pname, uint32* var) {
diff --git a/gpu/command_buffer/service/gpu_control_service.cc b/gpu/command_buffer/service/gpu_control_service.cc
new file mode 100644
index 0000000..d368ff92
--- /dev/null
+++ b/gpu/command_buffer/service/gpu_control_service.cc
@@ -0,0 +1,74 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/gpu_control_service.h"
+
+#include "gpu/command_buffer/client/gpu_memory_buffer_factory.h"
+#include "gpu/command_buffer/service/gpu_memory_buffer_manager.h"
+
+namespace gpu {
+
+GpuControlService::GpuControlService(
+ GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager,
+ GpuMemoryBufferFactory* gpu_memory_buffer_factory)
+ : gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
+ gpu_memory_buffer_factory_(gpu_memory_buffer_factory) {
+}
+
+GpuControlService::~GpuControlService() {
+}
+
+gfx::GpuMemoryBuffer* GpuControlService::CreateGpuMemoryBuffer(
+ size_t width,
+ size_t height,
+ unsigned internalformat,
+ int32* id) {
+ *id = -1;
+
+ CHECK(gpu_memory_buffer_factory_) << "No GPU memory buffer factory provided";
+ linked_ptr<gfx::GpuMemoryBuffer> buffer = make_linked_ptr(
+ gpu_memory_buffer_factory_->CreateGpuMemoryBuffer(width,
+ height,
+ internalformat));
+ if (!buffer.get())
+ return NULL;
+
+ static int32 next_id = 1;
+ *id = next_id++;
+
+ if (!RegisterGpuMemoryBuffer(*id,
+ buffer->GetHandle(),
+ width,
+ height,
+ internalformat)) {
+ *id = -1;
+ return NULL;
+ }
+
+ gpu_memory_buffers_[*id] = buffer;
+ return buffer.get();
+}
+
+void GpuControlService::DestroyGpuMemoryBuffer(int32 id) {
+ GpuMemoryBufferMap::iterator it = gpu_memory_buffers_.find(id);
+ if (it != gpu_memory_buffers_.end())
+ gpu_memory_buffers_.erase(it);
+
+ gpu_memory_buffer_manager_->DestroyGpuMemoryBuffer(id);
+}
+
+bool GpuControlService::RegisterGpuMemoryBuffer(
+ int32 id,
+ gfx::GpuMemoryBufferHandle buffer,
+ size_t width,
+ size_t height,
+ unsigned internalformat) {
+ return gpu_memory_buffer_manager_->RegisterGpuMemoryBuffer(id,
+ buffer,
+ width,
+ height,
+ internalformat);
+}
+
+} // namespace gpu
diff --git a/gpu/command_buffer/service/gpu_control_service.h b/gpu/command_buffer/service/gpu_control_service.h
new file mode 100644
index 0000000..a12fee46
--- /dev/null
+++ b/gpu/command_buffer/service/gpu_control_service.h
@@ -0,0 +1,51 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_CONTROL_SERVICE_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GPU_CONTROL_SERVICE_H_
+
+#include <map>
+
+#include "base/memory/linked_ptr.h"
+#include "gpu/command_buffer/common/gpu_control.h"
+#include "ui/gfx/gpu_memory_buffer.h"
+
+namespace gpu {
+class GpuMemoryBufferFactory;
+class GpuMemoryBufferManagerInterface;
+
+class GPU_EXPORT GpuControlService : public GpuControl {
+ public:
+ GpuControlService(GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager,
+ GpuMemoryBufferFactory* gpu_memory_buffer_factory);
+ virtual ~GpuControlService();
+
+ // Overridden from GpuControl:
+ virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
+ size_t width,
+ size_t height,
+ unsigned internalformat,
+ int32* id) OVERRIDE;
+ virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
+
+ // Register an existing gpu memory buffer and get an ID that can be used
+ // to identify it in the command buffer.
+ bool RegisterGpuMemoryBuffer(int32 id,
+ gfx::GpuMemoryBufferHandle buffer,
+ size_t width,
+ size_t height,
+ unsigned internalformat);
+
+ private:
+ GpuMemoryBufferManagerInterface* gpu_memory_buffer_manager_;
+ GpuMemoryBufferFactory* gpu_memory_buffer_factory_;
+ typedef std::map<int32, linked_ptr<gfx::GpuMemoryBuffer> > GpuMemoryBufferMap;
+ GpuMemoryBufferMap gpu_memory_buffers_;
+
+ DISALLOW_COPY_AND_ASSIGN(GpuControlService);
+};
+
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_CONTROL_SERVICE_H_
diff --git a/gpu/command_buffer/service/gpu_memory_buffer_manager.h b/gpu/command_buffer/service/gpu_memory_buffer_manager.h
new file mode 100644
index 0000000..fb44ede
--- /dev/null
+++ b/gpu/command_buffer/service/gpu_memory_buffer_manager.h
@@ -0,0 +1,28 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_MEMORY_BUFFER_MANAGER_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GPU_MEMORY_BUFFER_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "gpu/gpu_export.h"
+#include "ui/gfx/gpu_memory_buffer.h"
+
+namespace gpu {
+
+class GPU_EXPORT GpuMemoryBufferManagerInterface {
+ public:
+ virtual ~GpuMemoryBufferManagerInterface() {}
+
+ virtual bool RegisterGpuMemoryBuffer(int32 id,
+ gfx::GpuMemoryBufferHandle buffer,
+ size_t width,
+ size_t height,
+ unsigned internalformat) = 0;
+ virtual void DestroyGpuMemoryBuffer(int32 id) = 0;
+};
+
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_MEMORY_BUFFER_MANAGER_H_
diff --git a/gpu/command_buffer/service/image_manager.cc b/gpu/command_buffer/service/image_manager.cc
index 6be4e66..a09af15 100644
--- a/gpu/command_buffer/service/image_manager.cc
+++ b/gpu/command_buffer/service/image_manager.cc
@@ -15,6 +15,36 @@
ImageManager::~ImageManager() {
}
+bool ImageManager::RegisterGpuMemoryBuffer(int32 id,
+ gfx::GpuMemoryBufferHandle buffer,
+ size_t width,
+ size_t height,
+ unsigned internalformat) {
+ if (id <= 0) {
+ DVLOG(0) << "Cannot register GPU memory buffer with non-positive ID.";
+ return false;
+ }
+
+ if (LookupImage(id)) {
+ DVLOG(0) << "GPU memory buffer ID already in use.";
+ return false;
+ }
+
+ scoped_refptr<gfx::GLImage> gl_image =
+ gfx::GLImage::CreateGLImageForGpuMemoryBuffer(buffer,
+ gfx::Size(width, height),
+ internalformat);
+ if (!gl_image)
+ return false;
+
+ AddImage(gl_image.get(), id);
+ return true;
+}
+
+void ImageManager::DestroyGpuMemoryBuffer(int32 id) {
+ RemoveImage(id);
+}
+
void ImageManager::AddImage(gfx::GLImage* image, int32 service_id) {
gl_images_[service_id] = image;
}
diff --git a/gpu/command_buffer/service/image_manager.h b/gpu/command_buffer/service/image_manager.h
index 1b42146..a125ae80 100644
--- a/gpu/command_buffer/service/image_manager.h
+++ b/gpu/command_buffer/service/image_manager.h
@@ -8,6 +8,7 @@
#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
+#include "gpu/command_buffer/service/gpu_memory_buffer_manager.h"
#include "gpu/gpu_export.h"
namespace gfx {
@@ -18,10 +19,20 @@
namespace gles2 {
// Interface used by the cmd decoder to lookup images.
-class GPU_EXPORT ImageManager : public base::RefCounted<ImageManager> {
+class GPU_EXPORT ImageManager
+ : public GpuMemoryBufferManagerInterface,
+ public base::RefCounted<ImageManager> {
public:
ImageManager();
+ // Overridden from GpuMemoryBufferManagerInterface:
+ virtual bool RegisterGpuMemoryBuffer(int32 id,
+ gfx::GpuMemoryBufferHandle buffer,
+ size_t width,
+ size_t height,
+ unsigned internalformat) OVERRIDE;
+ virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
+
void AddImage(gfx::GLImage* gl_image, int32 service_id);
void RemoveImage(int32 service_id);
gfx::GLImage* LookupImage(int32 service_id);
@@ -29,7 +40,7 @@
private:
friend class base::RefCounted<ImageManager>;
- ~ImageManager();
+ virtual ~ImageManager();
typedef base::hash_map<uint32, scoped_refptr<gfx::GLImage> > GLImageMap;
GLImageMap gl_images_;
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index ccbfb32..2f949c9 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -22,10 +22,10 @@
#include "base/message_loop/message_loop_proxy.h"
#include "base/sequence_checker.h"
#include "base/threading/thread.h"
-#include "gpu/command_buffer/common/id_allocator.h"
#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gl_context_virtual.h"
+#include "gpu/command_buffer/service/gpu_control_service.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/transfer_buffer_manager.h"
@@ -43,6 +43,7 @@
static bool g_use_virtualized_gl_context = false;
static bool g_uses_explicit_scheduling = false;
+static GpuMemoryBufferFactory* g_gpu_memory_buffer_factory = NULL;
template <typename T>
static void RunTaskWithResult(base::Callback<T(void)> task,
@@ -390,6 +391,10 @@
&GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler_.get())));
command_buffer_ = command_buffer.Pass();
+ gpu_control_.reset(
+ new GpuControlService(decoder_->GetContextGroup()->image_manager(),
+ g_gpu_memory_buffer_factory));
+
decoder_->set_engine(gpu_scheduler_.get());
if (!surface_) {
@@ -496,55 +501,6 @@
sequence_checker_->CalledOnValidSequencedThread());
}
-unsigned int InProcessCommandBuffer::CreateImageForGpuMemoryBuffer(
- gfx::GpuMemoryBufferHandle buffer,
- gfx::Size size) {
- CheckSequencedThread();
- unsigned int image_id;
- {
- // TODO: ID allocation should go through CommandBuffer
- base::AutoLock lock(command_buffer_lock_);
- gles2::ContextGroup* group = decoder_->GetContextGroup();
- image_id =
- group->GetIdAllocator(gles2::id_namespaces::kImages)->AllocateID();
- }
- base::Closure image_task =
- base::Bind(&InProcessCommandBuffer::CreateImageOnGpuThread,
- base::Unretained(this), buffer, size, image_id);
- QueueTask(image_task);
- return image_id;
-}
-
-void InProcessCommandBuffer::CreateImageOnGpuThread(
- gfx::GpuMemoryBufferHandle buffer,
- gfx::Size size,
- unsigned int image_id) {
- CheckSequencedThread();
- scoped_refptr<gfx::GLImage> gl_image =
- gfx::GLImage::CreateGLImageForGpuMemoryBuffer(buffer, size);
- decoder_->GetContextGroup()->image_manager()->AddImage(gl_image, image_id);
-}
-
-void InProcessCommandBuffer::RemoveImage(unsigned int image_id) {
- CheckSequencedThread();
- {
- // TODO: ID allocation should go through CommandBuffer
- base::AutoLock lock(command_buffer_lock_);
- gles2::ContextGroup* group = decoder_->GetContextGroup();
- group->GetIdAllocator(gles2::id_namespaces::kImages)->FreeID(image_id);
- }
- base::Closure image_manager_task =
- base::Bind(&InProcessCommandBuffer::RemoveImageOnGpuThread,
- base::Unretained(this),
- image_id);
- QueueTask(image_manager_task);
-}
-
-void InProcessCommandBuffer::RemoveImageOnGpuThread(unsigned int image_id) {
- CheckSequencedThread();
- decoder_->GetContextGroup()->image_manager()->RemoveImage(image_id);
-}
-
void InProcessCommandBuffer::OnContextLost() {
CheckSequencedThread();
if (!context_lost_callback_.is_null()) {
@@ -680,6 +636,28 @@
QueueTask(WrapCallback(callback));
}
+gfx::GpuMemoryBuffer* InProcessCommandBuffer::CreateGpuMemoryBuffer(
+ size_t width,
+ size_t height,
+ unsigned internalformat,
+ int32* id) {
+ CheckSequencedThread();
+ base::AutoLock lock(command_buffer_lock_);
+ return gpu_control_->CreateGpuMemoryBuffer(width,
+ height,
+ internalformat,
+ id);
+}
+
+void InProcessCommandBuffer::DestroyGpuMemoryBuffer(int32 id) {
+ CheckSequencedThread();
+ base::Closure task = base::Bind(&GpuControl::DestroyGpuMemoryBuffer,
+ base::Unretained(gpu_control_.get()),
+ id);
+
+ QueueTask(task);
+}
+
gpu::error::Error InProcessCommandBuffer::GetLastError() {
CheckSequencedThread();
return last_state_.error;
@@ -753,4 +731,10 @@
g_gpu_queue.Get().RunTasks();
}
+// static
+void InProcessCommandBuffer::SetGpuMemoryBufferFactory(
+ GpuMemoryBufferFactory* factory) {
+ g_gpu_memory_buffer_factory = factory;
+}
+
} // namespace gpu
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index 9bdbd49..03c0f42 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -14,6 +14,7 @@
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "gpu/command_buffer/common/command_buffer.h"
+#include "gpu/command_buffer/common/gpu_control.h"
#include "gpu/gpu_export.h"
#include "ui/gfx/gpu_memory_buffer.h"
#include "ui/gfx/native_widget_types.h"
@@ -26,7 +27,6 @@
namespace gfx {
class GLContext;
-class GLImage;
class GLSurface;
class Size;
}
@@ -37,6 +37,7 @@
class GLES2Decoder;
}
+class GpuMemoryBufferFactory;
class GpuScheduler;
class TransferBufferManagerInterface;
@@ -44,7 +45,8 @@
// example GPU thread) when being run in single process mode.
// However, the behavior for accessing one context (i.e. one instance of this
// class) from different client threads is undefined.
-class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer {
+class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer,
+ public GpuControl {
public:
InProcessCommandBuffer();
virtual ~InProcessCommandBuffer();
@@ -61,6 +63,7 @@
static void ProcessGpuWorkOnCurrentThread();
static void EnableVirtualizedContext();
+ static void SetGpuMemoryBufferFactory(GpuMemoryBufferFactory* factory);
// If |surface| is not NULL, use it directly; in this case, the command
// buffer gpu thread must be the same as the client thread. Otherwise create
@@ -78,10 +81,6 @@
void Destroy();
void SignalSyncPoint(unsigned sync_point,
const base::Closure& callback);
- unsigned int CreateImageForGpuMemoryBuffer(
- gfx::GpuMemoryBufferHandle buffer,
- gfx::Size size);
- void RemoveImage(unsigned int image_id);
// CommandBuffer implementation:
virtual bool Initialize() OVERRIDE;
@@ -102,6 +101,14 @@
virtual uint32 InsertSyncPoint() OVERRIDE;
virtual gpu::error::Error GetLastError() OVERRIDE;
+ // GpuControl implementation:
+ virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer(
+ size_t width,
+ size_t height,
+ unsigned internalformat,
+ int32* id) OVERRIDE;
+ virtual void DestroyGpuMemoryBuffer(int32 id) OVERRIDE;
+
// The serializer interface to the GPU service (i.e. thread).
class SchedulerClient {
public:
@@ -118,10 +125,6 @@
gfx::GpuPreference gpu_preference);
bool DestroyOnGpuThread();
void FlushOnGpuThread(int32 put_offset);
- void CreateImageOnGpuThread(gfx::GpuMemoryBufferHandle buffer,
- gfx::Size size,
- unsigned int image_id);
- void RemoveImageOnGpuThread(unsigned int image_id);
bool MakeCurrent();
bool IsContextLost();
base::Closure WrapCallback(const base::Closure& callback);
@@ -158,6 +161,7 @@
scoped_ptr<SchedulerClient> queue_;
State state_after_last_flush_;
base::Lock state_after_last_flush_lock_;
+ scoped_ptr<GpuControl> gpu_control_;
// Only used with explicit scheduling and the gpu thread is the same as
// the client thread.
diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc
index 9c9d5ab..91fbc6ae 100644
--- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc
+++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc
@@ -11,6 +11,8 @@
#include "base/memory/ref_counted.h"
#include "base/process/process_handle.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
+#include "gpu/command_buffer/client/gpu_memory_buffer_factory.h"
+#include "gpu/command_buffer/service/command_buffer_service.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/tests/gl_manager.h"
#include "gpu/command_buffer/tests/gl_test_utils.h"
@@ -51,24 +53,16 @@
DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBuffer);
};
-class MockImageFactory : public ImageFactory {
+class MockGpuMemoryBufferFactory : public GpuMemoryBufferFactory {
public:
- MockImageFactory(ImageManager* image_manager) {}
- virtual ~MockImageFactory() {}
+ MockGpuMemoryBufferFactory() {}
+ virtual ~MockGpuMemoryBufferFactory() {}
- MOCK_METHOD4(CreateGpuMemoryBufferMock, gfx::GpuMemoryBuffer*(
- int width, int height, GLenum internalformat, unsigned* image_id));
- MOCK_METHOD1(DeleteGpuMemoryBuffer, void(unsigned));
- // Workaround for mocking methods that return scoped_ptrs
- virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer(
- int width, int height, GLenum internalformat,
- unsigned* image_id) OVERRIDE {
- return scoped_ptr<gfx::GpuMemoryBuffer>(CreateGpuMemoryBufferMock(
- width, height, internalformat, image_id));
- }
+ MOCK_METHOD3(CreateGpuMemoryBuffer,
+ gfx::GpuMemoryBuffer*(size_t, size_t, unsigned));
private:
- DISALLOW_COPY_AND_ASSIGN(MockImageFactory);
+ DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBufferFactory);
};
class MockGpuMemoryBufferTest : public testing::Test {
@@ -76,10 +70,9 @@
virtual void SetUp() {
GLManager::Options options;
image_manager_ = new ImageManager;
- image_factory_.reset(
- new StrictMock<MockImageFactory>(image_manager_.get()));
+ gpu_memory_buffer_factory_.reset(new MockGpuMemoryBufferFactory);
options.image_manager = image_manager_.get();
- options.image_factory = image_factory_.get();
+ options.gpu_memory_buffer_factory = gpu_memory_buffer_factory_.get();
gl_.Initialize(options);
gl_.MakeCurrent();
@@ -108,8 +101,8 @@
gl_.Destroy();
}
- scoped_ptr<StrictMock<MockImageFactory> > image_factory_;
scoped_refptr<ImageManager> image_manager_;
+ scoped_ptr<MockGpuMemoryBufferFactory> gpu_memory_buffer_factory_;
GLManager gl_;
GLuint texture_ids_[2];
GLuint framebuffer_id_;
@@ -133,29 +126,21 @@
handle.type = gfx::SHARED_MEMORY_BUFFER;
handle.handle = duped_shared_memory_handle;
- const GLuint kImageId = 345u;
-
- EXPECT_CALL(*image_factory_.get(), CreateGpuMemoryBufferMock(
- kImageWidth, kImageHeight, GL_RGBA8_OES, _))
+ EXPECT_CALL(*gpu_memory_buffer_factory_.get(), CreateGpuMemoryBuffer(
+ kImageWidth, kImageHeight, GL_RGBA8_OES))
.Times(1)
- .WillOnce(DoAll(SetArgPointee<3>(kImageId), Return(gpu_memory_buffer)))
+ .WillOnce(Return(gpu_memory_buffer))
.RetiresOnSaturation();
-
- // Create the GLImage and insert it into the ImageManager, which
- // would be done within CreateGpuMemoryBufferMock if it weren't a mock.
- GLuint image_id = glCreateImageCHROMIUM(
- kImageWidth, kImageHeight, GL_RGBA8_OES);
- EXPECT_EQ(kImageId, image_id);
-
EXPECT_CALL(*gpu_memory_buffer, GetHandle())
+ .Times(1)
.WillOnce(Return(handle))
.RetiresOnSaturation();
- gfx::Size size(kImageWidth, kImageHeight);
- scoped_refptr<gfx::GLImage> gl_image(
- gfx::GLImage::CreateGLImageForGpuMemoryBuffer(
- gpu_memory_buffer->GetHandle(), size));
- image_manager_->AddImage(gl_image.get(), image_id);
+ // Create the image. This should add the image ID to the ImageManager.
+ GLuint image_id = glCreateImageCHROMIUM(
+ kImageWidth, kImageHeight, GL_RGBA8_OES);
+ EXPECT_NE(0u, image_id);
+ EXPECT_TRUE(image_manager_->LookupImage(image_id) != NULL);
EXPECT_CALL(*gpu_memory_buffer, IsMapped())
.WillOnce(Return(false))
@@ -217,11 +202,6 @@
EXPECT_CALL(*gpu_memory_buffer, Die())
.Times(1)
.RetiresOnSaturation();
-
- EXPECT_CALL(*image_factory_.get(), DeleteGpuMemoryBuffer(image_id))
- .Times(1)
- .RetiresOnSaturation();
-
glDestroyImageCHROMIUM(image_id);
}
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 54ff645..2c48164 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -17,6 +17,7 @@
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gl_context_virtual.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/service/gpu_control_service.h"
#include "gpu/command_buffer/service/gpu_scheduler.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
@@ -39,8 +40,7 @@
virtual_manager(NULL),
bind_generates_resource(false),
context_lost_allowed(false),
- image_manager(NULL),
- image_factory(NULL) {
+ image_manager(NULL) {
}
GLManager::GLManager()
@@ -132,6 +132,10 @@
ASSERT_TRUE(command_buffer_->Initialize())
<< "could not create command buffer service";
+ gpu_control_.reset(
+ new GpuControlService(decoder_->GetContextGroup()->image_manager(),
+ options.gpu_memory_buffer_factory));
+
gpu_scheduler_.reset(new GpuScheduler(command_buffer_.get(),
decoder_.get(),
decoder_.get()));
@@ -189,7 +193,7 @@
client_share_group,
transfer_buffer_.get(),
options.bind_generates_resource,
- options.image_factory));
+ gpu_control_.get()));
ASSERT_TRUE(gles2_implementation_->Initialize(
kStartTransferBufferSize,
diff --git a/gpu/command_buffer/tests/gl_manager.h b/gpu/command_buffer/tests/gl_manager.h
index a53aa4096..8a811fdf7 100644
--- a/gpu/command_buffer/tests/gl_manager.h
+++ b/gpu/command_buffer/tests/gl_manager.h
@@ -21,8 +21,10 @@
namespace gpu {
class CommandBufferService;
-class TransferBuffer;
+class GpuControlService;
+class GpuMemoryBufferFactory;
class GpuScheduler;
+class TransferBuffer;
namespace gles2 {
@@ -55,8 +57,8 @@
bool context_lost_allowed;
// Image manager to be used.
gles2::ImageManager* image_manager;
- // Image factory to be used.
- gles2::ImageFactory* image_factory;
+ // GpuMemoryBuffer factory to be used.
+ GpuMemoryBufferFactory* gpu_memory_buffer_factory;
};
GLManager();
~GLManager();
@@ -98,6 +100,7 @@
scoped_refptr<gles2::MailboxManager> mailbox_manager_;
scoped_refptr<gfx::GLShareGroup> share_group_;
scoped_ptr<CommandBufferService> command_buffer_;
+ scoped_ptr<GpuControlService> gpu_control_;
scoped_ptr<gles2::GLES2Decoder> decoder_;
scoped_ptr<GpuScheduler> gpu_scheduler_;
scoped_refptr<gfx::GLSurface> surface_;
diff --git a/gpu/command_buffer_common.gypi b/gpu/command_buffer_common.gypi
index 85431e49..55e825e 100644
--- a/gpu/command_buffer_common.gypi
+++ b/gpu/command_buffer_common.gypi
@@ -21,6 +21,7 @@
'command_buffer/common/gles2_cmd_format_autogen.h',
'command_buffer/common/gles2_cmd_format.cc',
'command_buffer/common/gles2_cmd_format.h',
+ 'command_buffer/common/gpu_control.h',
'command_buffer/common/id_allocator.cc',
'command_buffer/common/id_allocator.h',
'command_buffer/common/mailbox.cc',
diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi
index f8e94c1..d9408b6f 100644
--- a/gpu/command_buffer_service.gypi
+++ b/gpu/command_buffer_service.gypi
@@ -75,13 +75,16 @@
'command_buffer/service/gl_state_restorer_impl.cc',
'command_buffer/service/gl_state_restorer_impl.h',
'command_buffer/service/gl_utils.h',
- 'command_buffer/service/gpu_scheduler.h',
+ 'command_buffer/service/gpu_control_service.cc',
+ 'command_buffer/service/gpu_control_service.h',
+ 'command_buffer/service/gpu_memory_buffer_manager.h',
'command_buffer/service/gpu_scheduler.cc',
+ 'command_buffer/service/gpu_scheduler.h',
'command_buffer/service/gpu_scheduler_mock.h',
- 'command_buffer/service/gpu_switches.h',
'command_buffer/service/gpu_switches.cc',
- 'command_buffer/service/gpu_tracer.h',
+ 'command_buffer/service/gpu_switches.h',
'command_buffer/service/gpu_tracer.cc',
+ 'command_buffer/service/gpu_tracer.h',
'command_buffer/service/id_manager.h',
'command_buffer/service/id_manager.cc',
'command_buffer/service/image_manager.cc',
diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi
index da2be68..015d9c6e 100644
--- a/gpu/gpu_common.gypi
+++ b/gpu/gpu_common.gypi
@@ -39,7 +39,6 @@
'command_buffer/client/gpu_memory_buffer_factory.h',
'command_buffer/client/gpu_memory_buffer_tracker.cc',
'command_buffer/client/gpu_memory_buffer_tracker.h',
- 'command_buffer/client/image_factory.h',
'command_buffer/client/program_info_manager.cc',
'command_buffer/client/program_info_manager.h',
'command_buffer/client/query_tracker.cc',
diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h
index f1d0537..8d59bc4 100644
--- a/ui/gl/gl_image.h
+++ b/ui/gl/gl_image.h
@@ -38,7 +38,9 @@
// Create a GL image for a GPU Memory buffer.
static scoped_refptr<GLImage> CreateGLImageForGpuMemoryBuffer(
- gfx::GpuMemoryBufferHandle buffer, gfx::Size size);
+ gfx::GpuMemoryBufferHandle buffer,
+ gfx::Size size,
+ unsigned internalformat);
protected:
virtual ~GLImage();
diff --git a/ui/gl/gl_image_android.cc b/ui/gl/gl_image_android.cc
index fe871e7b..e56dc2d0 100644
--- a/ui/gl/gl_image_android.cc
+++ b/ui/gl/gl_image_android.cc
@@ -26,13 +26,16 @@
}
scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer(
- gfx::GpuMemoryBufferHandle buffer, gfx::Size size) {
+ gfx::GpuMemoryBufferHandle buffer,
+ gfx::Size size,
+ unsigned internalformat) {
TRACE_EVENT0("gpu", "GLImage::CreateGLImageForGpuMemoryBuffer");
switch (GetGLImplementation()) {
case kGLImplementationEGLGLES2:
switch (buffer.type) {
case SHARED_MEMORY_BUFFER: {
- scoped_refptr<GLImageShm> image(new GLImageShm(size));
+ scoped_refptr<GLImageShm> image(
+ new GLImageShm(size, internalformat));
if (!image->Initialize(buffer))
return NULL;
diff --git a/ui/gl/gl_image_mac.cc b/ui/gl/gl_image_mac.cc
index b244a22a..04dc61e 100644
--- a/ui/gl/gl_image_mac.cc
+++ b/ui/gl/gl_image_mac.cc
@@ -27,7 +27,9 @@
}
scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer(
- gfx::GpuMemoryBufferHandle buffer, gfx::Size size) {
+ gfx::GpuMemoryBufferHandle buffer,
+ gfx::Size size,
+ unsigned internalformat) {
TRACE_EVENT0("gpu", "GLImage::CreateGLImageForGpuMemoryBuffer");
switch (GetGLImplementation()) {
case kGLImplementationOSMesaGL:
@@ -35,7 +37,8 @@
case kGLImplementationAppleGL:
switch (buffer.type) {
case SHARED_MEMORY_BUFFER: {
- scoped_refptr<GLImageShm> image(new GLImageShm(size));
+ scoped_refptr<GLImageShm> image(
+ new GLImageShm(size, internalformat));
if (!image->Initialize(buffer))
return NULL;
diff --git a/ui/gl/gl_image_ozone.cc b/ui/gl/gl_image_ozone.cc
index c217f99..a1c13296 100644
--- a/ui/gl/gl_image_ozone.cc
+++ b/ui/gl/gl_image_ozone.cc
@@ -27,7 +27,9 @@
}
scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer(
- gfx::GpuMemoryBufferHandle buffer, gfx::Size size) {
+ gfx::GpuMemoryBufferHandle buffer,
+ gfx::Size size,
+ unsigned internalformat) {
TRACE_EVENT0("gpu", "GLImage::CreateGLImageForGpuMemoryBuffer");
switch (GetGLImplementation()) {
case kGLImplementationOSMesaGL:
diff --git a/ui/gl/gl_image_shm.cc b/ui/gl/gl_image_shm.cc
index 14ed836..78e81649 100644
--- a/ui/gl/gl_image_shm.cc
+++ b/ui/gl/gl_image_shm.cc
@@ -10,7 +10,11 @@
namespace gfx {
-GLImageShm::GLImageShm(gfx::Size size) : size_(size) {
+GLImageShm::GLImageShm(gfx::Size size, unsigned internalformat)
+ : size_(size),
+ internalformat_(internalformat) {
+ // GL_RGBA8_OES is currently the only supported internalformat.
+ DCHECK_EQ(static_cast<GLenum>(GL_RGBA8_OES), internalformat);
}
GLImageShm::~GLImageShm() {
@@ -40,8 +44,23 @@
TRACE_EVENT0("gpu", "GLImageShm::BindTexImage");
DCHECK(shared_memory_);
- const int kBytesPerPixel = 4;
- size_t size = size_.GetArea() * kBytesPerPixel;
+ GLenum internalformat;
+ GLenum format;
+ GLenum type;
+ int bytes_per_pixel;
+ switch (internalformat_) {
+ case GL_RGBA8_OES:
+ internalformat = GL_RGBA;
+ format = GL_RGBA;
+ type = GL_UNSIGNED_BYTE;
+ bytes_per_pixel = 4;
+ break;
+ default:
+ DVLOG(0) << "Invalid format: " << internalformat_;
+ return false;
+ }
+
+ size_t size = size_.GetArea() * bytes_per_pixel;
DCHECK(!shared_memory_->memory());
if (!shared_memory_->Map(size)) {
DVLOG(0) << "Failed to map shared memory.";
@@ -51,12 +70,12 @@
DCHECK(shared_memory_->memory());
glTexImage2D(GL_TEXTURE_2D,
0, // mip level
- GL_RGBA,
+ internalformat,
size_.width(),
size_.height(),
0, // border
- GL_RGBA,
- GL_UNSIGNED_BYTE,
+ format,
+ type,
shared_memory_->memory());
shared_memory_->Unmap();
diff --git a/ui/gl/gl_image_shm.h b/ui/gl/gl_image_shm.h
index 70233f9a..ffdfc8b9 100644
--- a/ui/gl/gl_image_shm.h
+++ b/ui/gl/gl_image_shm.h
@@ -12,7 +12,7 @@
class GL_EXPORT GLImageShm : public GLImage {
public:
- explicit GLImageShm(gfx::Size size);
+ GLImageShm(gfx::Size size, unsigned internalformat);
bool Initialize(gfx::GpuMemoryBufferHandle buffer);
@@ -28,6 +28,7 @@
private:
scoped_ptr<base::SharedMemory> shared_memory_;
gfx::Size size_;
+ unsigned internalformat_;
DISALLOW_COPY_AND_ASSIGN(GLImageShm);
};
diff --git a/ui/gl/gl_image_win.cc b/ui/gl/gl_image_win.cc
index 26b4a8f..1486520 100644
--- a/ui/gl/gl_image_win.cc
+++ b/ui/gl/gl_image_win.cc
@@ -27,7 +27,9 @@
}
scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer(
- gfx::GpuMemoryBufferHandle buffer, gfx::Size size) {
+ gfx::GpuMemoryBufferHandle buffer,
+ gfx::Size size,
+ unsigned internalformat) {
TRACE_EVENT0("gpu", "GLImage::CreateGLImageForGpuMemoryBuffer");
switch (GetGLImplementation()) {
case kGLImplementationOSMesaGL:
@@ -35,7 +37,8 @@
case kGLImplementationEGLGLES2:
switch (buffer.type) {
case SHARED_MEMORY_BUFFER: {
- scoped_refptr<GLImageShm> image(new GLImageShm(size));
+ scoped_refptr<GLImageShm> image(
+ new GLImageShm(size, internalformat));
if (!image->Initialize(buffer))
return NULL;
diff --git a/ui/gl/gl_image_x11.cc b/ui/gl/gl_image_x11.cc
index a6c09a1..6f7d8c6 100644
--- a/ui/gl/gl_image_x11.cc
+++ b/ui/gl/gl_image_x11.cc
@@ -35,7 +35,9 @@
}
scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer(
- gfx::GpuMemoryBufferHandle buffer, gfx::Size size) {
+ gfx::GpuMemoryBufferHandle buffer,
+ gfx::Size size,
+ unsigned internalformat) {
TRACE_EVENT0("gpu", "GLImage::CreateGLImageForGpuMemoryBuffer");
switch (GetGLImplementation()) {
case kGLImplementationOSMesaGL:
@@ -43,7 +45,8 @@
case kGLImplementationEGLGLES2:
switch (buffer.type) {
case SHARED_MEMORY_BUFFER: {
- scoped_refptr<GLImageShm> image(new GLImageShm(size));
+ scoped_refptr<GLImageShm> image(
+ new GLImageShm(size, internalformat));
if (!image->Initialize(buffer))
return NULL;