Commit 10821a81 authored by Jonathan Backer's avatar Jonathan Backer Committed by Commit Bot

Implement CopySubTexture in RasterDecoderImpl

This is largely a copy-and-paste from GLES2DecoderImpl, with some minor
cleanup.

- added a vertex array manager to RasterDecoderImpl and copied
  associated boilerplate because it was required by
  CopyTextureCHROMIUMResourceManager

- copied GLES2DecoderImpl::CopySubTextureHelper as
  RasterDecoderImpl::CopySubTexture with very minor modification
  (e.g. raster is given a destination texture ID instead of the target
  that GLES2 takes)

- added a unittest to verify that source and destination textures are
  cleared appropriately

Bug: 789238
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I1eb50e43cc52ee9931a483ab89f9cdbdf47e2332
Reviewed-on: https://chromium-review.googlesource.com/993763
Commit-Queue: Jonathan Backer <backer@chromium.org>
Reviewed-by: default avatarZhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548258}
parent a8e2568e
...@@ -15,6 +15,7 @@ namespace gpu { ...@@ -15,6 +15,7 @@ namespace gpu {
class DecoderClient; class DecoderClient;
namespace gles2 { namespace gles2 {
class CopyTextureCHROMIUMResourceManager;
class GLES2Util; class GLES2Util;
class ImageManager; class ImageManager;
class Logger; class Logger;
...@@ -68,6 +69,10 @@ class GPU_GLES2_EXPORT RasterDecoder : public DecoderContext, ...@@ -68,6 +69,10 @@ class GPU_GLES2_EXPORT RasterDecoder : public DecoderContext,
void set_log_commands(bool log_commands) { log_commands_ = log_commands; } void set_log_commands(bool log_commands) { log_commands_ = log_commands; }
bool log_commands() const { return log_commands_; } bool log_commands() const { return log_commands_; }
virtual void SetCopyTextureResourceManagerForTest(
gles2::CopyTextureCHROMIUMResourceManager*
copy_texture_resource_manager) = 0;
protected: protected:
RasterDecoder(CommandBufferServiceBase* command_buffer_service); RasterDecoder(CommandBufferServiceBase* command_buffer_service);
......
...@@ -141,6 +141,9 @@ class MockRasterDecoder : public RasterDecoder { ...@@ -141,6 +141,9 @@ class MockRasterDecoder : public RasterDecoder {
int width, int width,
int height, int height,
int depth)); int depth));
MOCK_METHOD1(SetCopyTextureResourceManagerForTest,
void(gles2::CopyTextureCHROMIUMResourceManager*
copy_texture_resource_manager));
private: private:
base::WeakPtrFactory<MockRasterDecoder> weak_ptr_factory_; base::WeakPtrFactory<MockRasterDecoder> weak_ptr_factory_;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
using ::testing::_; using ::testing::_;
using ::testing::Return; using ::testing::Return;
using ::testing::SetArgPointee;
using namespace gpu::raster::cmds; using namespace gpu::raster::cmds;
...@@ -400,8 +401,53 @@ TEST_P(RasterDecoderTest, ReleaseTexImage2DCHROMIUM) { ...@@ -400,8 +401,53 @@ TEST_P(RasterDecoderTest, ReleaseTexImage2DCHROMIUM) {
EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == nullptr); EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == nullptr);
} }
// TODO(backer): Port CopyTexSubImage2DTwiceClearsUnclearedTexture) after TEST_P(RasterDecoderTest, CopyTexSubImage2DTwiceClearsUnclearedTexture) {
// CopyTexSubImage implemented. // Create uninitialized source texture.
GLuint source_texture_id = kNewClientId;
EXPECT_CALL(*gl_, GenTextures(1, _))
.WillOnce(SetArgPointee<1>(kNewServiceId))
.RetiresOnSaturation();
cmds::CreateTexture cmd;
cmd.Init(false /* use_buffer */, gfx::BufferUsage::GPU_READ,
viz::ResourceFormat::RGBA_8888, source_texture_id);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
// Set dimensions on source and dest textures.
DoTexStorage2D(source_texture_id, 1 /* levels */, 2, 2);
DoTexStorage2D(client_texture_id_, 1 /* levels */, 2, 2);
// This will initialize the top half of destination.
{
// Source is undefined, so first call to CopySubTexture will clear the
// source.
SetupClearTextureExpectations(kNewServiceId, kServiceTextureId,
GL_TEXTURE_2D, GL_TEXTURE_2D, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0, 0, 2, 2, 0);
SetScopedTextureBinderExpectations(GL_TEXTURE_2D);
CopySubTexture cmd;
cmd.Init(source_texture_id, client_texture_id_, 0, 0, 0, 0, 2, 1);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
// This will initialize bottom right corner of the destination.
// CopySubTexture will clear the bottom half of the destination because a
// single rectangle is insufficient to keep track of the initialized area.
{
SetupClearTextureExpectations(kServiceTextureId, kServiceTextureId,
GL_TEXTURE_2D, GL_TEXTURE_2D, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0, 1, 2, 1, 0);
SetScopedTextureBinderExpectations(GL_TEXTURE_2D);
CopySubTexture cmd;
cmd.Init(source_texture_id, client_texture_id_, 1, 1, 0, 0, 1, 1);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
}
gles2::TextureManager* manager = group().texture_manager();
gles2::TextureRef* texture_ref = manager->GetTexture(client_texture_id_);
ASSERT_TRUE(texture_ref != NULL);
gles2::Texture* texture = texture_ref->texture();
EXPECT_TRUE(texture->SafeToRenderFrom());
}
TEST_P(RasterDecoderTest, GLImageAttachedAfterClearLevel) { TEST_P(RasterDecoderTest, GLImageAttachedAfterClearLevel) {
scoped_refptr<gl::GLImage> image(new gl::GLImageStub); scoped_refptr<gl::GLImage> image(new gl::GLImageStub);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "gpu/command_buffer/common/gles2_cmd_utils.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/common/raster_cmd_format.h" #include "gpu/command_buffer/common/raster_cmd_format.h"
#include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/copy_texture_chromium_mock.h"
#include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/gpu_switches.h"
#include "gpu/command_buffer/service/logger.h" #include "gpu/command_buffer/service/logger.h"
#include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h"
...@@ -57,7 +58,8 @@ RasterDecoderTestBase::RasterDecoderTestBase() ...@@ -57,7 +58,8 @@ RasterDecoderTestBase::RasterDecoderTestBase()
shared_memory_address_(nullptr), shared_memory_address_(nullptr),
shared_memory_base_(nullptr), shared_memory_base_(nullptr),
ignore_cached_state_for_test_(GetParam()), ignore_cached_state_for_test_(GetParam()),
shader_translator_cache_(gpu_preferences_) { shader_translator_cache_(gpu_preferences_),
copy_texture_manager_(nullptr) {
memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_)); memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_));
} }
...@@ -78,6 +80,58 @@ void RasterDecoderTestBase::SetUp() { ...@@ -78,6 +80,58 @@ void RasterDecoderTestBase::SetUp() {
InitDecoderWithWorkarounds({"GL_ARB_sync"}); InitDecoderWithWorkarounds({"GL_ARB_sync"});
} }
void RasterDecoderTestBase::AddExpectationsForVertexAttribManager() {
for (GLint ii = 0; ii < kNumVertexAttribs; ++ii) {
EXPECT_CALL(*gl_, VertexAttrib4f(ii, 0.0f, 0.0f, 0.0f, 1.0f))
.Times(1)
.RetiresOnSaturation();
}
}
void RasterDecoderTestBase::AddExpectationsForBindVertexArrayOES() {
if (group_->feature_info()->feature_flags().native_vertex_array_object) {
EXPECT_CALL(*gl_, BindVertexArrayOES(_)).Times(1).RetiresOnSaturation();
} else {
for (uint32_t vv = 0; vv < group_->max_vertex_attribs(); ++vv) {
AddExpectationsForRestoreAttribState(vv);
}
EXPECT_CALL(*gl_, BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _))
.Times(1)
.RetiresOnSaturation();
}
}
void RasterDecoderTestBase::AddExpectationsForRestoreAttribState(
GLuint attrib) {
EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*gl_, VertexAttribPointer(attrib, _, _, _, _, _))
.Times(1)
.RetiresOnSaturation();
EXPECT_CALL(*gl_, VertexAttribDivisorANGLE(attrib, _))
.Times(testing::AtMost(1))
.RetiresOnSaturation();
EXPECT_CALL(*gl_, BindBuffer(GL_ARRAY_BUFFER, _))
.Times(1)
.RetiresOnSaturation();
if (attrib != 0 || group_->feature_info()->gl_version_info().is_es) {
// TODO(bajones): Not sure if I can tell which of these will be called
EXPECT_CALL(*gl_, EnableVertexAttribArray(attrib))
.Times(testing::AtMost(1))
.RetiresOnSaturation();
EXPECT_CALL(*gl_, DisableVertexAttribArray(attrib))
.Times(testing::AtMost(1))
.RetiresOnSaturation();
}
}
void RasterDecoderTestBase::InitDecoderWithWorkarounds( void RasterDecoderTestBase::InitDecoderWithWorkarounds(
std::initializer_list<std::string> extensions) { std::initializer_list<std::string> extensions) {
std::string all_extensions; std::string all_extensions;
...@@ -146,6 +200,18 @@ void RasterDecoderTestBase::InitDecoderWithWorkarounds( ...@@ -146,6 +200,18 @@ void RasterDecoderTestBase::InitDecoderWithWorkarounds(
attribs.lose_context_when_out_of_memory = lose_context_when_out_of_memory; attribs.lose_context_when_out_of_memory = lose_context_when_out_of_memory;
attribs.context_type = context_type; attribs.context_type = context_type;
if (group_->feature_info()->feature_flags().native_vertex_array_object) {
EXPECT_CALL(*gl_, GenVertexArraysOES(1, _))
.WillOnce(SetArgPointee<1>(kServiceVertexArrayId))
.RetiresOnSaturation();
EXPECT_CALL(*gl_, BindVertexArrayOES(_)).Times(1).RetiresOnSaturation();
}
if (group_->feature_info()->workarounds().init_vertex_attributes)
AddExpectationsForVertexAttribManager();
AddExpectationsForBindVertexArrayOES();
bool use_default_textures = bind_generates_resource; bool use_default_textures = bind_generates_resource;
for (GLint tt = 0; tt < TestHelper::kNumTextureUnits; ++tt) { for (GLint tt = 0; tt < TestHelper::kNumTextureUnits; ++tt) {
EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0 + tt)) EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0 + tt))
...@@ -164,6 +230,10 @@ void RasterDecoderTestBase::InitDecoderWithWorkarounds( ...@@ -164,6 +230,10 @@ void RasterDecoderTestBase::InitDecoderWithWorkarounds(
&outputter_, group_.get())); &outputter_, group_.get()));
decoder_->SetIgnoreCachedStateForTest(ignore_cached_state_for_test_); decoder_->SetIgnoreCachedStateForTest(ignore_cached_state_for_test_);
decoder_->GetLogger()->set_log_synthesized_gl_errors(false); decoder_->GetLogger()->set_log_synthesized_gl_errors(false);
copy_texture_manager_ = new MockCopyTextureResourceManager();
decoder_->SetCopyTextureResourceManagerForTest(copy_texture_manager_);
ASSERT_EQ(decoder_->Initialize(surface_, context_, true, DisallowedFeatures(), ASSERT_EQ(decoder_->Initialize(surface_, context_, true, DisallowedFeatures(),
attribs), attribs),
gpu::ContextResult::kSuccess); gpu::ContextResult::kSuccess);
...@@ -194,6 +264,14 @@ void RasterDecoderTestBase::ResetDecoder() { ...@@ -194,6 +264,14 @@ void RasterDecoderTestBase::ResetDecoder() {
EXPECT_EQ(GL_NO_ERROR, GetGLError()); EXPECT_EQ(GL_NO_ERROR, GetGLError());
decoder_->EndDecoding(); decoder_->EndDecoding();
if (!decoder_->WasContextLost()) {
EXPECT_CALL(*copy_texture_manager_, Destroy())
.Times(1)
.RetiresOnSaturation();
copy_texture_manager_ = nullptr;
}
decoder_->Destroy(!decoder_->WasContextLost()); decoder_->Destroy(!decoder_->WasContextLost());
decoder_.reset(); decoder_.reset();
group_->Destroy(mock_decoder_.get(), false); group_->Destroy(mock_decoder_.get(), false);
...@@ -382,9 +460,11 @@ void RasterDecoderTestBase::SetupClearTextureExpectations( ...@@ -382,9 +460,11 @@ void RasterDecoderTestBase::SetupClearTextureExpectations(
#ifndef COMPILER_MSVC #ifndef COMPILER_MSVC
const GLint RasterDecoderTestBase::kMaxTextureSize; const GLint RasterDecoderTestBase::kMaxTextureSize;
const GLint RasterDecoderTestBase::kNumTextureUnits; const GLint RasterDecoderTestBase::kNumTextureUnits;
const GLint RasterDecoderTestBase::kNumVertexAttribs;
const GLuint RasterDecoderTestBase::kServiceBufferId; const GLuint RasterDecoderTestBase::kServiceBufferId;
const GLuint RasterDecoderTestBase::kServiceTextureId; const GLuint RasterDecoderTestBase::kServiceTextureId;
const GLuint RasterDecoderTestBase::kServiceVertexArrayId;
const size_t RasterDecoderTestBase::kSharedBufferSize; const size_t RasterDecoderTestBase::kSharedBufferSize;
const uint32_t RasterDecoderTestBase::kSharedMemoryOffset; const uint32_t RasterDecoderTestBase::kSharedMemoryOffset;
......
...@@ -43,6 +43,7 @@ namespace gpu { ...@@ -43,6 +43,7 @@ namespace gpu {
namespace gles2 { namespace gles2 {
class ImageManager; class ImageManager;
class MemoryTracker; class MemoryTracker;
class MockCopyTextureResourceManager;
} // namespace gles2 } // namespace gles2
namespace raster { namespace raster {
...@@ -134,6 +135,10 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>, ...@@ -134,6 +135,10 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>,
memory_tracker_ = memory_tracker; memory_tracker_ = memory_tracker;
} }
void AddExpectationsForVertexAttribManager();
void AddExpectationsForBindVertexArrayOES();
void AddExpectationsForRestoreAttribState(GLuint attrib);
void InitDecoderWithWorkarounds( void InitDecoderWithWorkarounds(
std::initializer_list<std::string> extensions); std::initializer_list<std::string> extensions);
...@@ -199,9 +204,11 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>, ...@@ -199,9 +204,11 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>,
protected: protected:
static const GLint kMaxTextureSize = 2048; static const GLint kMaxTextureSize = 2048;
static const GLint kNumTextureUnits = 8; static const GLint kNumTextureUnits = 8;
static const GLint kNumVertexAttribs = 16;
static const GLuint kServiceBufferId = 301; static const GLuint kServiceBufferId = 301;
static const GLuint kServiceTextureId = 304; static const GLuint kServiceTextureId = 304;
static const GLuint kServiceVertexArrayId = 310;
static const size_t kSharedBufferSize = 2048; static const size_t kSharedBufferSize = 2048;
static const uint32_t kSharedMemoryOffset = 132; static const uint32_t kSharedMemoryOffset = 132;
...@@ -245,6 +252,7 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>, ...@@ -245,6 +252,7 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>,
ServiceDiscardableManager discardable_manager_; ServiceDiscardableManager discardable_manager_;
scoped_refptr<gles2::ContextGroup> group_; scoped_refptr<gles2::ContextGroup> group_;
base::MessageLoop message_loop_; base::MessageLoop message_loop_;
gles2::MockCopyTextureResourceManager* copy_texture_manager_; // not owned
}; };
} // namespace raster } // namespace raster
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment