diff options
Diffstat (limited to 'gpu/command_buffer/service')
5 files changed, 228 insertions, 10 deletions
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index f954189..f14058d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -937,7 +937,14 @@ class GLES2DecoderImpl : public GLES2Decoder, GLsizei height); void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); + void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, + const GLbyte* key); + void ProduceTextureRef(std::string func_name, TextureRef* texture_ref, + GLenum target, const GLbyte* data); + void DoConsumeTextureCHROMIUM(GLenum target, const GLbyte* key); + void DoCreateAndConsumeTextureCHROMIUM(GLenum target, const GLbyte* key, + GLuint client_id); void DoBindTexImage2DCHROMIUM( GLenum target, @@ -10197,25 +10204,44 @@ void GLES2DecoderImpl::DoProduceTextureCHROMIUM(GLenum target, "context", logger_.GetLogPrefix(), "mailbox[0]", static_cast<unsigned char>(data[0])); + TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( + &state_, target); + ProduceTextureRef("glProduceTextureCHROMIUM", texture_ref, target, data); +} + +void GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM(GLuint client_id, + GLenum target, const GLbyte* data) { + TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoProduceTextureDirectCHROMIUM", + "context", logger_.GetLogPrefix(), + "mailbox[0]", static_cast<unsigned char>(data[0])); + + ProduceTextureRef("glProduceTextureDirectCHROMIUM", GetTexture(client_id), + target, data); +} + +void GLES2DecoderImpl::ProduceTextureRef(std::string func_name, + TextureRef* texture_ref, GLenum target, const GLbyte* data) { const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data); - DLOG_IF(ERROR, !mailbox.Verify()) << "ProduceTextureCHROMIUM was passed a " + DLOG_IF(ERROR, !mailbox.Verify()) << func_name << " was passed a " "mailbox that was not generated by " "GenMailboxCHROMIUM."; - TextureRef* texture_ref = texture_manager()->GetTextureInfoForTarget( - &state_, target); if (!texture_ref) { LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glProduceTextureCHROMIUM", "unknown texture for target"); + GL_INVALID_OPERATION, func_name.c_str(), "unknown texture for target"); return; } Texture* produced = texture_manager()->Produce(texture_ref); if (!produced) { LOCAL_SET_GL_ERROR( - GL_INVALID_OPERATION, - "glProduceTextureCHROMIUM", "invalid texture"); + GL_INVALID_OPERATION, func_name.c_str(), "invalid texture"); + return; + } + + if (produced->target() != target) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, func_name.c_str(), "invalid target"); return; } @@ -10286,6 +10312,70 @@ void GLES2DecoderImpl::DoConsumeTextureCHROMIUM(GLenum target, } } +error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate( + uint32_t immediate_data_size, + const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLbyte* mailbox = + GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size); + if (!validators_->texture_bind_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glCreateAndConsumeTextureCHROMIUM", target, "target"); + return error::kNoError; + } + if (mailbox == NULL) { + return error::kOutOfBounds; + } + uint32_t client_id = c.client_id; + DoCreateAndConsumeTextureCHROMIUM(target, mailbox, client_id); + return error::kNoError; +} + +void GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM(GLenum target, + const GLbyte* data, GLuint client_id) { + TRACE_EVENT2("gpu", "GLES2DecoderImpl::DoCreateAndConsumeTextureCHROMIUM", + "context", logger_.GetLogPrefix(), + "mailbox[0]", static_cast<unsigned char>(data[0])); + const Mailbox& mailbox = *reinterpret_cast<const Mailbox*>(data); + DLOG_IF(ERROR, !mailbox.Verify()) << "CreateAndConsumeTextureCHROMIUM was " + "passed a mailbox that was not " + "generated by GenMailboxCHROMIUM."; + + TextureRef* texture_ref = GetTexture(client_id); + if (texture_ref) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glCreateAndConsumeTextureCHROMIUM", "client id already in use"); + return; + } + Texture* texture = group_->mailbox_manager()->ConsumeTexture(target, mailbox); + if (!texture) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glCreateAndConsumeTextureCHROMIUM", "invalid mailbox name"); + return; + } + if (texture->target() != target) { + LOCAL_SET_GL_ERROR( + GL_INVALID_OPERATION, + "glCreateAndConsumeTextureCHROMIUM", "invalid target"); + return; + } + + IdAllocatorInterface* id_allocator = + group_->GetIdAllocator(id_namespaces::kTextures); + id_allocator->MarkAsUsed(client_id); + + texture_ref = texture_manager()->Consume(client_id, texture); +} + void GLES2DecoderImpl::DoInsertEventMarkerEXT( GLsizei length, const GLchar* marker) { if (!marker) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index edf5a57..8011ab1 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -2694,6 +2694,32 @@ error::Error GLES2DecoderImpl::HandleProduceTextureCHROMIUMImmediate( return error::kNoError; } +error::Error GLES2DecoderImpl::HandleProduceTextureDirectCHROMIUMImmediate( + uint32_t immediate_data_size, + const gles2::cmds::ProduceTextureDirectCHROMIUMImmediate& c) { + GLuint texture = c.texture; + GLenum target = static_cast<GLenum>(c.target); + uint32_t data_size; + if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) { + return error::kOutOfBounds; + } + if (data_size > immediate_data_size) { + return error::kOutOfBounds; + } + const GLbyte* mailbox = + GetImmediateDataAs<const GLbyte*>(c, data_size, immediate_data_size); + if (!validators_->texture_bind_target.IsValid(target)) { + LOCAL_SET_GL_ERROR_INVALID_ENUM( + "glProduceTextureDirectCHROMIUM", target, "target"); + return error::kNoError; + } + if (mailbox == NULL) { + return error::kOutOfBounds; + } + DoProduceTextureDirectCHROMIUM(texture, target, mailbox); + return error::kNoError; +} + error::Error GLES2DecoderImpl::HandleConsumeTextureCHROMIUMImmediate( uint32_t immediate_data_size, const gles2::cmds::ConsumeTextureCHROMIUMImmediate& c) { diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h index 80dc8f7..cbff801 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h @@ -746,7 +746,9 @@ TEST_P(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) { // TODO(gman): GenMailboxCHROMIUM // TODO(gman): ProduceTextureCHROMIUMImmediate +// TODO(gman): ProduceTextureDirectCHROMIUMImmediate // TODO(gman): ConsumeTextureCHROMIUMImmediate +// TODO(gman): CreateAndConsumeTextureCHROMIUMImmediate // TODO(gman): BindUniformLocationCHROMIUM // TODO(gman): BindUniformLocationCHROMIUMBucket @@ -761,7 +763,4 @@ TEST_P(GLES2DecoderTest2, PopGroupMarkerEXTValidArgs) { // TODO(gman): WaitAsyncTexImage2DCHROMIUM -// TODO(gman): WaitAllAsyncTexImage2DCHROMIUM - -// TODO(gman): DiscardFramebufferEXTImmediate #endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_ 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 1c98b68..ce869a4 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 @@ -12,6 +12,9 @@ #ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ #define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_3_AUTOGEN_H_ +// TODO(gman): WaitAllAsyncTexImage2DCHROMIUM + +// TODO(gman): DiscardFramebufferEXTImmediate // TODO(gman): LoseContextCHROMIUM // TODO(gman): InsertSyncPointCHROMIUM diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc index 5e6a0d4..6761813 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc @@ -1931,6 +1931,106 @@ TEST_P(GLES2DecoderTest, ProduceAndConsumeTextureCHROMIUM) { EXPECT_EQ(kServiceTextureId, texture->service_id()); } +TEST_P(GLES2DecoderTest, ProduceAndConsumeDirectTextureCHROMIUM) { + Mailbox mailbox = Mailbox::Generate(); + + 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); + DoTexImage2D( + GL_TEXTURE_2D, 1, GL_RGBA, 2, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, 0); + TextureRef* texture_ref = + group().texture_manager()->GetTexture(client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + EXPECT_EQ(kServiceTextureId, texture->service_id()); + + ProduceTextureDirectCHROMIUMImmediate& produce_cmd = + *GetImmediateAs<ProduceTextureDirectCHROMIUMImmediate>(); + produce_cmd.Init(client_texture_id_, GL_TEXTURE_2D, mailbox.name); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(produce_cmd, sizeof(mailbox.name))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Texture didn't change. + GLsizei width; + GLsizei height; + GLenum type; + GLenum internal_format; + + EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_EQ(3, width); + EXPECT_EQ(1, height); + EXPECT_TRUE(texture->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(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); + EXPECT_EQ(2, width); + EXPECT_EQ(4, height); + EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format)); + EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format); + EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); + + // Service ID has not changed. + EXPECT_EQ(kServiceTextureId, texture->service_id()); + + // Consume the texture into a new client ID. + GLuint new_texture_id = kNewClientId; + CreateAndConsumeTextureCHROMIUMImmediate& consume_cmd = + *GetImmediateAs<CreateAndConsumeTextureCHROMIUMImmediate>(); + consume_cmd.Init(GL_TEXTURE_2D, new_texture_id, mailbox.name); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(consume_cmd, sizeof(mailbox.name))); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + + // Make sure the new client ID is associated with the produced service ID. + texture_ref = group().texture_manager()->GetTexture(new_texture_id); + ASSERT_TRUE(texture_ref != NULL); + texture = texture_ref->texture(); + EXPECT_EQ(kServiceTextureId, texture->service_id()); + + DoBindTexture(GL_TEXTURE_2D, kNewClientId, kServiceTextureId); + + // Texture is redefined. + EXPECT_TRUE(texture->GetLevelSize(GL_TEXTURE_2D, 0, &width, &height)); + EXPECT_EQ(3, width); + EXPECT_EQ(1, height); + EXPECT_TRUE(texture->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(texture->GetLevelSize(GL_TEXTURE_2D, 1, &width, &height)); + EXPECT_EQ(2, width); + EXPECT_EQ(4, height); + EXPECT_TRUE(texture->GetLevelType(GL_TEXTURE_2D, 1, &type, &internal_format)); + EXPECT_EQ(static_cast<GLenum>(GL_RGBA), internal_format); + EXPECT_EQ(static_cast<GLenum>(GL_UNSIGNED_BYTE), type); +} + +TEST_P(GLES2DecoderTest, ProduceTextureCHROMIUMInvalidTarget) { + Mailbox mailbox = Mailbox::Generate(); + + DoBindTexture(GL_TEXTURE_CUBE_MAP, client_texture_id_, kServiceTextureId); + DoTexImage2D( + GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 3, 1, 0, GL_RGBA, + GL_UNSIGNED_BYTE, 0, 0); + TextureRef* texture_ref = + group().texture_manager()->GetTexture(client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + EXPECT_EQ(kServiceTextureId, texture->service_id()); + + ProduceTextureDirectCHROMIUMImmediate& produce_cmd = + *GetImmediateAs<ProduceTextureDirectCHROMIUMImmediate>(); + produce_cmd.Init(client_texture_id_, GL_TEXTURE_2D, mailbox.name); + EXPECT_EQ(error::kNoError, + ExecuteImmediateCmd(produce_cmd, sizeof(mailbox.name))); + + // ProduceTexture should fail it the texture and produce targets don't match. + EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); +} + TEST_P(GLES2DecoderManualInitTest, DepthTextureBadArgs) { InitState init; init.extensions = "GL_ANGLE_depth_texture"; |