diff options
author | reveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-03 13:22:42 +0000 |
---|---|---|
committer | reveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-03 13:22:42 +0000 |
commit | 5780f5ac5dc59b860e062cbad5992262841e05ad (patch) | |
tree | a1d040abaa18b4b4b5a6e05b41fef9b023022248 | |
parent | a679e42fffa709c69aec93eb4e7cbcd9fd1e9f55 (diff) | |
download | chromium_src-5780f5ac5dc59b860e062cbad5992262841e05ad.zip chromium_src-5780f5ac5dc59b860e062cbad5992262841e05ad.tar.gz chromium_src-5780f5ac5dc59b860e062cbad5992262841e05ad.tar.bz2 |
gpu: Add support for multiple GpuMemoryBuffer types.
This is a re-factoring of the GpuMemoryBuffer framework to support
different run-time buffer implementations.
This also adds a GpuMemoryBuffer type that is backed by standard
shared memory. This allows us exercise more code in unit tests.
TEST=gpu_unittests --gtest_filter=MockGpuMemoryBufferTest.Lifecycle
BUG=261649
Review URL: https://chromiumcodereview.appspot.com/20536006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215508 0039d316-1c4b-4281-b951-d872f2087c98
32 files changed, 402 insertions, 271 deletions
diff --git a/android_webview/browser/gpu_memory_buffer_factory_impl.cc b/android_webview/browser/gpu_memory_buffer_factory_impl.cc index 00758c9..c4a6cac 100644 --- a/android_webview/browser/gpu_memory_buffer_factory_impl.cc +++ b/android_webview/browser/gpu_memory_buffer_factory_impl.cc @@ -6,7 +6,7 @@ #include "android_webview/public/browser/draw_gl.h" #include "base/logging.h" -#include "gpu/command_buffer/client/gpu_memory_buffer.h" +#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/size.h" #include "ui/gl/gl_bindings.h" @@ -17,7 +17,7 @@ namespace { // Provides hardware rendering functions from the Android glue layer. AwDrawGLFunctionTable* g_gl_draw_functions = NULL; -class GpuMemoryBufferImpl : public gpu::GpuMemoryBuffer { +class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { public: GpuMemoryBufferImpl(int buffer_id, gfx::Size size) : buffer_id_(buffer_id), @@ -30,8 +30,8 @@ class GpuMemoryBufferImpl : public gpu::GpuMemoryBuffer { g_gl_draw_functions->release_graphic_buffer(buffer_id_); } - // Overridden from gpu::GpuMemoryBuffer: - virtual void Map(gpu::GpuMemoryBuffer::AccessMode mode, + // Overridden from gfx::GpuMemoryBuffer: + virtual void Map(gfx::GpuMemoryBuffer::AccessMode mode, void** vaddr) OVERRIDE { AwMapMode map_mode = MAP_READ_ONLY; switch (mode) { @@ -56,12 +56,15 @@ class GpuMemoryBufferImpl : public gpu::GpuMemoryBuffer { DCHECK(!err); mapped_ = false; } - virtual bool IsMapped() OVERRIDE { return mapped_; } - virtual uint32 GetStride() OVERRIDE { + virtual bool IsMapped() const OVERRIDE { return mapped_; } + virtual uint32 GetStride() const OVERRIDE { return g_gl_draw_functions->get_stride(buffer_id_); } - virtual void* GetNativeBuffer() OVERRIDE { - return g_gl_draw_functions->get_native_buffer(buffer_id_); + virtual gfx::GpuMemoryBufferHandle GetHandle() const OVERRIDE { + gfx::GpuMemoryBufferHandle handle; + handle.type = gfx::EGL_CLIENT_BUFFER; + handle.native_buffer = g_gl_draw_functions->get_native_buffer(buffer_id_); + return handle; } private: @@ -80,7 +83,7 @@ GpuMemoryBufferFactoryImpl::GpuMemoryBufferFactoryImpl() { GpuMemoryBufferFactoryImpl::~GpuMemoryBufferFactoryImpl() { } -gpu::GpuMemoryBuffer* GpuMemoryBufferFactoryImpl::CreateGpuMemoryBuffer( +gfx::GpuMemoryBuffer* GpuMemoryBufferFactoryImpl::CreateGpuMemoryBuffer( size_t width, size_t height, unsigned internalformat) { diff --git a/android_webview/browser/gpu_memory_buffer_factory_impl.h b/android_webview/browser/gpu_memory_buffer_factory_impl.h index b85c24a..a5d8988 100644 --- a/android_webview/browser/gpu_memory_buffer_factory_impl.h +++ b/android_webview/browser/gpu_memory_buffer_factory_impl.h @@ -21,7 +21,7 @@ class GpuMemoryBufferFactoryImpl : public gpu::GpuMemoryBufferFactory { static void SetAwDrawGLFunctionTable(AwDrawGLFunctionTable* table); // Overridden from gpu::GpuMemoryBufferFactory: - virtual gpu::GpuMemoryBuffer* CreateGpuMemoryBuffer( + virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer( size_t width, size_t height, unsigned internalformat) OVERRIDE; diff --git a/gpu/command_buffer/client/gl_in_process_context.cc b/gpu/command_buffer/client/gl_in_process_context.cc index b1b5a03..97f1715 100644 --- a/gpu/command_buffer/client/gl_in_process_context.cc +++ b/gpu/command_buffer/client/gl_in_process_context.cc @@ -23,7 +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.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" @@ -71,7 +70,7 @@ class GLInProcessContextImpl virtual gles2::GLES2Implementation* GetImplementation() OVERRIDE; // ImageFactory implementation: - virtual scoped_ptr<GpuMemoryBuffer> CreateGpuMemoryBuffer( + virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( int width, int height, GLenum internalformat, unsigned* image_id) OVERRIDE; virtual void DeleteGpuMemoryBuffer(unsigned image_id) OVERRIDE; @@ -107,17 +106,17 @@ size_t SharedContextCount() { return g_all_shared_contexts.Get().size(); } -scoped_ptr<GpuMemoryBuffer> GLInProcessContextImpl::CreateGpuMemoryBuffer( +scoped_ptr<gfx::GpuMemoryBuffer> GLInProcessContextImpl::CreateGpuMemoryBuffer( int width, int height, GLenum internalformat, unsigned int* image_id) { - scoped_ptr<GpuMemoryBuffer> buffer( + scoped_ptr<gfx::GpuMemoryBuffer> buffer( g_gpu_memory_buffer_factory->CreateGpuMemoryBuffer(width, height, internalformat)); if (!buffer) - return scoped_ptr<GpuMemoryBuffer>(); + return scoped_ptr<gfx::GpuMemoryBuffer>(); *image_id = command_buffer_->CreateImageForGpuMemoryBuffer( - buffer->GetNativeBuffer(), gfx::Size(width, height)); + buffer->GetHandle(), gfx::Size(width, height)); return buffer.Pass(); } diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index a61da77..9285b6d8 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -16,7 +16,6 @@ #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> #include "gpu/command_buffer/client/buffer_tracker.h" -#include "gpu/command_buffer/client/gpu_memory_buffer.h" #include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h" #include "gpu/command_buffer/client/mapped_memory.h" #include "gpu/command_buffer/client/program_info_manager.h" @@ -25,6 +24,7 @@ #include "gpu/command_buffer/client/vertex_array_object_manager.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/trace_event.h" +#include "ui/gfx/gpu_memory_buffer.h" #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS @@ -3699,7 +3699,8 @@ GLuint GLES2Implementation::CreateImageCHROMIUM( } void GLES2Implementation::DestroyImageCHROMIUMHelper(GLuint image_id) { - GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer(image_id); + gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( + image_id); if (!gpu_buffer) { SetGLError(GL_INVALID_OPERATION, "glDestroyImageCHROMIUM", "invalid image"); return; @@ -3720,7 +3721,8 @@ void GLES2Implementation::DestroyImageCHROMIUM(GLuint image_id) { } void GLES2Implementation::UnmapImageCHROMIUMHelper(GLuint image_id) { - GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer(image_id); + gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( + image_id); if (!gpu_buffer) { SetGLError(GL_INVALID_OPERATION, "glUnmapImageCHROMIUM", "invalid image"); return; @@ -3744,21 +3746,22 @@ void GLES2Implementation::UnmapImageCHROMIUM(GLuint image_id) { void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id, GLenum access) { - GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer(image_id); + gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( + image_id); if (!gpu_buffer) { SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "invalid image"); return NULL; } - GpuMemoryBuffer::AccessMode mode; + gfx::GpuMemoryBuffer::AccessMode mode; switch(access) { case GL_WRITE_ONLY: - mode = GpuMemoryBuffer::WRITE_ONLY; + mode = gfx::GpuMemoryBuffer::WRITE_ONLY; break; case GL_READ_ONLY: - mode = GpuMemoryBuffer::READ_ONLY; + mode = gfx::GpuMemoryBuffer::READ_ONLY; break; case GL_READ_WRITE: - mode = GpuMemoryBuffer::READ_WRITE; + mode = gfx::GpuMemoryBuffer::READ_WRITE; break; default: SetGLError(GL_INVALID_ENUM, "glMapImageCHROMIUM", @@ -3796,8 +3799,8 @@ void GLES2Implementation::GetImageParameterivCHROMIUMHelper( return; } - GpuMemoryBuffer* gpu_buffer = - gpu_memory_buffer_tracker_->GetBuffer(image_id); + gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( + image_id); if (!gpu_buffer) { SetGLError(GL_INVALID_OPERATION, "glGetImageParameterivCHROMIUM", "invalid image"); diff --git a/gpu/command_buffer/client/gpu_memory_buffer_factory.h b/gpu/command_buffer/client/gpu_memory_buffer_factory.h index 5ea4bf5..42dde40 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer_factory.h +++ b/gpu/command_buffer/client/gpu_memory_buffer_factory.h @@ -7,12 +7,15 @@ #include "gpu/gpu_export.h" -namespace gpu { +namespace gfx { class GpuMemoryBuffer; +} + +namespace gpu { class GPU_EXPORT GpuMemoryBufferFactory { public: - virtual gpu::GpuMemoryBuffer* CreateGpuMemoryBuffer( + virtual gfx::GpuMemoryBuffer* CreateGpuMemoryBuffer( size_t width, size_t height, unsigned internalformat) = 0; diff --git a/gpu/command_buffer/client/gpu_memory_buffer_mock.cc b/gpu/command_buffer/client/gpu_memory_buffer_mock.cc deleted file mode 100644 index 289b0fe..0000000 --- a/gpu/command_buffer/client/gpu_memory_buffer_mock.cc +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 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/client/gpu_memory_buffer_mock.h" - -namespace gpu { - -GpuMemoryBufferMock::GpuMemoryBufferMock(int width, int height) { -} - -GpuMemoryBufferMock::~GpuMemoryBufferMock() { - Die(); -} - -} // namespace gpu diff --git a/gpu/command_buffer/client/gpu_memory_buffer_mock.h b/gpu/command_buffer/client/gpu_memory_buffer_mock.h deleted file mode 100644 index 6a4db89..0000000 --- a/gpu/command_buffer/client/gpu_memory_buffer_mock.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 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_GPU_MEMORY_BUFFER_MOCK_H_ -#define GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_MOCK_H_ - -#include "gpu/command_buffer/client/gpu_memory_buffer.h" -#include "base/basictypes.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu { - -class GpuMemoryBufferMock : public GpuMemoryBuffer { - public: - GpuMemoryBufferMock(int width, int height); - virtual ~GpuMemoryBufferMock(); - - MOCK_METHOD2(Map, void(GpuMemoryBuffer::AccessMode, void**)); - MOCK_METHOD0(Unmap, void()); - MOCK_METHOD0(IsMapped, bool()); - MOCK_METHOD0(GetNativeBuffer, void*()); - MOCK_METHOD0(GetStride, uint32()); - MOCK_METHOD0(Die, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferMock); -}; - -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_MOCK_H_ diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc index 894898b..c1c9b4d 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc +++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc @@ -6,8 +6,8 @@ #include "base/memory/scoped_ptr.h" #include "gpu/command_buffer/client/gles2_implementation.h" -#include "gpu/command_buffer/client/gpu_memory_buffer.h" #include "gpu/command_buffer/client/image_factory.h" +#include "ui/gfx/gpu_memory_buffer.h" namespace gpu { namespace gles2 { @@ -27,7 +27,7 @@ GLuint GpuMemoryBufferTracker::CreateBuffer( GLsizei width, GLsizei height, GLenum internalformat) { GLuint image_id = 0; DCHECK(factory_); - scoped_ptr<GpuMemoryBuffer> buffer = + scoped_ptr<gfx::GpuMemoryBuffer> buffer = factory_->CreateGpuMemoryBuffer(width, height, internalformat, &image_id); if (buffer.get() == NULL) @@ -40,7 +40,7 @@ GLuint GpuMemoryBufferTracker::CreateBuffer( return image_id; } -GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(GLuint image_id) { +gfx::GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(GLuint image_id) { BufferMap::iterator it = buffers_.find(image_id); return (it != buffers_.end()) ? it->second : NULL; } @@ -48,7 +48,7 @@ GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(GLuint image_id) { void GpuMemoryBufferTracker::RemoveBuffer(GLuint image_id) { BufferMap::iterator buffer_it = buffers_.find(image_id); if (buffer_it != buffers_.end()) { - GpuMemoryBuffer* buffer = buffer_it->second; + gfx::GpuMemoryBuffer* buffer = buffer_it->second; buffers_.erase(buffer_it); delete buffer; } diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h index f2f6e9f0..1192b17 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h +++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h @@ -11,9 +11,11 @@ #include "gles2_impl_export.h" #include "gpu/command_buffer/client/hash_tables.h" -namespace gpu { +namespace gfx { class GpuMemoryBuffer; +} +namespace gpu { namespace gles2 { class ImageFactory; @@ -26,11 +28,11 @@ class GLES2_IMPL_EXPORT GpuMemoryBufferTracker { GLuint CreateBuffer( GLsizei width, GLsizei height, GLenum internalformat); - GpuMemoryBuffer* GetBuffer(GLuint image_id); + gfx::GpuMemoryBuffer* GetBuffer(GLuint image_id); void RemoveBuffer(GLuint image_id); private: - typedef gpu::hash_map<GLuint, GpuMemoryBuffer*> BufferMap; + typedef gpu::hash_map<GLuint, gfx::GpuMemoryBuffer*> BufferMap; BufferMap buffers_; ImageFactory* factory_; diff --git a/gpu/command_buffer/client/image_factory.h b/gpu/command_buffer/client/image_factory.h index b752cb1..449c8a4 100644 --- a/gpu/command_buffer/client/image_factory.h +++ b/gpu/command_buffer/client/image_factory.h @@ -10,9 +10,11 @@ #include "base/memory/scoped_ptr.h" #include "gles2_impl_export.h" -namespace gpu { +namespace gfx { class GpuMemoryBuffer; +} +namespace gpu { namespace gles2 { class GLES2_IMPL_EXPORT ImageFactory { @@ -22,7 +24,7 @@ class GLES2_IMPL_EXPORT ImageFactory { // Create a GpuMemoryBuffer and makes it available to the // service side by inserting it to the ImageManager. - virtual scoped_ptr<GpuMemoryBuffer> CreateGpuMemoryBuffer( + virtual scoped_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBuffer( int width, int height, GLenum internalformat, unsigned* image_id) = 0; virtual void DeleteGpuMemoryBuffer(unsigned image_id) = 0; }; diff --git a/gpu/command_buffer/client/image_factory_mock.cc b/gpu/command_buffer/client/image_factory_mock.cc deleted file mode 100644 index d167cee..0000000 --- a/gpu/command_buffer/client/image_factory_mock.cc +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 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/client/image_factory_mock.h" - -namespace gpu { -namespace gles2 { - -ImageFactoryMock::ImageFactoryMock(ImageManager* manager) { -} - -ImageFactoryMock::~ImageFactoryMock() { -} - -} // namespace gles2 -} // namespace gpu diff --git a/gpu/command_buffer/client/image_factory_mock.h b/gpu/command_buffer/client/image_factory_mock.h deleted file mode 100644 index 2516d69..0000000 --- a/gpu/command_buffer/client/image_factory_mock.h +++ /dev/null @@ -1,41 +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_MOCK_H_ -#define GPU_COMMAND_BUFFER_CLIENT_IMAGE_FACTORY_MOCK_H_ - -#include "base/memory/scoped_ptr.h" -#include "gpu/command_buffer/client/gpu_memory_buffer.h" -#include "gpu/command_buffer/client/image_factory.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace gpu { -namespace gles2 { -class ImageManager; - -// Mock implementation of ImageFactory -class ImageFactoryMock : public ImageFactory { - public: - ImageFactoryMock(ImageManager* image_manager); - virtual ~ImageFactoryMock(); - - MOCK_METHOD4(CreateGpuMemoryBufferMock, 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<GpuMemoryBuffer> CreateGpuMemoryBuffer( - int width, int height, GLenum internalformat, - unsigned* image_id) OVERRIDE { - return scoped_ptr<GpuMemoryBuffer>(CreateGpuMemoryBufferMock( - width, height, internalformat, image_id)); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ImageFactoryMock); -}; - -} // namespace gles2 -} // namespace gpu - -#endif // GPU_COMMAND_BUFFER_CLIENT_IMAGE_FACTORY_MOCK_H_ diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h index 489c9e9..18c919f 100644 --- a/gpu/command_buffer/service/in_process_command_buffer.h +++ b/gpu/command_buffer/service/in_process_command_buffer.h @@ -15,6 +15,7 @@ #include "base/synchronization/waitable_event.h" #include "gpu/command_buffer/common/command_buffer.h" #include "gpu/gpu_export.h" +#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_widget_types.h" #include "ui/gl/gpu_preference.h" 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 7e6372c..9c9d5ab 100644 --- a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc +++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc @@ -9,17 +9,14 @@ #include "base/bind.h" #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_mock.h" -#include "gpu/command_buffer/client/image_factory_mock.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" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/native_widget_types.h" #include "ui/gl/gl_image.h" -#include "ui/gl/gl_image_mock.h" using testing::_; using testing::IgnoreResult; @@ -32,50 +29,116 @@ using testing::StrictMock; namespace gpu { namespace gles2 { -static const int kImageWidth = 256; -static const int kImageHeight = 256; +static const int kImageWidth = 32; +static const int kImageHeight = 32; static const int kImageBytesPerPixel = 4; +class MockGpuMemoryBuffer : public gfx::GpuMemoryBuffer { + public: + MockGpuMemoryBuffer(int width, int height) {} + virtual ~MockGpuMemoryBuffer() { + Die(); + } + + MOCK_METHOD2(Map, void(gfx::GpuMemoryBuffer::AccessMode, void**)); + MOCK_METHOD0(Unmap, void()); + MOCK_CONST_METHOD0(IsMapped, bool()); + MOCK_CONST_METHOD0(GetStride, uint32()); + MOCK_CONST_METHOD0(GetHandle, gfx::GpuMemoryBufferHandle()); + MOCK_METHOD0(Die, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockGpuMemoryBuffer); +}; + +class MockImageFactory : public ImageFactory { + public: + MockImageFactory(ImageManager* image_manager) {} + virtual ~MockImageFactory() {} + + 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)); + } + + private: + DISALLOW_COPY_AND_ASSIGN(MockImageFactory); +}; + class MockGpuMemoryBufferTest : public testing::Test { protected: virtual void SetUp() { GLManager::Options options; image_manager_ = new ImageManager; image_factory_.reset( - new StrictMock<ImageFactoryMock>(image_manager_.get())); + new StrictMock<MockImageFactory>(image_manager_.get())); options.image_manager = image_manager_.get(); options.image_factory = image_factory_.get(); gl_.Initialize(options); gl_.MakeCurrent(); + + glGenTextures(2, texture_ids_); + glBindTexture(GL_TEXTURE_2D, texture_ids_[1]); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glGenFramebuffers(1, &framebuffer_id_); + glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_id_); + glFramebufferTexture2D(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, + texture_ids_[1], + 0); } virtual void TearDown() { + glDeleteTextures(2, texture_ids_); + glDeleteFramebuffers(1, &framebuffer_id_); + gl_.Destroy(); } - scoped_ptr<StrictMock<ImageFactoryMock> > image_factory_; + scoped_ptr<StrictMock<MockImageFactory> > image_factory_; scoped_refptr<ImageManager> image_manager_; GLManager gl_; + GLuint texture_ids_[2]; + GLuint framebuffer_id_; }; // An end to end test that tests the whole GpuMemoryBuffer lifecycle. TEST_F(MockGpuMemoryBufferTest, Lifecycle) { - // Create a client texture id. - GLuint texture_id; - glGenTextures(1, &texture_id); + size_t bytes = kImageWidth * kImageHeight * kImageBytesPerPixel; + uint8 pixels[1 * 4] = { 255u, 0u, 0u, 255u }; // Buffer is owned and freed by GpuMemoryBufferTracker. - StrictMock<GpuMemoryBufferMock>* gpu_memory_buffer = - new StrictMock<GpuMemoryBufferMock>(kImageWidth, kImageHeight); + StrictMock<MockGpuMemoryBuffer>* gpu_memory_buffer = + new StrictMock<MockGpuMemoryBuffer>(kImageWidth, kImageHeight); + base::SharedMemory shared_memory; + shared_memory.CreateAnonymous(bytes); + + base::SharedMemoryHandle duped_shared_memory_handle; + shared_memory.ShareToProcess(base::GetCurrentProcessHandle(), + &duped_shared_memory_handle); + gfx::GpuMemoryBufferHandle handle; + 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, _)) .Times(1) - .WillOnce(DoAll(SetArgPointee<3>(kImageId), - Return(gpu_memory_buffer))) + .WillOnce(DoAll(SetArgPointee<3>(kImageId), Return(gpu_memory_buffer))) .RetiresOnSaturation(); // Create the GLImage and insert it into the ImageManager, which @@ -84,24 +147,41 @@ TEST_F(MockGpuMemoryBufferTest, Lifecycle) { kImageWidth, kImageHeight, GL_RGBA8_OES); EXPECT_EQ(kImageId, image_id); + EXPECT_CALL(*gpu_memory_buffer, GetHandle()) + .WillOnce(Return(handle)) + .RetiresOnSaturation(); + gfx::Size size(kImageWidth, kImageHeight); - scoped_refptr<StrictMock<gfx::GLImageMock> > gl_image( - new StrictMock<gfx::GLImageMock>(gpu_memory_buffer, size)); + scoped_refptr<gfx::GLImage> gl_image( + gfx::GLImage::CreateGLImageForGpuMemoryBuffer( + gpu_memory_buffer->GetHandle(), size)); image_manager_->AddImage(gl_image.get(), image_id); EXPECT_CALL(*gpu_memory_buffer, IsMapped()) .WillOnce(Return(false)) .RetiresOnSaturation(); - scoped_ptr<uint8[]> buffer_pixels(new uint8[ - kImageWidth * kImageHeight * kImageBytesPerPixel]); + shared_memory.Map(bytes); + EXPECT_TRUE(shared_memory.memory()); EXPECT_CALL(*gpu_memory_buffer, Map(_, _)) .Times(1) - .WillOnce(SetArgPointee<1>(buffer_pixels.get())) + .WillOnce(SetArgPointee<1>(shared_memory.memory())) .RetiresOnSaturation(); - void* mapped_buffer = glMapImageCHROMIUM(image_id, GL_WRITE_ONLY); - EXPECT_EQ(buffer_pixels.get(), mapped_buffer); + uint8* mapped_buffer = static_cast<uint8*>( + glMapImageCHROMIUM(image_id, GL_READ_WRITE)); + ASSERT_TRUE(mapped_buffer != NULL); + + // Assign a value to each pixel. + int stride = kImageWidth * kImageBytesPerPixel; + for (int x = 0; x < kImageWidth; ++x) { + for (int y = 0; y < kImageHeight; ++y) { + mapped_buffer[y * stride + x * kImageBytesPerPixel + 0] = pixels[0]; + mapped_buffer[y * stride + x * kImageBytesPerPixel + 1] = pixels[1]; + mapped_buffer[y * stride + x * kImageBytesPerPixel + 2] = pixels[2]; + mapped_buffer[y * stride + x * kImageBytesPerPixel + 3] = pixels[3]; + } + } EXPECT_CALL(*gpu_memory_buffer, IsMapped()) .WillOnce(Return(true)) @@ -114,21 +194,23 @@ TEST_F(MockGpuMemoryBufferTest, Lifecycle) { glUnmapImageCHROMIUM(image_id); // Bind the texture and the image. - glBindTexture(GL_TEXTURE_2D, texture_id); - EXPECT_CALL(*gl_image.get(), BindTexImage()) - .Times(1) - .WillOnce(Return(true)) - .RetiresOnSaturation(); - EXPECT_CALL(*gl_image.get(), GetSize()) - .Times(1) - .WillOnce(Return(size)) - .RetiresOnSaturation(); + glBindTexture(GL_TEXTURE_2D, texture_ids_[0]); glBindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id); - // Unbind the image. - EXPECT_CALL(*gl_image.get(), ReleaseTexImage()) - .Times(1) - .RetiresOnSaturation(); + // Copy texture so we can verify result using CheckPixels. + glCopyTextureCHROMIUM(GL_TEXTURE_2D, + texture_ids_[0], + texture_ids_[1], + 0, + GL_RGBA, + GL_UNSIGNED_BYTE); + EXPECT_TRUE(glGetError() == GL_NO_ERROR); + + // Check if pixels match the values that were assigned to the mapped buffer. + GLTestHelper::CheckPixels(0, 0, kImageWidth, kImageHeight, 0, pixels); + EXPECT_TRUE(GL_NO_ERROR == glGetError()); + + // Release the image. glReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id); // Destroy the image. @@ -141,9 +223,6 @@ TEST_F(MockGpuMemoryBufferTest, Lifecycle) { .RetiresOnSaturation(); glDestroyImageCHROMIUM(image_id); - - // Delete the texture. - glDeleteTextures(1, &texture_id); } } // namespace gles2 diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 9225f65..316aa91 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -270,10 +270,6 @@ ], 'sources': [ '<@(gles2_c_lib_source_files)', - 'command_buffer/client/gpu_memory_buffer_mock.cc', - 'command_buffer/client/gpu_memory_buffer_mock.h', - 'command_buffer/client/image_factory_mock.cc', - 'command_buffer/client/image_factory_mock.h', 'command_buffer/tests/compressed_texture_test.cc', 'command_buffer/tests/gl_bind_uniform_location_unittest.cc', 'command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc', diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi index 026e5e6..da2be68 100644 --- a/gpu/gpu_common.gypi +++ b/gpu/gpu_common.gypi @@ -36,7 +36,6 @@ 'command_buffer/client/gles2_trace_implementation.cc', 'command_buffer/client/gles2_trace_implementation.h', 'command_buffer/client/gles2_trace_implementation_impl_autogen.h', - 'command_buffer/client/gpu_memory_buffer.h', 'command_buffer/client/gpu_memory_buffer_factory.h', 'command_buffer/client/gpu_memory_buffer_tracker.cc', 'command_buffer/client/gpu_memory_buffer_tracker.h', diff --git a/ui/gfx/gpu_memory_buffer.cc b/ui/gfx/gpu_memory_buffer.cc new file mode 100644 index 0000000..c1de26c --- /dev/null +++ b/ui/gfx/gpu_memory_buffer.cc @@ -0,0 +1,13 @@ +// 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 "ui/gfx/gpu_memory_buffer.h" + +namespace gfx { + +GpuMemoryBuffer::GpuMemoryBuffer() {} + +GpuMemoryBuffer::~GpuMemoryBuffer() {} + +} // namespace gfx diff --git a/gpu/command_buffer/client/gpu_memory_buffer.h b/ui/gfx/gpu_memory_buffer.h index d1de7a4..ff94979 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer.h +++ b/ui/gfx/gpu_memory_buffer.h @@ -2,14 +2,41 @@ // 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_GPU_MEMORY_BUFFER_H_ -#define GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_H_ +#ifndef UI_GFX_GPU_MEMORY_BUFFER_H_ +#define UI_GFX_GPU_MEMORY_BUFFER_H_ -#include "base/basictypes.h" -#include "base/memory/scoped_ptr.h" -#include "gles2_impl_export.h" +#include "base/memory/shared_memory.h" +#include "build/build_config.h" +#include "ui/base/ui_export.h" -namespace gpu { +#if defined(OS_ANDROID) +#include <third_party/khronos/EGL/egl.h> +#endif + +namespace gfx { + +enum GpuMemoryBufferType { + EMPTY_BUFFER, + SHARED_MEMORY_BUFFER, + EGL_CLIENT_BUFFER +}; + +struct GpuMemoryBufferHandle { + GpuMemoryBufferHandle() + : type(EMPTY_BUFFER), + handle(base::SharedMemory::NULLHandle()) +#if defined(OS_ANDROID) + , native_buffer(NULL) +#endif + { + } + bool is_null() const { return type == EMPTY_BUFFER; } + GpuMemoryBufferType type; + base::SharedMemoryHandle handle; +#if defined(OS_ANDROID) + EGLClientBuffer native_buffer; +#endif +}; // Interface for creating and accessing a zero-copy GPU memory buffer. // This design evolved from the generalization of GraphicBuffer API @@ -20,7 +47,7 @@ namespace gpu { // This interface is thread-safe. However, multiple threads mapping // a buffer for Write or ReadOrWrite simultaneously may result in undefined // behavior and is not allowed. -class GLES2_IMPL_EXPORT GpuMemoryBuffer { +class UI_EXPORT GpuMemoryBuffer { public: enum AccessMode { READ_ONLY, @@ -28,9 +55,8 @@ class GLES2_IMPL_EXPORT GpuMemoryBuffer { READ_WRITE, }; - // Frees a previously allocated buffer. Freeing a buffer that is still - // mapped in any process is undefined behavior. - virtual ~GpuMemoryBuffer() {} + GpuMemoryBuffer(); + virtual ~GpuMemoryBuffer(); // Maps the buffer so the client can write the bitmap data in |*vaddr| // subsequently. This call may block, for instance if the hardware needs @@ -42,15 +68,15 @@ class GLES2_IMPL_EXPORT GpuMemoryBuffer { virtual void Unmap() = 0; // Returns true iff the buffer is mapped. - virtual bool IsMapped() = 0; - - // Returns the native pointer for the buffer. - virtual void* GetNativeBuffer() = 0; + virtual bool IsMapped() const = 0; // Returns the stride in bytes for the buffer. - virtual uint32 GetStride() = 0; + virtual uint32 GetStride() const = 0; + + // Returns a platform specific handle for this buffer. + virtual GpuMemoryBufferHandle GetHandle() const = 0; }; -} // namespace gpu +} // namespace gfx -#endif // GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_H_ +#endif // UI_GFX_GPU_MEMORY_BUFFER_H_ diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index eb6dcb4..faf3607 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h @@ -325,8 +325,6 @@ const AcceleratedWidget kNullAcceleratedWidget = 0; #error unknown platform #endif -typedef void* GpuMemoryBufferHandle; - } // namespace gfx #endif // UI_GFX_NATIVE_WIDGET_TYPES_H_ diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp index ae0a1cb..02a1963 100644 --- a/ui/gl/gl.gyp +++ b/ui/gl/gl.gyp @@ -72,6 +72,8 @@ 'gl_image_android.cc', 'gl_image_mac.cc', 'gl_image_ozone.cc', + 'gl_image_shm.cc', + 'gl_image_shm.h', 'gl_image_stub.cc', 'gl_image_stub.h', 'gl_image_win.cc', @@ -307,8 +309,6 @@ ], }, 'sources': [ - 'gl_image_mock.cc', - 'gl_image_mock.h', 'gl_mock.h', 'gl_mock.cc', '<(gl_binding_output_dir)/gl_mock_autogen_gl.h', diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h index 1c12a68..987ec20 100644 --- a/ui/gl/gl_bindings.h +++ b/ui/gl/gl_bindings.h @@ -207,11 +207,6 @@ typedef void (*OSMESAproc)(); // Forward declare EGL types. typedef uint64 EGLuint64CHROMIUM; -#ifndef EGL_ANDROID_image_native_buffer -#define EGL_ANDROID_image_native_buffer 1 -#define EGL_NATIVE_BUFFER_ANDROID 0x3140 -#endif - #include "gl_bindings_autogen_gl.h" #include "gl_bindings_autogen_osmesa.h" diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h index ba8b39a..f1d0537 100644 --- a/ui/gl/gl_image.h +++ b/ui/gl/gl_image.h @@ -6,6 +6,7 @@ #define UI_GL_GL_IMAGE_H_ #include "base/memory/ref_counted.h" +#include "ui/gfx/gpu_memory_buffer.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/size.h" #include "ui/gl/gl_export.h" diff --git a/ui/gl/gl_image_android.cc b/ui/gl/gl_image_android.cc index 0c7db63..fe871e7 100644 --- a/ui/gl/gl_image_android.cc +++ b/ui/gl/gl_image_android.cc @@ -6,6 +6,7 @@ #include "base/debug/trace_event.h" #include "ui/gl/gl_image_egl.h" +#include "ui/gl/gl_image_shm.h" #include "ui/gl/gl_image_stub.h" #include "ui/gl/gl_implementation.h" @@ -28,13 +29,26 @@ scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer( gfx::GpuMemoryBufferHandle buffer, gfx::Size size) { TRACE_EVENT0("gpu", "GLImage::CreateGLImageForGpuMemoryBuffer"); switch (GetGLImplementation()) { - case kGLImplementationEGLGLES2: { - scoped_refptr<GLImageEGL> image(new GLImageEGL(size)); - if (!image->Initialize(buffer)) - return NULL; + case kGLImplementationEGLGLES2: + switch (buffer.type) { + case SHARED_MEMORY_BUFFER: { + scoped_refptr<GLImageShm> image(new GLImageShm(size)); + if (!image->Initialize(buffer)) + return NULL; + + return image; + } + case EGL_CLIENT_BUFFER: { + scoped_refptr<GLImageEGL> image(new GLImageEGL(size)); + if (!image->Initialize(buffer)) + return NULL; - return image; - } + return image; + } + default: + NOTREACHED(); + return NULL; + } case kGLImplementationMockGL: return new GLImageStub; default: diff --git a/ui/gl/gl_image_egl.cc b/ui/gl/gl_image_egl.cc index dbbd979..182117c 100644 --- a/ui/gl/gl_image_egl.cc +++ b/ui/gl/gl_image_egl.cc @@ -19,7 +19,7 @@ GLImageEGL::~GLImageEGL() { } bool GLImageEGL::Initialize(gfx::GpuMemoryBufferHandle buffer) { - EGLClientBuffer cbuf = static_cast<EGLClientBuffer>(buffer); + DCHECK(buffer.native_buffer); EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, @@ -28,7 +28,7 @@ bool GLImageEGL::Initialize(gfx::GpuMemoryBufferHandle buffer) { GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, - cbuf, + buffer.native_buffer, attrs); if (egl_image_ == EGL_NO_IMAGE_KHR) { diff --git a/ui/gl/gl_image_mac.cc b/ui/gl/gl_image_mac.cc index 54cbd52..b244a22 100644 --- a/ui/gl/gl_image_mac.cc +++ b/ui/gl/gl_image_mac.cc @@ -5,6 +5,7 @@ #include "ui/gl/gl_image.h" #include "base/debug/trace_event.h" +#include "ui/gl/gl_image_shm.h" #include "ui/gl/gl_image_stub.h" #include "ui/gl/gl_implementation.h" @@ -32,7 +33,18 @@ scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer( case kGLImplementationOSMesaGL: case kGLImplementationDesktopGL: case kGLImplementationAppleGL: - return NULL; + switch (buffer.type) { + case SHARED_MEMORY_BUFFER: { + scoped_refptr<GLImageShm> image(new GLImageShm(size)); + if (!image->Initialize(buffer)) + return NULL; + + return image; + } + default: + NOTREACHED(); + return NULL; + } case kGLImplementationMockGL: return new GLImageStub; default: diff --git a/ui/gl/gl_image_mock.cc b/ui/gl/gl_image_mock.cc deleted file mode 100644 index fc3267da..0000000 --- a/ui/gl/gl_image_mock.cc +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) 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 "ui/gl/gl_image_mock.h" - -namespace gfx { - -GLImageMock::GLImageMock(gfx::GpuMemoryBufferHandle handle, gfx::Size size) { -} - -GLImageMock::~GLImageMock() { -} - -} // namespace gfx diff --git a/ui/gl/gl_image_mock.h b/ui/gl/gl_image_mock.h deleted file mode 100644 index b903165..0000000 --- a/ui/gl/gl_image_mock.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 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 UI_GL_GL_IMAGE_MOCK_H_ -#define UI_GL_GL_IMAGE_MOCK_H_ - -#include "base/basictypes.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "ui/gfx/size.h" -#include "ui/gl/gl_image.h" - -namespace gfx { - -class GLImageMock : public GLImage { - public: - GLImageMock(gfx::GpuMemoryBufferHandle handle, gfx::Size size); - - MOCK_METHOD0(BindTexImage, bool()); - MOCK_METHOD0(Destroy, void()); - MOCK_METHOD0(GetSize, gfx::Size()); - MOCK_METHOD0(ReleaseTexImage, void()); - - protected: - virtual ~GLImageMock(); - - private: - DISALLOW_COPY_AND_ASSIGN(GLImageMock); -}; - -} // namespace gfx - -#endif // UI_GL_GL_IMAGE_MOCK_H_ diff --git a/ui/gl/gl_image_shm.cc b/ui/gl/gl_image_shm.cc new file mode 100644 index 0000000..14ed836 --- /dev/null +++ b/ui/gl/gl_image_shm.cc @@ -0,0 +1,76 @@ +// 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 "ui/gl/gl_image_shm.h" + +#include "base/debug/trace_event.h" +#include "base/process/process_handle.h" +#include "ui/gl/gl_bindings.h" + +namespace gfx { + +GLImageShm::GLImageShm(gfx::Size size) : size_(size) { +} + +GLImageShm::~GLImageShm() { + Destroy(); +} + +bool GLImageShm::Initialize(gfx::GpuMemoryBufferHandle buffer) { + if (!base::SharedMemory::IsHandleValid(buffer.handle)) + return false; + + base::SharedMemory shared_memory(buffer.handle, true); + + // Duplicate the handle. + base::SharedMemoryHandle duped_shared_memory_handle; + if (!shared_memory.ShareToProcess(base::GetCurrentProcessHandle(), + &duped_shared_memory_handle)) { + DVLOG(0) << "Failed to duplicate shared memory handle."; + return false; + } + + shared_memory_.reset( + new base::SharedMemory(duped_shared_memory_handle, true)); + return true; +} + +bool GLImageShm::BindTexImage() { + TRACE_EVENT0("gpu", "GLImageShm::BindTexImage"); + DCHECK(shared_memory_); + + const int kBytesPerPixel = 4; + size_t size = size_.GetArea() * kBytesPerPixel; + DCHECK(!shared_memory_->memory()); + if (!shared_memory_->Map(size)) { + DVLOG(0) << "Failed to map shared memory."; + return false; + } + + DCHECK(shared_memory_->memory()); + glTexImage2D(GL_TEXTURE_2D, + 0, // mip level + GL_RGBA, + size_.width(), + size_.height(), + 0, // border + GL_RGBA, + GL_UNSIGNED_BYTE, + shared_memory_->memory()); + + shared_memory_->Unmap(); + return true; +} + +gfx::Size GLImageShm::GetSize() { + return size_; +} + +void GLImageShm::Destroy() { +} + +void GLImageShm::ReleaseTexImage() { +} + +} // namespace gfx diff --git a/ui/gl/gl_image_shm.h b/ui/gl/gl_image_shm.h new file mode 100644 index 0000000..70233f9 --- /dev/null +++ b/ui/gl/gl_image_shm.h @@ -0,0 +1,37 @@ +// 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 UI_GL_GL_IMAGE_SHM_H_ +#define UI_GL_GL_IMAGE_SHM_H_ + +#include "base/memory/scoped_ptr.h" +#include "ui/gl/gl_image.h" + +namespace gfx { + +class GL_EXPORT GLImageShm : public GLImage { + public: + explicit GLImageShm(gfx::Size size); + + bool Initialize(gfx::GpuMemoryBufferHandle buffer); + + // Overridden from GLImage: + virtual void Destroy() OVERRIDE; + virtual gfx::Size GetSize() OVERRIDE; + virtual bool BindTexImage() OVERRIDE; + virtual void ReleaseTexImage() OVERRIDE; + + protected: + virtual ~GLImageShm(); + + private: + scoped_ptr<base::SharedMemory> shared_memory_; + gfx::Size size_; + + DISALLOW_COPY_AND_ASSIGN(GLImageShm); +}; + +} // namespace gfx + +#endif // UI_GL_GL_IMAGE_SHM_H_ diff --git a/ui/gl/gl_image_win.cc b/ui/gl/gl_image_win.cc index 7698b84..26b4a8f 100644 --- a/ui/gl/gl_image_win.cc +++ b/ui/gl/gl_image_win.cc @@ -5,6 +5,7 @@ #include "ui/gl/gl_image.h" #include "base/debug/trace_event.h" +#include "ui/gl/gl_image_shm.h" #include "ui/gl/gl_image_stub.h" #include "ui/gl/gl_implementation.h" @@ -32,7 +33,18 @@ scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer( case kGLImplementationOSMesaGL: case kGLImplementationDesktopGL: case kGLImplementationEGLGLES2: - return NULL; + switch (buffer.type) { + case SHARED_MEMORY_BUFFER: { + scoped_refptr<GLImageShm> image(new GLImageShm(size)); + if (!image->Initialize(buffer)) + return NULL; + + return image; + } + default: + NOTREACHED(); + return NULL; + } case kGLImplementationMockGL: return new GLImageStub; default: diff --git a/ui/gl/gl_image_x11.cc b/ui/gl/gl_image_x11.cc index fe945ec..a6c09a1 100644 --- a/ui/gl/gl_image_x11.cc +++ b/ui/gl/gl_image_x11.cc @@ -6,6 +6,7 @@ #include "base/debug/trace_event.h" #include "ui/gl/gl_image_glx.h" +#include "ui/gl/gl_image_shm.h" #include "ui/gl/gl_image_stub.h" #include "ui/gl/gl_implementation.h" @@ -40,7 +41,18 @@ scoped_refptr<GLImage> GLImage::CreateGLImageForGpuMemoryBuffer( case kGLImplementationOSMesaGL: case kGLImplementationDesktopGL: case kGLImplementationEGLGLES2: - return NULL; + switch (buffer.type) { + case SHARED_MEMORY_BUFFER: { + scoped_refptr<GLImageShm> image(new GLImageShm(size)); + if (!image->Initialize(buffer)) + return NULL; + + return image; + } + default: + NOTREACHED(); + return NULL; + } case kGLImplementationMockGL: return new GLImageStub; default: @@ -454,6 +454,8 @@ 'gfx/font_smoothing_win.h', 'gfx/gfx_paths.cc', 'gfx/gfx_paths.h', + 'gfx/gpu_memory_buffer.cc', + 'gfx/gpu_memory_buffer.h', 'gfx/image/canvas_image_source.cc', 'gfx/image/canvas_image_source.h', 'gfx/image/image.cc', |