summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorkaanb@chromium.org <kaanb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-16 10:46:01 +0000
committerkaanb@chromium.org <kaanb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-16 10:46:01 +0000
commite9ec4269f805d8abcb187890a6ec82c4fffb861a (patch)
tree4e46f3971b5e764ea795305a6010dad3abf2ff1c /gpu
parentb9ed58f046141b4610c1bdc966d962d5fb95ac6b (diff)
downloadchromium_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')
-rw-r--r--gpu/GLES2/extensions/CHROMIUM/CHROMIUM_map_image.txt107
-rw-r--r--gpu/GLES2/gl2chromium_autogen.h6
-rw-r--r--gpu/GLES2/gl2extchromium.h33
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py40
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h28
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc175
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h18
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h12
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest.cc3
-rw-r--r--gpu/command_buffer/client/gles2_interface_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h15
-rw-r--r--gpu/command_buffer/client/gles2_trace_implementation_autogen.h7
-rw-r--r--gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h28
-rw-r--r--gpu/command_buffer/client/gpu_memory_buffer.h2
-rw-r--r--gpu/command_buffer/client/gpu_memory_buffer_factory.cc4
-rw-r--r--gpu/command_buffer/client/gpu_memory_buffer_factory.h2
-rw-r--r--gpu/command_buffer/client/gpu_memory_buffer_mock.cc16
-rw-r--r--gpu/command_buffer/client/gpu_memory_buffer_mock.h32
-rw-r--r--gpu/command_buffer/client/gpu_memory_buffer_tracker.cc57
-rw-r--r--gpu/command_buffer/client/gpu_memory_buffer_tracker.h43
-rw-r--r--gpu/command_buffer/client/image_factory.h33
-rw-r--r--gpu/command_buffer/client/image_factory_mock.cc17
-rw-r--r--gpu/command_buffer/client/image_factory_mock.h41
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt5
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h1
-rw-r--r--gpu/command_buffer/tests/gl_gpu_memory_buffer_unittests.cc146
-rw-r--r--gpu/command_buffer/tests/gl_manager.cc10
-rw-r--r--gpu/command_buffer/tests/gl_manager.h6
-rw-r--r--gpu/gles2_conform_support/egl/display.cc3
-rw-r--r--gpu/gpu.gyp5
-rw-r--r--gpu/gpu_common.gypi3
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',