summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-18 05:15:50 +0000
committerreveman@chromium.org <reveman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-18 05:15:50 +0000
commitf4ba36512524dc3150261942ec9a89b4dfb7364a (patch)
treee9f7e293728188a158b4156a03eb713f5eeebada /gpu
parentfcb0f644c83064a695588aa74d755aff74a51286 (diff)
downloadchromium_src-f4ba36512524dc3150261942ec9a89b4dfb7364a.zip
chromium_src-f4ba36512524dc3150261942ec9a89b4dfb7364a.tar.gz
chromium_src-f4ba36512524dc3150261942ec9a89b4dfb7364a.tar.bz2
gpu: Add support for GLX_EXT_texture_from_pixmap extension.
Implement CHROMIUM_texture_from_image. This extension behaves just like EXT_texture_from_pixmap but uses chromium specific image identifiers rather than platform specific pixmap IDs. Add IPC message for creating an image identifier using a gfx::PluginWindowHandle. Each GPU channel maintains a different set of images and deleting an image will cause the internal image representation to be freed once it's no longer bound to a texture. BUG=132342 TEST=gpu_unittests --gtest_filter=TextureInfoTest.GetLevelImage:GLES2DecoderTest.BindTexImage2DCHROMIUM:GLES2DecoderTest.ReleaseTexImage2DCHROMIUM and manual Review URL: https://chromiumcodereview.appspot.com/10543125 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162654 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py12
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h6
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h16
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h12
-rw-r--r--gpu/command_buffer/client/gles2_implementation_unittest_autogen.h22
-rw-r--r--gpu/command_buffer/cmd_buffer_functions.txt3
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h76
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h30
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h2
-rw-r--r--gpu/command_buffer/service/context_group.cc3
-rw-r--r--gpu/command_buffer/service/context_group.h7
-rw-r--r--gpu/command_buffer/service/context_group_unittest.cc2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc250
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h24
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc82
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h2
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc1
-rw-r--r--gpu/command_buffer/service/image_manager.cc35
-rw-r--r--gpu/command_buffer/service/image_manager.h43
-rw-r--r--gpu/command_buffer/service/texture_manager.cc61
-rw-r--r--gpu/command_buffer/service/texture_manager.h20
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc20
-rw-r--r--gpu/command_buffer/tests/gl_manager.cc1
-rw-r--r--gpu/command_buffer_service.gypi2
-rw-r--r--gpu/gles2_conform_support/egl/display.cc1
25 files changed, 656 insertions, 77 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 1b9db9f..21b8e69 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1759,6 +1759,18 @@ _FUNCTION_INFO = {
'expectation': False,
'unit_test': False,
},
+ 'BindTexImage2DCHROMIUM': {
+ 'decoder_func': 'DoBindTexImage2DCHROMIUM',
+ 'unit_test': False,
+ 'extension': True,
+ 'chromium': True,
+ },
+ 'ReleaseTexImage2DCHROMIUM': {
+ 'decoder_func': 'DoReleaseTexImage2DCHROMIUM',
+ 'unit_test': False,
+ 'extension': True,
+ 'chromium': True,
+ },
}
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index 8e5b255..a0d3fa6 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -679,6 +679,12 @@ void GLES2BindUniformLocationCHROMIUM(
GLuint program, GLint location, const char* name) {
gles2::GetGLContext()->BindUniformLocationCHROMIUM(program, location, name);
}
+void GLES2BindTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+ gles2::GetGLContext()->BindTexImage2DCHROMIUM(target, imageId);
+}
+void GLES2ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+ gles2::GetGLContext()->ReleaseTexImage2DCHROMIUM(target, imageId);
+}
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_C_LIB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index c311d6c..080cc8a 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1902,5 +1902,21 @@
}
}
+ void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+ gles2::BindTexImage2DCHROMIUM* c =
+ GetCmdSpace<gles2::BindTexImage2DCHROMIUM>();
+ if (c) {
+ c->Init(target, imageId);
+ }
+ }
+
+ void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+ gles2::ReleaseTexImage2DCHROMIUM* c =
+ GetCmdSpace<gles2::ReleaseTexImage2DCHROMIUM>();
+ if (c) {
+ c->Init(target, imageId);
+ }
+ }
+
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 7ecd17d..57835fb 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -498,5 +498,17 @@ virtual void ConsumeTextureCHROMIUM(
virtual void BindUniformLocationCHROMIUM(
GLuint program, GLint location, const char* name) OVERRIDE;
+void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindTexImage2DCHROMIUM(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << imageId << ")"); // NOLINT
+ helper_->BindTexImage2DCHROMIUM(target, imageId);
+}
+
+void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) {
+ GPU_CLIENT_SINGLE_THREAD_CHECK();
+ GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReleaseTexImage2DCHROMIUM(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << imageId << ")"); // NOLINT
+ helper_->ReleaseTexImage2DCHROMIUM(target, imageId);
+}
+
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index a70a73e..0692887 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -1771,5 +1771,27 @@ TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
}
// TODO: Implement unit test for BindUniformLocationCHROMIUM
+
+TEST_F(GLES2ImplementationTest, BindTexImage2DCHROMIUM) {
+ struct Cmds {
+ BindTexImage2DCHROMIUM cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(GL_TEXTURE_2D, 2);
+
+ gl_->BindTexImage2DCHROMIUM(GL_TEXTURE_2D, 2);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
+
+TEST_F(GLES2ImplementationTest, ReleaseTexImage2DCHROMIUM) {
+ struct Cmds {
+ ReleaseTexImage2DCHROMIUM cmd;
+ };
+ Cmds expected;
+ expected.cmd.Init(GL_TEXTURE_2D, 2);
+
+ gl_->ReleaseTexImage2DCHROMIUM(GL_TEXTURE_2D, 2);
+ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_UNITTEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index 0ad28c8..f9914a9 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -196,4 +196,5 @@ GL_APICALL void GL_APIENTRY glGenMailboxCHROMIUM (GLbyte* mailbox);
GL_APICALL void GL_APIENTRY glProduceTextureCHROMIUM (GLenumTextureTarget target, const GLbyte* mailbox);
GL_APICALL void GL_APIENTRY glConsumeTextureCHROMIUM (GLenumTextureTarget target, const GLbyte* mailbox);
GL_APICALL void GL_APIENTRY glBindUniformLocationCHROMIUM (GLidProgram program, GLint location, const char* name);
-
+GL_APICALL void GL_APIENTRY glBindTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId);
+GL_APICALL void GL_APIENTRY glReleaseTexImage2DCHROMIUM (GLenumTextureBindTarget target, GLint imageId);
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index 04fd1b2..4a0e20e 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -10432,6 +10432,82 @@ COMPILE_ASSERT(
offsetof(BindUniformLocationCHROMIUMBucket, name_bucket_id) == 12,
OffsetOf_BindUniformLocationCHROMIUMBucket_name_bucket_id_not_12); // NOLINT
+struct BindTexImage2DCHROMIUM {
+ typedef BindTexImage2DCHROMIUM ValueType;
+ static const CommandId kCmdId = kBindTexImage2DCHROMIUM;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmd<ValueType>();
+ }
+
+ void Init(GLenum _target, GLint _imageId) {
+ SetHeader();
+ target = _target;
+ imageId = _imageId;
+ }
+
+ void* Set(void* cmd, GLenum _target, GLint _imageId) {
+ static_cast<ValueType*>(cmd)->Init(_target, _imageId);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 target;
+ int32 imageId;
+};
+
+COMPILE_ASSERT(sizeof(BindTexImage2DCHROMIUM) == 12,
+ Sizeof_BindTexImage2DCHROMIUM_is_not_12);
+COMPILE_ASSERT(offsetof(BindTexImage2DCHROMIUM, header) == 0,
+ OffsetOf_BindTexImage2DCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(BindTexImage2DCHROMIUM, target) == 4,
+ OffsetOf_BindTexImage2DCHROMIUM_target_not_4);
+COMPILE_ASSERT(offsetof(BindTexImage2DCHROMIUM, imageId) == 8,
+ OffsetOf_BindTexImage2DCHROMIUM_imageId_not_8);
+
+struct ReleaseTexImage2DCHROMIUM {
+ typedef ReleaseTexImage2DCHROMIUM ValueType;
+ static const CommandId kCmdId = kReleaseTexImage2DCHROMIUM;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmd<ValueType>();
+ }
+
+ void Init(GLenum _target, GLint _imageId) {
+ SetHeader();
+ target = _target;
+ imageId = _imageId;
+ }
+
+ void* Set(void* cmd, GLenum _target, GLint _imageId) {
+ static_cast<ValueType*>(cmd)->Init(_target, _imageId);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 target;
+ int32 imageId;
+};
+
+COMPILE_ASSERT(sizeof(ReleaseTexImage2DCHROMIUM) == 12,
+ Sizeof_ReleaseTexImage2DCHROMIUM_is_not_12);
+COMPILE_ASSERT(offsetof(ReleaseTexImage2DCHROMIUM, header) == 0,
+ OffsetOf_ReleaseTexImage2DCHROMIUM_header_not_0);
+COMPILE_ASSERT(offsetof(ReleaseTexImage2DCHROMIUM, target) == 4,
+ OffsetOf_ReleaseTexImage2DCHROMIUM_target_not_4);
+COMPILE_ASSERT(offsetof(ReleaseTexImage2DCHROMIUM, imageId) == 8,
+ OffsetOf_ReleaseTexImage2DCHROMIUM_imageId_not_8);
+
#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index cee8095..a7b1e85 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -4202,5 +4202,35 @@ TEST_F(GLES2FormatTest, BindUniformLocationCHROMIUMBucket) {
next_cmd, sizeof(cmd));
}
+TEST_F(GLES2FormatTest, BindTexImage2DCHROMIUM) {
+ BindTexImage2DCHROMIUM& cmd = *GetBufferAs<BindTexImage2DCHROMIUM>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ static_cast<GLint>(12));
+ EXPECT_EQ(static_cast<uint32>(BindTexImage2DCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ EXPECT_EQ(static_cast<GLint>(12), cmd.imageId);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd));
+}
+
+TEST_F(GLES2FormatTest, ReleaseTexImage2DCHROMIUM) {
+ ReleaseTexImage2DCHROMIUM& cmd = *GetBufferAs<ReleaseTexImage2DCHROMIUM>();
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ static_cast<GLint>(12));
+ EXPECT_EQ(static_cast<uint32>(ReleaseTexImage2DCHROMIUM::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ EXPECT_EQ(static_cast<GLint>(12), cmd.imageId);
+ CheckBytesWrittenMatchesExpectedSize(
+ next_cmd, sizeof(cmd));
+}
+
#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index bed63e2..6543de3 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -239,6 +239,8 @@
OP(BindUniformLocationCHROMIUM) /* 482 */ \
OP(BindUniformLocationCHROMIUMImmediate) /* 483 */ \
OP(BindUniformLocationCHROMIUMBucket) /* 484 */ \
+ OP(BindTexImage2DCHROMIUM) /* 485 */ \
+ OP(ReleaseTexImage2DCHROMIUM) /* 486 */ \
enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index ecaf700..3fe50ad 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -14,6 +14,7 @@
#include "gpu/command_buffer/service/framebuffer_manager.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/program_manager.h"
@@ -28,9 +29,11 @@ namespace gles2 {
ContextGroup::ContextGroup(
MailboxManager* mailbox_manager,
+ ImageManager* image_manager,
MemoryTracker* memory_tracker,
bool bind_generates_resource)
: mailbox_manager_(mailbox_manager ? mailbox_manager : new MailboxManager),
+ image_manager_(image_manager ? image_manager : new ImageManager),
memory_tracker_(memory_tracker),
num_contexts_(0),
enforce_gl_minimums_(CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index 671d0ff..c459c56 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -27,6 +27,7 @@ class ProgramCache;
class BufferManager;
class GLES2Decoder;
class FramebufferManager;
+class ImageManager;
class MailboxManager;
class RenderbufferManager;
class ProgramManager;
@@ -43,6 +44,7 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
ContextGroup(
MailboxManager* mailbox_manager,
+ ImageManager* image_manager,
MemoryTracker* memory_tracker,
bool bind_generates_resource);
@@ -59,6 +61,10 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
return mailbox_manager_.get();
}
+ ImageManager* image_manager() const {
+ return image_manager_.get();
+ }
+
MemoryTracker* memory_tracker() const {
return memory_tracker_.get();
}
@@ -149,6 +155,7 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
bool QueryGLFeatureU(GLenum pname, GLint min_required, uint32* v);
scoped_refptr<MailboxManager> mailbox_manager_;
+ scoped_refptr<ImageManager> image_manager_;
scoped_refptr<MemoryTracker> memory_tracker_;
scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_;
diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc
index 6f6c919..5a15abf 100644
--- a/gpu/command_buffer/service/context_group_unittest.cc
+++ b/gpu/command_buffer/service/context_group_unittest.cc
@@ -36,7 +36,7 @@ class ContextGroupTest : public testing::Test {
virtual void SetUp() {
gl_.reset(new ::testing::StrictMock< ::gfx::MockGLInterface>());
::gfx::GLInterface::SetGLInterface(gl_.get());
- group_ = ContextGroup::Ref(new ContextGroup(NULL, NULL, true));
+ group_ = ContextGroup::Ref(new ContextGroup(NULL, NULL, NULL, true));
}
virtual void TearDown() {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 748eb21..f7e3ebc 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -39,6 +39,7 @@
#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h"
#include "gpu/command_buffer/service/gles2_cmd_validation.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/memory_tracking.h"
#include "gpu/command_buffer/service/program_manager.h"
@@ -54,6 +55,7 @@
#include "gpu/command_buffer/service/vertex_attrib_manager.h"
#include "gpu/command_buffer/service/vertex_array_manager.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_image.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_surface.h"
#if defined(OS_MACOSX)
@@ -616,6 +618,10 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
return group_->mailbox_manager();
}
+ ImageManager* image_manager() {
+ return group_->image_manager();
+ }
+
VertexArrayManager* vertex_array_manager() {
return vertex_array_manager_.get();
}
@@ -653,100 +659,107 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Wrapper for CompressedTexImage2D commands.
error::Error DoCompressedTexImage2D(
- GLenum target,
- GLint level,
- GLenum internal_format,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLsizei image_size,
- const void* data);
+ GLenum target,
+ GLint level,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLsizei image_size,
+ const void* data);
// Wrapper for CompressedTexSubImage2D.
void DoCompressedTexSubImage2D(
- GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLsizei imageSize,
- const void * data);
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLsizei imageSize,
+ const void * data);
// Wrapper for CopyTexImage2D.
void DoCopyTexImage2D(
- GLenum target,
- GLint level,
- GLenum internal_format,
- GLint x,
- GLint y,
- GLsizei width,
- GLsizei height,
- GLint border);
+ GLenum target,
+ GLint level,
+ GLenum internal_format,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height,
+ GLint border);
// Wrapper for CopyTexSubImage2D.
void DoCopyTexSubImage2D(
- GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLint x,
- GLint y,
- GLsizei width,
- GLsizei height);
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLint x,
+ GLint y,
+ GLsizei width,
+ GLsizei height);
// Wrapper for TexImage2D commands.
error::Error DoTexImage2D(
- GLenum target,
- GLint level,
- GLenum internal_format,
- GLsizei width,
- GLsizei height,
- GLint border,
- GLenum format,
- GLenum type,
- const void* pixels,
- uint32 pixels_size);
+ GLenum target,
+ GLint level,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height,
+ GLint border,
+ GLenum format,
+ GLenum type,
+ const void* pixels,
+ uint32 pixels_size);
// Wrapper for TexSubImage2D.
void DoTexSubImage2D(
- GLenum target,
- GLint level,
- GLint xoffset,
- GLint yoffset,
- GLsizei width,
- GLsizei height,
- GLenum format,
- GLenum type,
- const void * data);
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLint yoffset,
+ GLsizei width,
+ GLsizei height,
+ GLenum format,
+ GLenum type,
+ const void * data);
// Wrapper for TexImageIOSurface2DCHROMIUM.
void DoTexImageIOSurface2DCHROMIUM(
- GLenum target,
- GLsizei width,
- GLsizei height,
- GLuint io_surface_id,
- GLuint plane);
+ GLenum target,
+ GLsizei width,
+ GLsizei height,
+ GLuint io_surface_id,
+ GLuint plane);
void DoCopyTextureCHROMIUM(
- GLenum target,
- GLuint source_id,
- GLuint target_id,
- GLint level,
- GLenum internal_format);
+ GLenum target,
+ GLuint source_id,
+ GLuint target_id,
+ GLint level,
+ GLenum internal_format);
// Wrapper for TexStorage2DEXT.
void DoTexStorage2DEXT(
- GLenum target,
- GLint levels,
- GLenum internal_format,
- GLsizei width,
- GLsizei height);
+ GLenum target,
+ GLint levels,
+ GLenum internal_format,
+ GLsizei width,
+ GLsizei height);
void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key);
void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key);
+ void DoBindTexImage2DCHROMIUM(
+ GLenum target,
+ GLint image_id);
+ void DoReleaseTexImage2DCHROMIUM(
+ GLenum target,
+ GLint image_id);
+
// Creates a ProgramInfo for the given program.
ProgramManager::ProgramInfo* CreateProgramInfo(
GLuint client_id, GLuint service_id) {
@@ -1268,6 +1281,16 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
return info;
}
+ TextureManager::TextureInfo* GetTextureInfoForTargetUnlessDefault(
+ GLenum target) {
+ TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
+ if (!info)
+ return NULL;
+ if (info == texture_manager()->GetDefaultTextureInfo(target))
+ return NULL;
+ return info;
+ }
+
GLenum GetBindTargetForSamplerType(GLenum type) {
DCHECK(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE ||
type == GL_SAMPLER_EXTERNAL_OES || type == GL_SAMPLER_2D_RECT_ARB);
@@ -8922,18 +8945,15 @@ void GLES2DecoderImpl::DoTexImageIOSurface2DCHROMIUM(
return;
}
- TextureManager::TextureInfo* info = GetTextureInfoForTarget(target);
+ // Default target might be conceptually valid, but disallow it to avoid
+ // accidents.
+ TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
+ target);
if (!info) {
SetGLError(GL_INVALID_OPERATION,
"glTexImageIOSurface2DCHROMIUM", "no rectangle texture bound");
return;
}
- if (info == texture_manager()->GetDefaultTextureInfo(target)) {
- // Maybe this is conceptually valid, but disallow it to avoid accidents.
- SetGLError(GL_INVALID_OPERATION,
- "glTexImageIOSurface2DCHROMIUM", "can't bind default texture");
- return;
- }
// Look up the new IOSurface. Note that because of asynchrony
// between processes this might fail; during live resizing the
@@ -9333,6 +9353,88 @@ void GLES2DecoderImpl::DoPopGroupMarkerEXT(void) {
debug_marker_manager_.PopGroup();
}
+void GLES2DecoderImpl::DoBindTexImage2DCHROMIUM(
+ GLenum target, GLint image_id) {
+ TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoBindTexImage2DCHROMIUM");
+ if (target != GL_TEXTURE_2D) {
+ // This might be supported in the future.
+ SetGLError(
+ GL_INVALID_OPERATION,
+ "glBindTexImage2DCHROMIUM", "requires TEXTURE_2D target");
+ return;
+ }
+
+ // Default target might be conceptually valid, but disallow it to avoid
+ // accidents.
+ TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
+ target);
+ if (!info) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glBindTexImage2DCHROMIUM", "no texture bound");
+ return;
+ }
+
+ gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
+ if (!gl_image) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glBindTexImage2DCHROMIUM",
+ "no image found with the given ID");
+ return;
+ }
+
+ if (!gl_image->BindTexImage()) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glBindTexImage2DCHROMIUM",
+ "fail to bind image with the given ID");
+ return;
+ }
+
+ gfx::Size size = gl_image->GetSize();
+ texture_manager()->SetLevelInfo(
+ info, target, 0, GL_RGBA, size.width(), size.height(), 1, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, true);
+ texture_manager()->SetLevelImage(info, target, 0, gl_image);
+}
+
+void GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM(
+ GLenum target, GLint image_id) {
+ TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoReleaseTexImage2DCHROMIUM");
+ if (target != GL_TEXTURE_2D) {
+ // This might be supported in the future.
+ SetGLError(
+ GL_INVALID_OPERATION,
+ "glReleaseTexImage2DCHROMIUM", "requires TEXTURE_2D target");
+ return;
+ }
+
+ // Default target might be conceptually valid, but disallow it to avoid
+ // accidents.
+ TextureManager::TextureInfo* info = GetTextureInfoForTargetUnlessDefault(
+ target);
+ if (!info) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glReleaseTexImage2DCHROMIUM", "no texture bound");
+ return;
+ }
+
+ gfx::GLImage* gl_image = image_manager()->LookupImage(image_id);
+ if (!gl_image) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glReleaseTexImage2DCHROMIUM",
+ "no image found with the given ID");
+ return;
+ }
+
+ // Do nothing when image is not currently bound.
+ if (info->GetLevelImage(target, 0) != gl_image)
+ return;
+
+ gl_image->ReleaseTexImage();
+
+ texture_manager()->SetLevelInfo(
+ info, target, 0, GL_RGBA, 0, 0, 1, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, false);
+}
// 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
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index e347ba8..fe5806f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -2887,5 +2887,29 @@ error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUMImmediate(
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleBindTexImage2DCHROMIUM(
+ uint32 immediate_data_size, const gles2::BindTexImage2DCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLint imageId = static_cast<GLint>(c.imageId);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ SetGLErrorInvalidEnum("glBindTexImage2DCHROMIUM", target, "target");
+ return error::kNoError;
+ }
+ DoBindTexImage2DCHROMIUM(target, imageId);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleReleaseTexImage2DCHROMIUM(
+ uint32 immediate_data_size, const gles2::ReleaseTexImage2DCHROMIUM& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLint imageId = static_cast<GLint>(c.imageId);
+ if (!validators_->texture_bind_target.IsValid(target)) {
+ SetGLErrorInvalidEnum("glReleaseTexImage2DCHROMIUM", target, "target");
+ return error::kNoError;
+ }
+ DoReleaseTexImage2DCHROMIUM(target, imageId);
+ return error::kNoError;
+}
+
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 59e82c9..b698bf9 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -13,6 +13,7 @@
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/gl_surface_mock.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h"
+#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
#include "gpu/command_buffer/service/program_manager.h"
#include "gpu/command_buffer/service/stream_texture_manager_mock.h"
@@ -7807,6 +7808,87 @@ TEST_F(GLES2DecoderEmulatedVertexArraysOESTest,
BindVertexArrayOESValidArgsNewId();
}
+TEST_F(GLES2DecoderTest, BindTexImage2DCHROMIUM) {
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ 0, 0);
+ TextureManager::TextureInfo* info =
+ group().texture_manager()->GetTextureInfo(client_texture_id_);
+ EXPECT_EQ(kServiceTextureId, info->service_id());
+
+ group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0), 1);
+ EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
+
+ GLsizei width;
+ GLsizei height;
+ GLenum type;
+ GLenum internal_format;
+
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+ EXPECT_EQ(3, width);
+ EXPECT_EQ(1, height);
+ EXPECT_TRUE(info->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+ EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+ EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+ EXPECT_TRUE(info->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+
+ // Bind image to texture.
+ BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
+ bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+ // Image should now be set.
+ EXPECT_FALSE(info->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+
+ // Define new texture image.
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ 0, 0);
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+ // Image should no longer be set.
+ EXPECT_TRUE(info->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+}
+
+TEST_F(GLES2DecoderTest, ReleaseTexImage2DCHROMIUM) {
+ DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
+ DoTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ 0, 0);
+ TextureManager::TextureInfo* info =
+ group().texture_manager()->GetTextureInfo(client_texture_id_);
+ EXPECT_EQ(kServiceTextureId, info->service_id());
+
+ group().image_manager()->AddImage(gfx::GLImage::CreateGLImage(0), 1);
+ EXPECT_FALSE(group().image_manager()->LookupImage(1) == NULL);
+
+ GLsizei width;
+ GLsizei height;
+ GLenum type;
+ GLenum internal_format;
+
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+ EXPECT_EQ(3, width);
+ EXPECT_EQ(1, height);
+ EXPECT_TRUE(info->GetLevelType(GL_TEXTURE_2D, 0, &type, &internal_format));
+ EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format);
+ EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type);
+ EXPECT_TRUE(info->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+
+ // Bind image to texture.
+ BindTexImage2DCHROMIUM bind_tex_image_2d_cmd;
+ bind_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(bind_tex_image_2d_cmd));
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+ // Image should now be set.
+ EXPECT_FALSE(info->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+
+ // Release image from texture.
+ ReleaseTexImage2DCHROMIUM release_tex_image_2d_cmd;
+ release_tex_image_2d_cmd.Init(GL_TEXTURE_2D, 1);
+ EXPECT_EQ(error::kNoError, ExecuteCmd(release_tex_image_2d_cmd));
+ EXPECT_TRUE(info->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height));
+ // Image should no longer be set.
+ EXPECT_TRUE(info->GetLevelImage(GL_TEXTURE_2D, 0) == NULL);
+}
+
// TODO(gman): Complete this test.
// TEST_F(GLES2DecoderTest, CompressedTexImage2DGLError) {
// }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
index ff37553..79ec1c2 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_3_autogen.h
@@ -55,5 +55,7 @@
// TODO(gman): BindUniformLocationCHROMIUMImmediate
// TODO(gman): BindUniformLocationCHROMIUMBucket
+// TODO(gman): BindTexImage2DCHROMIUM
+// TODO(gman): ReleaseTexImage2DCHROMIUM
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index b51aa55..f8a77d1 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -88,6 +88,7 @@ void GLES2DecoderTestBase::InitDecoder(
::gfx::GLInterface::SetGLInterface(gl_.get());
group_ = ContextGroup::Ref(new ContextGroup(NULL,
NULL,
+ NULL,
bind_generates_resource));
InSequence sequence;
diff --git a/gpu/command_buffer/service/image_manager.cc b/gpu/command_buffer/service/image_manager.cc
new file mode 100644
index 0000000..b424770
--- /dev/null
+++ b/gpu/command_buffer/service/image_manager.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/image_manager.h"
+
+#include "ui/gl/gl_image.h"
+
+namespace gpu {
+namespace gles2 {
+
+ImageManager::ImageManager() {
+}
+
+ImageManager::~ImageManager() {
+}
+
+void ImageManager::AddImage(gfx::GLImage* image, int32 service_id) {
+ gl_images_[service_id] = image;
+}
+
+void ImageManager::RemoveImage(int32 service_id) {
+ gl_images_.erase(service_id);
+}
+
+gfx::GLImage* ImageManager::LookupImage(int32 service_id) {
+ GLImageMap::const_iterator iter = gl_images_.find(service_id);
+ if (iter != gl_images_.end())
+ return iter->second;
+
+ return NULL;
+}
+
+} // namespace gles2
+} // namespace gpu
diff --git a/gpu/command_buffer/service/image_manager.h b/gpu/command_buffer/service/image_manager.h
new file mode 100644
index 0000000..06a02bc
--- /dev/null
+++ b/gpu/command_buffer/service/image_manager.h
@@ -0,0 +1,43 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_
+#define GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_
+
+#include "base/basictypes.h"
+#include "base/hash_tables.h"
+#include "base/memory/ref_counted.h"
+#include "gpu/gpu_export.h"
+
+namespace gfx {
+class GLImage;
+}
+
+namespace gpu {
+namespace gles2 {
+
+// Interface used by the cmd decoder to lookup images.
+class GPU_EXPORT ImageManager : public base::RefCounted<ImageManager> {
+ public:
+ ImageManager();
+
+ void AddImage(gfx::GLImage* gl_image, int32 service_id);
+ void RemoveImage(int32 service_id);
+ gfx::GLImage* LookupImage(int32 service_id);
+
+ private:
+ friend class base::RefCounted<ImageManager>;
+
+ ~ImageManager();
+
+ typedef base::hash_map<uint32, scoped_refptr<gfx::GLImage> > GLImageMap;
+ GLImageMap gl_images_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageManager);
+};
+
+} // namespage gles2
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_IMAGE_MANAGER_H_
diff --git a/gpu/command_buffer/service/texture_manager.cc b/gpu/command_buffer/service/texture_manager.cc
index 7c378d4..3206281 100644
--- a/gpu/command_buffer/service/texture_manager.cc
+++ b/gpu/command_buffer/service/texture_manager.cc
@@ -150,9 +150,13 @@ TextureManager::TextureInfo::LevelInfo::LevelInfo(const LevelInfo& rhs)
border(rhs.border),
format(rhs.format),
type(rhs.type),
+ image(rhs.image),
estimated_size(rhs.estimated_size) {
}
+TextureManager::TextureInfo::LevelInfo::~LevelInfo() {
+}
+
bool TextureManager::TextureInfo::CanRender(
const FeatureInfo* feature_info) const {
if (target_ == 0) {
@@ -252,7 +256,8 @@ bool TextureManager::TextureInfo::CanGenerateMipmaps(
(info.internal_format != first.internal_format) ||
(info.type != first.type) ||
feature_info->validators()->compressed_texture_format.IsValid(
- info.internal_format)) {
+ info.internal_format) ||
+ info.image) {
return false;
}
}
@@ -327,6 +332,7 @@ void TextureManager::TextureInfo::SetLevelInfo(
info.border = border;
info.format = format;
info.type = type;
+ info.image = 0;
estimated_size_ -= info.estimated_size;
GLES2Util::ComputeImageDataSizes(
@@ -616,6 +622,36 @@ bool TextureManager::TextureInfo::ClearLevel(
return info.cleared;
}
+void TextureManager::TextureInfo::SetLevelImage(
+ const FeatureInfo* feature_info,
+ GLenum target,
+ GLint level,
+ gfx::GLImage* image) {
+ DCHECK_GE(level, 0);
+ DCHECK_LT(static_cast<size_t>(GLTargetToFaceIndex(target)),
+ level_infos_.size());
+ DCHECK_LT(static_cast<size_t>(level),
+ level_infos_[GLTargetToFaceIndex(target)].size());
+ TextureInfo::LevelInfo& info =
+ level_infos_[GLTargetToFaceIndex(target)][level];
+ DCHECK_EQ(info.target, target);
+ DCHECK_EQ(info.level, level);
+ info.image = image;
+}
+
+gfx::GLImage* TextureManager::TextureInfo::GetLevelImage(
+ GLint face, GLint level) const {
+ size_t face_index = GLTargetToFaceIndex(face);
+ if (level >= 0 && face_index < level_infos_.size() &&
+ static_cast<size_t>(level) < level_infos_[face_index].size()) {
+ const LevelInfo& info = level_infos_[GLTargetToFaceIndex(face)][level];
+ if (info.target != 0) {
+ return info.image;
+ }
+ }
+ return 0;
+}
+
TextureManager::TextureManager(
MemoryTracker* memory_tracker,
FeatureInfo* feature_info,
@@ -1070,5 +1106,28 @@ GLsizei TextureManager::ComputeMipMapCount(
return 1 + base::bits::Log2Floor(std::max(std::max(width, height), depth));
}
+void TextureManager::SetLevelImage(
+ TextureManager::TextureInfo* info,
+ GLenum target,
+ GLint level,
+ gfx::GLImage* image) {
+ DCHECK(info);
+ if (!info->CanRender(feature_info_)) {
+ DCHECK_NE(0, num_unrenderable_textures_);
+ --num_unrenderable_textures_;
+ }
+ if (!info->SafeToRenderFrom()) {
+ DCHECK_NE(0, num_unsafe_textures_);
+ --num_unsafe_textures_;
+ }
+ info->SetLevelImage(feature_info_, target, level, image);
+ if (!info->CanRender(feature_info_)) {
+ ++num_unrenderable_textures_;
+ }
+ if (!info->SafeToRenderFrom()) {
+ ++num_unsafe_textures_;
+ }
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/texture_manager.h b/gpu/command_buffer/service/texture_manager.h
index 26c0c0c..ef9e020 100644
--- a/gpu/command_buffer/service/texture_manager.h
+++ b/gpu/command_buffer/service/texture_manager.h
@@ -13,6 +13,7 @@
#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gl_utils.h"
#include "gpu/gpu_export.h"
+#include "ui/gl/gl_image.h"
namespace gpu {
namespace gles2 {
@@ -124,6 +125,10 @@ class GPU_EXPORT TextureManager {
bool GetLevelType(
GLint face, GLint level, GLenum* type, GLenum* internal_format) const;
+ // Get the image bound to a particular level. Returns NULL if level
+ // does not exist.
+ gfx::GLImage* GetLevelImage(GLint face, GLint level) const;
+
bool IsDeleted() const {
return deleted_;
}
@@ -189,6 +194,7 @@ class GPU_EXPORT TextureManager {
struct LevelInfo {
LevelInfo();
LevelInfo(const LevelInfo& rhs);
+ ~LevelInfo();
bool cleared;
GLenum target;
@@ -200,6 +206,7 @@ class GPU_EXPORT TextureManager {
GLint border;
GLenum format;
GLenum type;
+ scoped_refptr<gfx::GLImage> image;
uint32 estimated_size;
};
@@ -265,6 +272,13 @@ class GPU_EXPORT TextureManager {
// Update info about this texture.
void Update(const FeatureInfo* feature_info);
+ // Set the image for a particular level.
+ void SetLevelImage(
+ const FeatureInfo* feature_info,
+ GLenum target,
+ GLint level,
+ gfx::GLImage* image);
+
// Info about each face and level of texture.
std::vector<std::vector<LevelInfo> > level_infos_;
@@ -490,6 +504,12 @@ class GPU_EXPORT TextureManager {
return mem_represented_;
}
+ void SetLevelImage(
+ TextureInfo* info,
+ GLenum target,
+ GLint level,
+ gfx::GLImage* image);
+
private:
// Helper for Initialize().
TextureInfo::Ref CreateDefaultAndBlackTextures(
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index dad2cf1..487bde7 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -999,6 +999,26 @@ TEST_F(TextureInfoTest, UseDeletedTexture) {
info = NULL;
}
+TEST_F(TextureInfoTest, GetLevelImage) {
+ manager_.SetInfoTarget(info_, GL_TEXTURE_2D);
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
+ EXPECT_TRUE(info_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL);
+ // Set image.
+ manager_.SetLevelImage(info_,
+ GL_TEXTURE_2D, 1, gfx::GLImage::CreateGLImage(0));
+ EXPECT_FALSE(info_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL);
+ // Remove it.
+ manager_.SetLevelImage(info_, GL_TEXTURE_2D, 1, NULL);
+ EXPECT_TRUE(info_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL);
+ manager_.SetLevelImage(info_,
+ GL_TEXTURE_2D, 1, gfx::GLImage::CreateGLImage(0));
+ // Image should be reset when SetLevelInfo is called.
+ manager_.SetLevelInfo(info_,
+ GL_TEXTURE_2D, 1, GL_RGBA, 2, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, true);
+ EXPECT_TRUE(info_->GetLevelImage(GL_TEXTURE_2D, 1) == NULL);
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 45589b6..fc2ab61 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -99,6 +99,7 @@ void GLManager::Setup(
if (!context_group) {
context_group = new gles2::ContextGroup(mailbox_manager_.get(),
NULL,
+ NULL,
kBindGeneratesResource);
}
diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi
index 06fda1b..78f4078 100644
--- a/gpu/command_buffer_service.gypi
+++ b/gpu/command_buffer_service.gypi
@@ -57,6 +57,8 @@
'command_buffer/service/gpu_switches.cc',
'command_buffer/service/id_manager.h',
'command_buffer/service/id_manager.cc',
+ 'command_buffer/service/image_manager.cc',
+ 'command_buffer/service/image_manager.h',
'command_buffer/service/mailbox_manager.cc',
'command_buffer/service/mailbox_manager.h',
'command_buffer/service/memory_program_cache.h',
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index 34e48639..ed72c01 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -113,6 +113,7 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config,
gpu::gles2::ContextGroup::Ref group(new gpu::gles2::ContextGroup(NULL,
NULL,
+ NULL,
true));
decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));