diff options
author | kaanb@chromium.org <kaanb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-16 10:46:01 +0000 |
---|---|---|
committer | kaanb@chromium.org <kaanb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-16 10:46:01 +0000 |
commit | e9ec4269f805d8abcb187890a6ec82c4fffb861a (patch) | |
tree | 4e46f3971b5e764ea795305a6010dad3abf2ff1c /gpu | |
parent | b9ed58f046141b4610c1bdc966d962d5fb95ac6b (diff) | |
download | chromium_src-e9ec4269f805d8abcb187890a6ec82c4fffb861a.zip chromium_src-e9ec4269f805d8abcb187890a6ec82c4fffb861a.tar.gz chromium_src-e9ec4269f805d8abcb187890a6ec82c4fffb861a.tar.bz2 |
GPU client side changes for GpuMemoryBuffers:
- Introduces a new GL extension CHROMIUM_map_image that contains Create/Destroy/Map/Unmap/GetImageParameteriv methods.
- A new data structure called GpuMemoryBufferTracker to track these buffers and images on the client side.
BUG=175012
Review URL: https://chromiumcodereview.appspot.com/14456004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200505 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
32 files changed, 899 insertions, 13 deletions
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_map_image.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_map_image.txt new file mode 100644 index 0000000..6304fda --- /dev/null +++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_map_image.txt @@ -0,0 +1,107 @@ +Name + + CHROMIUM_map_image + +Name Strings + + GL_CHROMIUM_map_image + +Version + + Last Modifed Date: May 9, 2013 + +Dependencies + + OpenGL ES 2.0 is required. + +Overview + + This extension allows for more efficient uploading of texture data through + Chromium's OpenGL ES 2.0 implementation. + + For security reasons Chromium accesses the GPU from a separate process. User + processes are not allowed to access the GPU directly. This multi-process + architechure has the advantage that GPU operations can be secured and + pipelined but it has the disadvantage that all data that is going to be + passed to GPU must first be made available to the separate GPU process. + + This extension helps the application directly allocate and access texture + memory. + +Issues + + None + +New Tokens + + None + +New Procedures and Functions + + GLuint CreateImageCHROMIUM (GLsizei width, GLsizei height, + GLenum internalformat) + + Allocate an image with width equal to <width> and height equal + to <height> stored in format <internalformat>. + + Returns a unique identifier for the allocated image that could be used + in subsequent operations. + + INVALID_VALUE is generated if <width> or <height> is nonpositive. + + void DestroyImageCHROMIUM (GLuint image_id) + + Frees the image previously allocated by a call to CreateImageCHROMIUM. + + INVALID_OPERATION is generated if <image_id> is not a valid image id. + + void* MapImageCHROMIUM (GLuint image_id, GLenum access) + + Returns a pointer to in the user memory for the application to modify + the image. <access> parameter defines if the user will read or write the + pixels. + + INVALID_OPERATION is generated if <image_id> is not a valid image id. + + INVALID_OPERATION is generated if the image was already mapped by a previous + call to this method. + + INVALID_ENUM is generated if <access> is not one of WRITE_ONLY, READ_ONLY + and READ_WRITE. + + void UnmapImageCHROMIUM (GLuint image_id) + + Removes the mapping created by a call to MapImageCHROMIUM. + + Note that after calling UnmapImageCHROMIUM the application should assume + that the memory returned by MapImageCHROMIUM is off limits and is no longer + accessible by the application. Accessing it after calling + UnmapImageCHROMIUM will produce undefined results. + + INVALID_OPERATION is generated if <image_id> is not a valid image id. + + INVALID_OPERATION is generated if the image was not already mapped by a + previous call to MapImageCHROMIUM. + + void GetImageParameterivCHROMIUM(GLuint image_id, GLenum pname, + GLint* params) + + Sets <params> to the integer value of the parameter specified by <pname> + for the image specified by <image_id>. <params> is expected to be + properly allocated before calling this method. + + INVALID_OPERATION is generated if <image_id> is not a valid image id. + + INVALID_ENUM is generated if <pname> is not IMAGE_ROWBYTES_CHROMIUM. + +Errors + + None. + +New State + + None. + +Revision History + + 5/9/2013 Documented the extension diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index fa099e6..e8970e0 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h @@ -182,6 +182,8 @@ #define glEnableFeatureCHROMIUM GLES2_GET_FUN(EnableFeatureCHROMIUM) #define glMapBufferCHROMIUM GLES2_GET_FUN(MapBufferCHROMIUM) #define glUnmapBufferCHROMIUM GLES2_GET_FUN(UnmapBufferCHROMIUM) +#define glMapImageCHROMIUM GLES2_GET_FUN(MapImageCHROMIUM) +#define glUnmapImageCHROMIUM GLES2_GET_FUN(UnmapImageCHROMIUM) #define glMapBufferSubDataCHROMIUM GLES2_GET_FUN(MapBufferSubDataCHROMIUM) #define glUnmapBufferSubDataCHROMIUM GLES2_GET_FUN(UnmapBufferSubDataCHROMIUM) #define glMapTexSubImage2DCHROMIUM GLES2_GET_FUN(MapTexSubImage2DCHROMIUM) @@ -199,6 +201,10 @@ CreateStreamTextureCHROMIUM) #define glDestroyStreamTextureCHROMIUM GLES2_GET_FUN( \ DestroyStreamTextureCHROMIUM) +#define glCreateImageCHROMIUM GLES2_GET_FUN(CreateImageCHROMIUM) +#define glDestroyImageCHROMIUM GLES2_GET_FUN(DestroyImageCHROMIUM) +#define glGetImageParameterivCHROMIUM GLES2_GET_FUN( \ + GetImageParameterivCHROMIUM) #define glGetTranslatedShaderSourceANGLE GLES2_GET_FUN( \ GetTranslatedShaderSourceANGLE) #define glPostSubBufferCHROMIUM GLES2_GET_FUN(PostSubBufferCHROMIUM) diff --git a/gpu/GLES2/gl2extchromium.h b/gpu/GLES2/gl2extchromium.h index 9193467..d23191c 100644 --- a/gpu/GLES2/gl2extchromium.h +++ b/gpu/GLES2/gl2extchromium.h @@ -94,6 +94,39 @@ typedef GLboolean (GL_APIENTRY PFNGLUNMAPBUFFERCHROMIUM) (GLuint target); #endif #endif /* GL_CHROMIUM_pixel_transfer_buffer_object */ +/* GL_CHROMIUM_map_image */ +#ifndef GL_CHROMIUM_map_image +#define GL_CHROMIUM_map_image 1 + +#ifndef GL_IMAGE_ROWBYTES_CHROMIUM +#define GL_IMAGE_ROWBYTES_CHROMIUM 0x78F0 +#endif + +#ifndef GL_READ_WRITE +#define GL_READ_WRITE 0x88BA +#endif + +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLuint GL_APIENTRY glCreateImageCHROMIUM( + GLsizei width, GLsizei height, GLenum internalformat); +GL_APICALL void GL_APIENTRY glDestroyImageCHROMIUM(GLuint image_id); +GL_APICALL void GL_APIENTRY glGetImageParameterivCHROMIUM( + GLuint image_id, GLenum pname, GLint* params); +GL_APICALL void* GL_APIENTRY glMapImageCHROMIUM(GLuint image_id, GLenum access); +GL_APICALL void GL_APIENTRY glUnmapImageCHROMIUM(GLuint image_id); +#endif +typedef GLuint (GL_APIENTRYP PFNGLCREATEIMAGECHROMIUMPROC) ( + GLsizei width, GLsizei height, GLenum internalformat); +typedef void ( + GL_APIENTRYP PFNGLDESTROYIMAGECHROMIUMPROC) (GLuint image_id); +typedef void ( + GL_APIENTRYP PFNGLGETIMAGEPARAMETERIVCHROMIUMPROC) ( + GLuint image_id, GLenum pname, GLint* params); +typedef void* (GL_APIENTRYP PFNGLMAPIMAGECHROMIUMPROC) ( + GLuint image_id, GLenum access); +typedef void (GL_APIENTRYP PFNGLUNMAPIMAGECHROMIUMPROC) (GLuint image_id); +#endif /* GL_CHROMIUM_map_image */ + /* GL_CHROMIUM_map_sub */ #ifndef GL_CHROMIUM_map_sub #define GL_CHROMIUM_map_sub 1 diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index f8a355d..435d13a 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -1306,6 +1306,32 @@ _FUNCTION_INFO = { 'decoder_func': 'DoCopyTexSubImage2D', 'defer_reads': True, }, + 'CreateImageCHROMIUM': { + 'type': 'Manual', + 'cmd_args': 'GLsizei width, GLsizei height, GLenum internalformat', + 'result': ['GLuint'], + 'client_test': False, + 'gen_cmd': False, + 'expectation': False, + 'extension': True, + 'chromium': True, + }, + 'DestroyImageCHROMIUM': { + 'type': 'Manual', + 'immediate': True, + 'client_test': False, + 'gen_cmd': False, + 'extension': True, + 'chromium': True, + }, + 'GetImageParameterivCHROMIUM': { + 'type': 'Manual', + 'client_test': False, + 'gen_cmd': False, + 'expectation': False, + 'extension': True, + 'chromium': True, + }, 'CreateProgram': { 'type': 'Create', 'client_test': False, @@ -1780,7 +1806,6 @@ _FUNCTION_INFO = { 'extension': True, 'chromium': True, 'client_test': False, - 'chromium': True, }, 'MapBufferSubDataCHROMIUM': { 'gen_cmd': False, @@ -1789,6 +1814,12 @@ _FUNCTION_INFO = { 'client_test': False, 'pepper_interface': 'ChromiumMapSub', }, + 'MapImageCHROMIUM': { + 'gen_cmd': False, + 'extension': True, + 'chromium': True, + 'client_test': False, + }, 'MapTexSubImage2DCHROMIUM': { 'gen_cmd': False, 'extension': True, @@ -2015,7 +2046,6 @@ _FUNCTION_INFO = { 'extension': True, 'chromium': True, 'client_test': False, - 'chromium': True, }, 'UnmapBufferSubDataCHROMIUM': { 'gen_cmd': False, @@ -2024,6 +2054,12 @@ _FUNCTION_INFO = { 'client_test': False, 'pepper_interface': 'ChromiumMapSub', }, + 'UnmapImageCHROMIUM': { + 'gen_cmd': False, + 'extension': True, + 'chromium': True, + 'client_test': False, + }, 'UnmapTexSubImage2DCHROMIUM': { 'gen_cmd': False, 'extension': True, diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index f1a5b08..6df6060 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -595,6 +595,12 @@ void* GLES2MapBufferCHROMIUM(GLuint target, GLenum access) { GLboolean GLES2UnmapBufferCHROMIUM(GLuint target) { return gles2::GetGLContext()->UnmapBufferCHROMIUM(target); } +void* GLES2MapImageCHROMIUM(GLuint image_id, GLenum access) { + return gles2::GetGLContext()->MapImageCHROMIUM(image_id, access); +} +void GLES2UnmapImageCHROMIUM(GLuint image_id) { + gles2::GetGLContext()->UnmapImageCHROMIUM(image_id); +} void* GLES2MapBufferSubDataCHROMIUM( GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) { return gles2::GetGLContext()->MapBufferSubDataCHROMIUM( @@ -639,6 +645,18 @@ GLuint GLES2CreateStreamTextureCHROMIUM(GLuint texture) { void GLES2DestroyStreamTextureCHROMIUM(GLuint texture) { gles2::GetGLContext()->DestroyStreamTextureCHROMIUM(texture); } +GLuint GLES2CreateImageCHROMIUM( + GLsizei width, GLsizei height, GLenum internalformat) { + return gles2::GetGLContext()->CreateImageCHROMIUM( + width, height, internalformat); +} +void GLES2DestroyImageCHROMIUM(GLuint image_id) { + gles2::GetGLContext()->DestroyImageCHROMIUM(image_id); +} +void GLES2GetImageParameterivCHROMIUM( + GLuint image_id, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetImageParameterivCHROMIUM(image_id, pname, params); +} void GLES2GetTranslatedShaderSourceANGLE( GLuint shader, GLsizei bufsize, GLsizei* length, char* source) { gles2::GetGLContext()->GetTranslatedShaderSourceANGLE( @@ -1006,6 +1024,10 @@ NameToFunc g_gles2_function_table[] = { glMapBufferCHROMIUM), }, { "glUnmapBufferCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( glUnmapBufferCHROMIUM), }, + { "glMapImageCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glMapImageCHROMIUM), }, + { "glUnmapImageCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glUnmapImageCHROMIUM), }, { "glMapBufferSubDataCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( glMapBufferSubDataCHROMIUM), }, { "glUnmapBufferSubDataCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( @@ -1028,6 +1050,12 @@ NameToFunc g_gles2_function_table[] = { glCreateStreamTextureCHROMIUM), }, { "glDestroyStreamTextureCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( glDestroyStreamTextureCHROMIUM), }, + { "glCreateImageCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glCreateImageCHROMIUM), }, + { "glDestroyImageCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glDestroyImageCHROMIUM), }, + { "glGetImageParameterivCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( + glGetImageParameterivCHROMIUM), }, { "glGetTranslatedShaderSourceANGLE", reinterpret_cast<GLES2FunctionPointer>( glGetTranslatedShaderSourceANGLE), }, { "glPostSubBufferCHROMIUM", reinterpret_cast<GLES2FunctionPointer>( diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 0ce55a5..e7dbdc2 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -16,6 +16,9 @@ #include <GLES2/gl2ext.h> #include <GLES2/gl2extchromium.h> #include "../client/buffer_tracker.h" +#include "../client/gpu_memory_buffer.h" +#include "../client/gpu_memory_buffer_factory.h" +#include "../client/gpu_memory_buffer_tracker.h" #include "../client/mapped_memory.h" #include "../client/program_info_manager.h" #include "../client/query_tracker.h" @@ -84,7 +87,8 @@ GLES2Implementation::GLES2Implementation( ShareGroup* share_group, TransferBufferInterface* transfer_buffer, bool share_resources, - bool bind_generates_resource) + bool bind_generates_resource, + ImageFactory* image_factory) : helper_(helper), transfer_buffer_(transfer_buffer), angle_pack_reverse_row_order_status_(kUnknownExtensionStatus), @@ -108,7 +112,8 @@ GLES2Implementation::GLES2Implementation( debug_(false), use_count_(0), current_query_(NULL), - error_message_callback_(NULL) { + error_message_callback_(NULL), + image_factory_(image_factory) { GPU_DCHECK(helper); GPU_DCHECK(transfer_buffer); @@ -162,6 +167,7 @@ bool GLES2Implementation::Initialize( 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_)); #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) GetIdHandler(id_namespaces::kBuffers)->MakeIds( @@ -2094,6 +2100,10 @@ const GLubyte* GLES2Implementation::GetStringHelper(GLenum name) { "GL_CHROMIUM_map_sub " "GL_CHROMIUM_shallow_flush " "GL_EXT_unpack_subimage"; + if (image_factory_ != NULL) { + // The first space character is intentional. + str += " GL_CHROMIUM_map_image"; + } break; default: break; @@ -3567,11 +3577,11 @@ GLboolean GLES2Implementation::UnmapBufferCHROMIUM(GLuint target) { } BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); if (!buffer) { - SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "invalid buffer"); + SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "invalid buffer"); return false; } if (!buffer->mapped()) { - SetGLError(GL_INVALID_OPERATION, "glMapBufferCHROMIUM", "not mapped"); + SetGLError(GL_INVALID_OPERATION, "glUnmapBufferCHROMIUM", "not mapped"); return false; } buffer->set_mapped(false); @@ -3687,6 +3697,163 @@ GLuint GLES2Implementation::InsertSyncPointCHROMIUM() { return helper_->InsertSyncPointCHROMIUM(); } +GLuint GLES2Implementation::CreateImageCHROMIUMHelper( + GLsizei width, GLsizei height, GLenum internalformat) { + if (width <= 0) { + SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "width <= 0"); + return 0; + } + + if (height <= 0) { + SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "height <= 0"); + return 0; + } + // Flush the command stream to ensure ordering in case the newly + // returned image_id has recently been in use with a different buffer. + helper_->CommandBufferHelper::Flush(); + + // Create new buffer. + return gpu_memory_buffer_tracker_->CreateBuffer( + width, height, internalformat); +} + +GLuint GLES2Implementation::CreateImageCHROMIUM( + GLsizei width, GLsizei height, GLenum internalformat) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateImageCHROMIUM(" + << width << ", " + << height << ", " + << GLES2Util::GetStringTextureInternalFormat(internalformat) << ")"); + GLuint image_id = CreateImageCHROMIUMHelper(width, height, internalformat); + CheckGLError(); + return image_id; +} + +void GLES2Implementation::DestroyImageCHROMIUMHelper(GLuint image_id) { + GpuMemoryBuffer* gpu_buffer = + gpu_memory_buffer_tracker_->GetBuffer(image_id); + if (!gpu_buffer) { + SetGLError(GL_INVALID_OPERATION, "glDestroyImageCHROMIUM", + "invalid image"); + return; + } + + // Flush the command stream to make sure all pending commands + // that may refer to the image_id are executed on the service side. + helper_->CommandBufferHelper::Flush(); + gpu_memory_buffer_tracker_->RemoveBuffer(image_id); +} + +void GLES2Implementation::DestroyImageCHROMIUM(GLuint image_id) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDestroyImageCHROMIUM(" + << image_id << ")"); + DestroyImageCHROMIUMHelper(image_id); + CheckGLError(); +} + +void GLES2Implementation::UnmapImageCHROMIUMHelper(GLuint image_id) { + GpuMemoryBuffer* gpu_buffer = + gpu_memory_buffer_tracker_->GetBuffer(image_id); + if (!gpu_buffer) { + SetGLError(GL_INVALID_OPERATION, "glUnmapImageCHROMIUM", "invalid image"); + return; + } + + if (!gpu_buffer->IsMapped()) { + SetGLError(GL_INVALID_OPERATION, "glUnmapImageCHROMIUM", "not mapped"); + return; + } + gpu_buffer->Unmap(); +} + +void GLES2Implementation::UnmapImageCHROMIUM(GLuint image_id) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnmapImageCHROMIUM(" + << image_id << ")"); + + UnmapImageCHROMIUMHelper(image_id); + CheckGLError(); +} + +void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id, + GLenum access) { + 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; + switch(access) { + case GL_WRITE_ONLY: + mode = GpuMemoryBuffer::WRITE_ONLY; + break; + case GL_READ_ONLY: + mode = GpuMemoryBuffer::READ_ONLY; + break; + case GL_READ_WRITE: + mode = GpuMemoryBuffer::READ_WRITE; + break; + default: + SetGLError(GL_INVALID_ENUM, "glMapImageCHROMIUM", + "invalid GPU access mode"); + return NULL; + } + + if (gpu_buffer->IsMapped()) { + SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "already mapped"); + return NULL; + } + + void* mapped_buffer = NULL; + gpu_buffer->Map(mode, &mapped_buffer); + return mapped_buffer; +} + +void* GLES2Implementation::MapImageCHROMIUM( + GLuint image_id, GLenum access) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM(" + << image_id << ", " + << GLES2Util::GetStringEnum(access) << ")"); + + void* mapped = MapImageCHROMIUMHelper(image_id, access); + CheckGLError(); + return mapped; +} + +void GLES2Implementation::GetImageParameterivCHROMIUMHelper( + GLuint image_id, GLenum pname, GLint* params) { + if (pname != GL_IMAGE_ROWBYTES_CHROMIUM) { + SetGLError(GL_INVALID_ENUM, "glGetImageParameterivCHROMIUM", + "invalid parameter"); + return; + } + + GpuMemoryBuffer* gpu_buffer = + gpu_memory_buffer_tracker_->GetBuffer(image_id); + if (!gpu_buffer) { + SetGLError(GL_INVALID_OPERATION, "glGetImageParameterivCHROMIUM", + "invalid image"); + return; + } + + *params = gpu_buffer->GetStride(); +} + +void GLES2Implementation::GetImageParameterivCHROMIUM( + GLuint image_id, GLenum pname, GLint* params) { + GPU_CLIENT_SINGLE_THREAD_CHECK(); + GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM(" + << image_id << ", " + << GLES2Util::GetStringBufferParameter(pname) << ", " + << static_cast<const void*>(params) << ")"); + GetImageParameterivCHROMIUM(image_id, pname, params); + CheckGLError(); +} + // Include the auto-generated part of this file. We split this because it means // we can easily edit the non-auto generated parts right here in this file // instead of having to edit some template or the code generator. diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index a633dd6..e8b367c 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -18,6 +18,8 @@ #include "../client/client_context_state.h" #include "../client/gles2_cmd_helper.h" #include "../client/gles2_interface.h" +#include "../client/gpu_memory_buffer_tracker.h" +#include "../client/image_factory.h" #include "../client/query_tracker.h" #include "../client/ref_counted.h" #include "../client/ring_buffer.h" @@ -102,6 +104,7 @@ class TransferBufferInterface; namespace gles2 { +class ImageFactory; class VertexArrayObjectManager; // This class emulates GLES2 over command buffers. It can be used by a client @@ -174,7 +177,8 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { ShareGroup* share_group, TransferBufferInterface* transfer_buffer, bool share_resources, - bool bind_generates_resource); + bool bind_generates_resource, + ImageFactory* image_factory); virtual ~GLES2Implementation(); @@ -496,6 +500,14 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { GLenum target, GLintptr offset, GLsizeiptr size, const void* data, ScopedTransferBufferPtr* buffer); + GLuint CreateImageCHROMIUMHelper( + GLsizei width, GLsizei height, GLenum internalformat); + void DestroyImageCHROMIUMHelper(GLuint image_id); + void* MapImageCHROMIUMHelper(GLuint image_id, GLenum access); + void UnmapImageCHROMIUMHelper(GLuint image_id); + void GetImageParameterivCHROMIUMHelper( + GLuint image_id, GLenum pname, GLint* params); + // Helper for GetVertexAttrib bool GetVertexAttribHelper(GLuint index, GLenum pname, uint32* param); @@ -654,10 +666,14 @@ class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface { scoped_ptr<BufferTracker> buffer_tracker_; + scoped_ptr<GpuMemoryBufferTracker> gpu_memory_buffer_tracker_; + ErrorMessageCallback* error_message_callback_; scoped_ptr<std::string> current_trace_name_; + ImageFactory* image_factory_; + DISALLOW_COPY_AND_ASSIGN(GLES2Implementation); }; diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index 3510bbf..3123b59 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -438,6 +438,10 @@ virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) OVERRIDE; virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE; +virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) OVERRIDE; + +virtual void UnmapImageCHROMIUM(GLuint image_id) OVERRIDE; + virtual void* MapBufferSubDataCHROMIUM( GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) OVERRIDE; @@ -468,6 +472,14 @@ virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) OVERRIDE; virtual void DestroyStreamTextureCHROMIUM(GLuint texture) OVERRIDE; +virtual GLuint CreateImageCHROMIUM( + GLsizei width, GLsizei height, GLenum internalformat) OVERRIDE; + +virtual void DestroyImageCHROMIUM(GLuint image_id) OVERRIDE; + +virtual void GetImageParameterivCHROMIUM( + GLuint image_id, GLenum pname, GLint* params) OVERRIDE; + virtual void GetTranslatedShaderSourceANGLE( GLuint shader, GLsizei bufsize, GLsizei* length, char* source) OVERRIDE; diff --git a/gpu/command_buffer/client/gles2_implementation_unittest.cc b/gpu/command_buffer/client/gles2_implementation_unittest.cc index 4343ca8..7208425 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest.cc +++ b/gpu/command_buffer/client/gles2_implementation_unittest.cc @@ -401,7 +401,8 @@ class GLES2ImplementationTest : public testing::Test { NULL, transfer_buffer_.get(), shared_resources, - bind_generates_resource)); + bind_generates_resource, + NULL)); ASSERT_TRUE(gl_->Initialize( kTransferBufferSize, kTransferBufferSize, diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index 865f7ed..0fca7e8 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h @@ -251,6 +251,8 @@ virtual void RegisterSharedIdsCHROMIUM( virtual GLboolean EnableFeatureCHROMIUM(const char* feature) = 0; virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) = 0; virtual GLboolean UnmapBufferCHROMIUM(GLuint target) = 0; +virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) = 0; +virtual void UnmapImageCHROMIUM(GLuint image_id) = 0; virtual void* MapBufferSubDataCHROMIUM( GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) = 0; virtual void UnmapBufferSubDataCHROMIUM(const void* mem) = 0; @@ -268,6 +270,11 @@ virtual void GetProgramInfoCHROMIUM( GLuint program, GLsizei bufsize, GLsizei* size, void* info) = 0; virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) = 0; virtual void DestroyStreamTextureCHROMIUM(GLuint texture) = 0; +virtual GLuint CreateImageCHROMIUM( + GLsizei width, GLsizei height, GLenum internalformat) = 0; +virtual void DestroyImageCHROMIUM(GLuint image_id) = 0; +virtual void GetImageParameterivCHROMIUM( + GLuint image_id, GLenum pname, GLint* params) = 0; virtual void GetTranslatedShaderSourceANGLE( GLuint shader, GLsizei bufsize, GLsizei* length, char* source) = 0; virtual void PostSubBufferCHROMIUM( diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index 769b260..00c3a90 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h @@ -279,6 +279,8 @@ virtual void RegisterSharedIdsCHROMIUM( virtual GLboolean EnableFeatureCHROMIUM(const char* feature) OVERRIDE; virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) OVERRIDE; virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE; +virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) OVERRIDE; +virtual void UnmapImageCHROMIUM(GLuint image_id) OVERRIDE; virtual void* MapBufferSubDataCHROMIUM( GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) OVERRIDE; virtual void UnmapBufferSubDataCHROMIUM(const void* mem) OVERRIDE; @@ -297,6 +299,11 @@ virtual void GetProgramInfoCHROMIUM( GLuint program, GLsizei bufsize, GLsizei* size, void* info) OVERRIDE; virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) OVERRIDE; virtual void DestroyStreamTextureCHROMIUM(GLuint texture) OVERRIDE; +virtual GLuint CreateImageCHROMIUM( + GLsizei width, GLsizei height, GLenum internalformat) OVERRIDE; +virtual void DestroyImageCHROMIUM(GLuint image_id) OVERRIDE; +virtual void GetImageParameterivCHROMIUM( + GLuint image_id, GLenum pname, GLint* params) OVERRIDE; virtual void GetTranslatedShaderSourceANGLE( GLuint shader, GLsizei bufsize, GLsizei* length, char* source) OVERRIDE; virtual void PostSubBufferCHROMIUM( diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index b1c4ac5..36ca9b8 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h @@ -527,6 +527,12 @@ void* GLES2InterfaceStub::MapBufferCHROMIUM( GLboolean GLES2InterfaceStub::UnmapBufferCHROMIUM(GLuint /* target */) { return 0; } +void* GLES2InterfaceStub::MapImageCHROMIUM( + GLuint /* image_id */, GLenum /* access */) { + return 0; +} +void GLES2InterfaceStub::UnmapImageCHROMIUM(GLuint /* image_id */) { +} void* GLES2InterfaceStub::MapBufferSubDataCHROMIUM( GLuint /* target */, GLintptr /* offset */, GLsizeiptr /* size */, GLenum /* access */) { @@ -566,6 +572,15 @@ GLuint GLES2InterfaceStub::CreateStreamTextureCHROMIUM(GLuint /* texture */) { } void GLES2InterfaceStub::DestroyStreamTextureCHROMIUM(GLuint /* texture */) { } +GLuint GLES2InterfaceStub::CreateImageCHROMIUM( + GLsizei /* width */, GLsizei /* height */, GLenum /* internalformat */) { + return 0; +} +void GLES2InterfaceStub::DestroyImageCHROMIUM(GLuint /* image_id */) { +} +void GLES2InterfaceStub::GetImageParameterivCHROMIUM( + GLuint /* image_id */, GLenum /* pname */, GLint* /* params */) { +} void GLES2InterfaceStub::GetTranslatedShaderSourceANGLE( GLuint /* shader */, GLsizei /* bufsize */, GLsizei* /* length */, char* /* source */) { diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index 7ec9eb6..9888a5d 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h @@ -279,6 +279,8 @@ virtual void RegisterSharedIdsCHROMIUM( virtual GLboolean EnableFeatureCHROMIUM(const char* feature) OVERRIDE; virtual void* MapBufferCHROMIUM(GLuint target, GLenum access) OVERRIDE; virtual GLboolean UnmapBufferCHROMIUM(GLuint target) OVERRIDE; +virtual void* MapImageCHROMIUM(GLuint image_id, GLenum access) OVERRIDE; +virtual void UnmapImageCHROMIUM(GLuint image_id) OVERRIDE; virtual void* MapBufferSubDataCHROMIUM( GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) OVERRIDE; virtual void UnmapBufferSubDataCHROMIUM(const void* mem) OVERRIDE; @@ -297,6 +299,11 @@ virtual void GetProgramInfoCHROMIUM( GLuint program, GLsizei bufsize, GLsizei* size, void* info) OVERRIDE; virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) OVERRIDE; virtual void DestroyStreamTextureCHROMIUM(GLuint texture) OVERRIDE; +virtual GLuint CreateImageCHROMIUM( + GLsizei width, GLsizei height, GLenum internalformat) OVERRIDE; +virtual void DestroyImageCHROMIUM(GLuint image_id) OVERRIDE; +virtual void GetImageParameterivCHROMIUM( + GLuint image_id, GLenum pname, GLint* params) OVERRIDE; virtual void GetTranslatedShaderSourceANGLE( GLuint shader, GLsizei bufsize, GLsizei* length, char* source) OVERRIDE; virtual void PostSubBufferCHROMIUM( diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 0471880..40be4e9 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h @@ -978,6 +978,17 @@ GLboolean GLES2TraceImplementation::UnmapBufferCHROMIUM(GLuint target) { return gl_->UnmapBufferCHROMIUM(target); } +void* GLES2TraceImplementation::MapImageCHROMIUM( + GLuint image_id, GLenum access) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::MapImageCHROMIUM"); + return gl_->MapImageCHROMIUM(image_id, access); +} + +void GLES2TraceImplementation::UnmapImageCHROMIUM(GLuint image_id) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::UnmapImageCHROMIUM"); + gl_->UnmapImageCHROMIUM(image_id); +} + void* GLES2TraceImplementation::MapBufferSubDataCHROMIUM( GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::MapBufferSubDataCHROMIUM"); @@ -1045,6 +1056,23 @@ void GLES2TraceImplementation::DestroyStreamTextureCHROMIUM(GLuint texture) { gl_->DestroyStreamTextureCHROMIUM(texture); } +GLuint GLES2TraceImplementation::CreateImageCHROMIUM( + GLsizei width, GLsizei height, GLenum internalformat) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::CreateImageCHROMIUM"); + return gl_->CreateImageCHROMIUM(width, height, internalformat); +} + +void GLES2TraceImplementation::DestroyImageCHROMIUM(GLuint image_id) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::DestroyImageCHROMIUM"); + gl_->DestroyImageCHROMIUM(image_id); +} + +void GLES2TraceImplementation::GetImageParameterivCHROMIUM( + GLuint image_id, GLenum pname, GLint* params) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetImageParameterivCHROMIUM"); // NOLINT + gl_->GetImageParameterivCHROMIUM(image_id, pname, params); +} + void GLES2TraceImplementation::GetTranslatedShaderSourceANGLE( GLuint shader, GLsizei bufsize, GLsizei* length, char* source) { TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::GetTranslatedShaderSourceANGLE"); // NOLINT diff --git a/gpu/command_buffer/client/gpu_memory_buffer.h b/gpu/command_buffer/client/gpu_memory_buffer.h index 14e95ee..b388f47 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer.h +++ b/gpu/command_buffer/client/gpu_memory_buffer.h @@ -27,7 +27,7 @@ class GLES2_IMPL_EXPORT GpuMemoryBuffer { enum AccessMode { READ_ONLY, WRITE_ONLY, - READ_OR_WRITE, + READ_WRITE, }; // Frees a previously allocated buffer. Freeing a buffer that is still diff --git a/gpu/command_buffer/client/gpu_memory_buffer_factory.cc b/gpu/command_buffer/client/gpu_memory_buffer_factory.cc index c0e5b9f..57fcef7 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer_factory.cc +++ b/gpu/command_buffer/client/gpu_memory_buffer_factory.cc @@ -7,19 +7,23 @@ #include "base/logging.h" namespace gpu { +namespace gles2 { namespace { GpuMemoryBuffer::Creator* g_gpu_memory_buffer_factory_ = NULL; } const GpuMemoryBuffer::Creator& GetProcessDefaultGpuMemoryBufferFactory() { + DCHECK(g_gpu_memory_buffer_factory_ != NULL); return *g_gpu_memory_buffer_factory_; } void SetProcessDefaultGpuMemoryBufferFactory( const GpuMemoryBuffer::Creator& factory) { DCHECK(g_gpu_memory_buffer_factory_ == NULL); + // TODO(kaanb): move the ownership of this memory to android_webview g_gpu_memory_buffer_factory_ = new GpuMemoryBuffer::Creator(factory); } +} // namespace gles2 } // namespace gpu diff --git a/gpu/command_buffer/client/gpu_memory_buffer_factory.h b/gpu/command_buffer/client/gpu_memory_buffer_factory.h index dd10a7d..191a2e2 100644 --- a/gpu/command_buffer/client/gpu_memory_buffer_factory.h +++ b/gpu/command_buffer/client/gpu_memory_buffer_factory.h @@ -9,6 +9,7 @@ #include "gpu/command_buffer/client/gpu_memory_buffer.h" namespace gpu { +namespace gles2 { // Getter and setter for a GpuMemoryBuffer factory for the current process. // Currently it is only used for Android Webview where both browser and @@ -22,6 +23,7 @@ GLES2_IMPL_EXPORT const GpuMemoryBuffer::Creator& GLES2_IMPL_EXPORT void SetProcessDefaultGpuMemoryBufferFactory( const GpuMemoryBuffer::Creator& factory); +} // namespace gles2 } // namespace gpu #endif // GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_FACTORY_H_ diff --git a/gpu/command_buffer/client/gpu_memory_buffer_mock.cc b/gpu/command_buffer/client/gpu_memory_buffer_mock.cc new file mode 100644 index 0000000..1d24716 --- /dev/null +++ b/gpu/command_buffer/client/gpu_memory_buffer_mock.cc @@ -0,0 +1,16 @@ +// 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 "../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 new file mode 100644 index 0000000..e47dc74 --- /dev/null +++ b/gpu/command_buffer/client/gpu_memory_buffer_mock.h @@ -0,0 +1,32 @@ +// 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 "../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 new file mode 100644 index 0000000..b336796 --- /dev/null +++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.cc @@ -0,0 +1,57 @@ +// 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 "../client/gpu_memory_buffer_tracker.h" + +#include "../client/gles2_implementation.h" +#include "../client/gpu_memory_buffer.h" +#include "../client/image_factory.h" +#include "base/memory/scoped_ptr.h" + +namespace gpu { +namespace gles2 { + +GpuMemoryBufferTracker::GpuMemoryBufferTracker(ImageFactory* factory) + : buffers_(), + factory_(factory) { +} + +GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { + while (!buffers_.empty()) { + RemoveBuffer(buffers_.begin()->first); + } +} + +GLuint GpuMemoryBufferTracker::CreateBuffer( + GLsizei width, GLsizei height, GLenum internalformat) { + GLuint image_id = 0; + DCHECK(factory_); + scoped_ptr<GpuMemoryBuffer> buffer = + factory_->CreateGpuMemoryBuffer(width, height, internalformat, &image_id); + + std::pair<BufferMap::iterator, bool> result = + buffers_.insert(std::make_pair(image_id, buffer.release())); + GPU_DCHECK(result.second); + + return image_id; +} + +GpuMemoryBuffer* GpuMemoryBufferTracker::GetBuffer(GLuint image_id) { + BufferMap::iterator it = buffers_.find(image_id); + return (it != buffers_.end()) ? it->second : NULL; +} + +void GpuMemoryBufferTracker::RemoveBuffer(GLuint image_id) { + BufferMap::iterator buffer_it = buffers_.find(image_id); + if (buffer_it != buffers_.end()) { + GpuMemoryBuffer* buffer = buffer_it->second; + buffers_.erase(buffer_it); + delete buffer; + } + DCHECK(factory_); + factory_->DeleteGpuMemoryBuffer(image_id); +} + +} // namespace gles2 +} // namespace gpu diff --git a/gpu/command_buffer/client/gpu_memory_buffer_tracker.h b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h new file mode 100644 index 0000000..2666c58 --- /dev/null +++ b/gpu/command_buffer/client/gpu_memory_buffer_tracker.h @@ -0,0 +1,43 @@ +// 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_TRACKER_H_ +#define GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_TRACKER_H_ + +#include <GLES2/gl2.h> + +#include "../client/hash_tables.h" +#include "base/basictypes.h" +#include "gles2_impl_export.h" + +namespace gpu { +class GpuMemoryBuffer; + +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); + virtual ~GpuMemoryBufferTracker(); + + GLuint CreateBuffer( + GLsizei width, GLsizei height, GLenum internalformat); + GpuMemoryBuffer* GetBuffer(GLuint image_id); + void RemoveBuffer(GLuint image_id); + + private: + typedef gpu::hash_map<GLuint, GpuMemoryBuffer*> BufferMap; + BufferMap buffers_; + ImageFactory* factory_; + + DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferTracker); +}; + +} // namespace gles2 +} // namespace gpu + +#endif // GPU_COMMAND_BUFFER_CLIENT_GPU_MEMORY_BUFFER_TRACKER_H_ diff --git a/gpu/command_buffer/client/image_factory.h b/gpu/command_buffer/client/image_factory.h new file mode 100644 index 0000000..b752cb1 --- /dev/null +++ b/gpu/command_buffer/client/image_factory.h @@ -0,0 +1,33 @@ +// 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 gpu { +class GpuMemoryBuffer; + +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<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/client/image_factory_mock.cc b/gpu/command_buffer/client/image_factory_mock.cc new file mode 100644 index 0000000..2d425f5 --- /dev/null +++ b/gpu/command_buffer/client/image_factory_mock.cc @@ -0,0 +1,17 @@ +// 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 "../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 new file mode 100644 index 0000000..101ee47 --- /dev/null +++ b/gpu/command_buffer/client/image_factory_mock.h @@ -0,0 +1,41 @@ +// 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 "../client/gpu_memory_buffer.h" +#include "../client/image_factory.h" +#include "base/memory/scoped_ptr.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/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt index 1a9268b..ec68be4 100644 --- a/gpu/command_buffer/cmd_buffer_functions.txt +++ b/gpu/command_buffer/cmd_buffer_functions.txt @@ -175,6 +175,8 @@ GL_APICALL void GL_APIENTRY glRegisterSharedIdsCHROMIUM (GLuint namespac GL_APICALL GLboolean GL_APIENTRY glEnableFeatureCHROMIUM (const char* feature); GL_APICALL void* GL_APIENTRY glMapBufferCHROMIUM (GLuint target, GLenum access); GL_APICALL GLboolean GL_APIENTRY glUnmapBufferCHROMIUM (GLuint target); +GL_APICALL void* GL_APIENTRY glMapImageCHROMIUM (GLuint image_id, GLenum access); +GL_APICALL void GL_APIENTRY glUnmapImageCHROMIUM (GLuint image_id); GL_APICALL void* GL_APIENTRY glMapBufferSubDataCHROMIUM (GLuint target, GLintptrNotNegative offset, GLsizeiptr size, GLenum access); GL_APICALL void GL_APIENTRY glUnmapBufferSubDataCHROMIUM (const void* mem); @@ -188,6 +190,9 @@ GL_APICALL void GL_APIENTRY glGetMultipleIntegervCHROMIUM (const GLenum* GL_APICALL void GL_APIENTRY glGetProgramInfoCHROMIUM (GLidProgram program, GLsizeiNotNegative bufsize, GLsizei* size, void* info); GL_APICALL GLuint GL_APIENTRY glCreateStreamTextureCHROMIUM (GLuint texture); GL_APICALL void GL_APIENTRY glDestroyStreamTextureCHROMIUM (GLuint texture); +GL_APICALL GLuint GL_APIENTRY glCreateImageCHROMIUM (GLsizei width, GLsizei height, GLenum internalformat); +GL_APICALL void GL_APIENTRY glDestroyImageCHROMIUM (GLuint image_id); +GL_APICALL void GL_APIENTRY glGetImageParameterivCHROMIUM (GLuint image_id, GLenum pname, GLint* params); GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLidShader shader, GLsizeiNotNegative bufsize, GLsizeiOptional* length, char* source); GL_APICALL void GL_APIENTRY glPostSubBufferCHROMIUM (GLint x, GLint y, GLint width, GLint height); GL_APICALL void GL_APIENTRY glTexImageIOSurface2DCHROMIUM (GLenumTextureBindTarget target, GLsizei width, GLsizei height, GLuint ioSurfaceId, GLuint plane); diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h index e78db86..1db8acf 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h @@ -41,6 +41,7 @@ static GLES2Util::EnumToString enum_to_string_table[] = { { 0x0003, "GL_LINE_STRIP", }, { 0x0000, "GL_POINTS", }, { 0x0001, "GL_LINES", }, + { 0x78F0, "GL_IMAGE_ROWBYTES_CHROMIUM", }, { 0x88B8, "GL_READ_ONLY", }, { 0x88B9, "GL_WRITE_ONLY_OES", }, { 0x8211, "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT", }, diff --git a/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc new file mode 100644 index 0000000..1598094 --- /dev/null +++ b/gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc @@ -0,0 +1,146 @@ +// 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 <GLES2/gl2.h> +#include <GLES2/gl2chromium.h> +#include <GLES2/gl2ext.h> +#include <GLES2/gl2extchromium.h> + +#include "base/bind.h" +#include "base/memory/ref_counted.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "gpu/command_buffer/client/gpu_memory_buffer_factory.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; +using testing::InvokeWithoutArgs; +using testing::Invoke; +using testing::Return; +using testing::SetArgPointee; +using testing::StrictMock; + +namespace gpu { +namespace gles2 { + +static const int kImageWidth = 256; +static const int kImageHeight = 256; +static const int kImageBytesPerPixel = 4; + +class MockGpuMemoryBufferTest : public testing::Test { + protected: + virtual void SetUp() { + GLManager::Options options; + image_manager_ = new ImageManager; + image_factory_.reset( + new StrictMock<ImageFactoryMock>(image_manager_)); + options.image_manager = image_manager_; + options.image_factory = image_factory_.get(); + + gl_.Initialize(options); + gl_.MakeCurrent(); + } + + virtual void TearDown() { + gl_.Destroy(); + } + + scoped_ptr<StrictMock<ImageFactoryMock> > image_factory_; + scoped_refptr<ImageManager> image_manager_; + GLManager gl_; +}; + +// 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); + + // Buffer is owned and freed by GpuMemoryBufferTracker. + StrictMock<GpuMemoryBufferMock>* gpu_memory_buffer = + new StrictMock<GpuMemoryBufferMock>(kImageWidth, kImageHeight); + + 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))) + .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); + + gfx::Size size(kImageWidth, kImageHeight); + scoped_refptr<gfx::GLImageMock> gl_image( + new gfx::GLImageMock(gpu_memory_buffer, 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]); + + EXPECT_CALL(*gpu_memory_buffer, Map(_, _)) + .Times(1) + .WillOnce(SetArgPointee<1>(buffer_pixels.get())) + .RetiresOnSaturation(); + void* mapped_buffer = + glMapImageCHROMIUM(image_id, GL_WRITE_ONLY); + EXPECT_EQ(buffer_pixels.get(), mapped_buffer); + + EXPECT_CALL(*gpu_memory_buffer, IsMapped()) + .WillOnce(Return(true)) + .RetiresOnSaturation(); + + // Unmap the image. + EXPECT_CALL(*gpu_memory_buffer, Unmap()) + .Times(1) + .RetiresOnSaturation(); + glUnmapImageCHROMIUM(image_id); + + // Bind the texture and the image. + glBindTexture(GL_TEXTURE_2D, texture_id); + EXPECT_CALL(*gl_image, BindTexImage()) + .Times(1) + .WillOnce(Return(true)) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_image, GetSize()) + .Times(1) + .WillOnce(Return(size)) + .RetiresOnSaturation(); + glBindTexImage2DCHROMIUM(GL_TEXTURE_2D, image_id); + + // Destroy the image. + EXPECT_CALL(*gpu_memory_buffer, Die()) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*image_factory_.get(), DeleteGpuMemoryBuffer(image_id)) + .Times(1) + .RetiresOnSaturation(); + + glDestroyImageCHROMIUM(image_id); + + // Delete the texture. + glDeleteTextures(1, &texture_id); +} + +} // namespace gles2 +} // namespace gpu diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc index 75a254a..3e55384 100644 --- a/gpu/command_buffer/tests/gl_manager.cc +++ b/gpu/command_buffer/tests/gl_manager.cc @@ -16,6 +16,7 @@ #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gl_context_virtual.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" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gl/gl_context.h" @@ -35,7 +36,9 @@ GLManager::Options::Options() share_mailbox_manager(NULL), virtual_manager(NULL), bind_generates_resource(false), - context_lost_allowed(false) { + context_lost_allowed(false), + image_manager(NULL), + image_factory(NULL) { } GLManager::GLManager() @@ -127,7 +130,7 @@ void GLManager::Initialize(const GLManager::Options& options) { if (!context_group) { context_group = new gles2::ContextGroup(mailbox_manager_.get(), - NULL, + options.image_manager, NULL, options.bind_generates_resource); } @@ -196,7 +199,8 @@ void GLManager::Initialize(const GLManager::Options& options) { client_share_group, transfer_buffer_.get(), kShareResources, - options.bind_generates_resource)); + options.bind_generates_resource, + options.image_factory)); 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 2ebe695..15fc9ef 100644 --- a/gpu/command_buffer/tests/gl_manager.h +++ b/gpu/command_buffer/tests/gl_manager.h @@ -30,6 +30,8 @@ class MailboxManager; class GLES2Decoder; class GLES2CmdHelper; class GLES2Implementation; +class ImageFactory; +class ImageManager; class ShareGroup; }; @@ -50,6 +52,10 @@ class GLManager { bool bind_generates_resource; // Whether or not it's ok to lose the context. bool context_lost_allowed; + // Image manager to be used. + gles2::ImageManager* image_manager; + // Image factory to be used. + gles2::ImageFactory* image_factory; }; GLManager(); ~GLManager(); diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 1d3fea6..6eb6eab 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc @@ -230,7 +230,8 @@ EGLContext Display::CreateContext(EGLConfig config, NULL, transfer_buffer_.get(), share_resources, - true)); + true, + NULL)); if (!context_->Initialize( kTransferBufferSize, diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp index 0492532..371f5cd 100644 --- a/gpu/gpu.gyp +++ b/gpu/gpu.gyp @@ -243,10 +243,15 @@ ], '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/gl_bind_uniform_location_unittest.cc', 'command_buffer/tests/gl_chromium_framebuffer_multisample_unittest.cc', 'command_buffer/tests/gl_copy_texture_CHROMIUM_unittest.cc', 'command_buffer/tests/gl_depth_texture_unittest.cc', + 'command_buffer/tests/gl_gpu_memory_buffer_unittests.cc', 'command_buffer/tests/gl_lose_context_chromium_unittests.cc', 'command_buffer/tests/gl_manager.cc', 'command_buffer/tests/gl_manager.h', diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi index 432457b..577c81b 100644 --- a/gpu/gpu_common.gypi +++ b/gpu/gpu_common.gypi @@ -39,6 +39,9 @@ 'command_buffer/client/gpu_memory_buffer.h', 'command_buffer/client/gpu_memory_buffer_factory.cc', 'command_buffer/client/gpu_memory_buffer_factory.h', + 'command_buffer/client/gpu_memory_buffer_tracker.h', + 'command_buffer/client/gpu_memory_buffer_tracker.cc', + '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', |