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 {
class DecoderClient;
namespace gles2 {
class CopyTextureCHROMIUMResourceManager;
class GLES2Util;
class ImageManager;
class Logger;
......@@ -68,6 +69,10 @@ class GPU_GLES2_EXPORT RasterDecoder : public DecoderContext,
void set_log_commands(bool log_commands) { log_commands_ = log_commands; }
bool log_commands() const { return log_commands_; }
virtual void SetCopyTextureResourceManagerForTest(
gles2::CopyTextureCHROMIUMResourceManager*
copy_texture_resource_manager) = 0;
protected:
RasterDecoder(CommandBufferServiceBase* command_buffer_service);
......
......@@ -141,6 +141,9 @@ class MockRasterDecoder : public RasterDecoder {
int width,
int height,
int depth));
MOCK_METHOD1(SetCopyTextureResourceManagerForTest,
void(gles2::CopyTextureCHROMIUMResourceManager*
copy_texture_resource_manager));
private:
base::WeakPtrFactory<MockRasterDecoder> weak_ptr_factory_;
......
......@@ -20,6 +20,7 @@
using ::testing::_;
using ::testing::Return;
using ::testing::SetArgPointee;
using namespace gpu::raster::cmds;
......@@ -400,8 +401,53 @@ TEST_P(RasterDecoderTest, ReleaseTexImage2DCHROMIUM) {
EXPECT_TRUE(texture->GetLevelImage(GL_TEXTURE_2D, 0) == nullptr);
}
// TODO(backer): Port CopyTexSubImage2DTwiceClearsUnclearedTexture) after
// CopyTexSubImage implemented.
TEST_P(RasterDecoderTest, CopyTexSubImage2DTwiceClearsUnclearedTexture) {
// 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) {
scoped_refptr<gl::GLImage> image(new gl::GLImageStub);
......
......@@ -18,6 +18,7 @@
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/common/raster_cmd_format.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/logger.h"
#include "gpu/command_buffer/service/mailbox_manager.h"
......@@ -57,7 +58,8 @@ RasterDecoderTestBase::RasterDecoderTestBase()
shared_memory_address_(nullptr),
shared_memory_base_(nullptr),
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_));
}
......@@ -78,6 +80,58 @@ void RasterDecoderTestBase::SetUp() {
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(
std::initializer_list<std::string> extensions) {
std::string all_extensions;
......@@ -146,6 +200,18 @@ void RasterDecoderTestBase::InitDecoderWithWorkarounds(
attribs.lose_context_when_out_of_memory = lose_context_when_out_of_memory;
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;
for (GLint tt = 0; tt < TestHelper::kNumTextureUnits; ++tt) {
EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0 + tt))
......@@ -164,6 +230,10 @@ void RasterDecoderTestBase::InitDecoderWithWorkarounds(
&outputter_, group_.get()));
decoder_->SetIgnoreCachedStateForTest(ignore_cached_state_for_test_);
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(),
attribs),
gpu::ContextResult::kSuccess);
......@@ -194,6 +264,14 @@ void RasterDecoderTestBase::ResetDecoder() {
EXPECT_EQ(GL_NO_ERROR, GetGLError());
decoder_->EndDecoding();
if (!decoder_->WasContextLost()) {
EXPECT_CALL(*copy_texture_manager_, Destroy())
.Times(1)
.RetiresOnSaturation();
copy_texture_manager_ = nullptr;
}
decoder_->Destroy(!decoder_->WasContextLost());
decoder_.reset();
group_->Destroy(mock_decoder_.get(), false);
......@@ -382,9 +460,11 @@ void RasterDecoderTestBase::SetupClearTextureExpectations(
#ifndef COMPILER_MSVC
const GLint RasterDecoderTestBase::kMaxTextureSize;
const GLint RasterDecoderTestBase::kNumTextureUnits;
const GLint RasterDecoderTestBase::kNumVertexAttribs;
const GLuint RasterDecoderTestBase::kServiceBufferId;
const GLuint RasterDecoderTestBase::kServiceTextureId;
const GLuint RasterDecoderTestBase::kServiceVertexArrayId;
const size_t RasterDecoderTestBase::kSharedBufferSize;
const uint32_t RasterDecoderTestBase::kSharedMemoryOffset;
......
......@@ -43,6 +43,7 @@ namespace gpu {
namespace gles2 {
class ImageManager;
class MemoryTracker;
class MockCopyTextureResourceManager;
} // namespace gles2
namespace raster {
......@@ -134,6 +135,10 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>,
memory_tracker_ = memory_tracker;
}
void AddExpectationsForVertexAttribManager();
void AddExpectationsForBindVertexArrayOES();
void AddExpectationsForRestoreAttribState(GLuint attrib);
void InitDecoderWithWorkarounds(
std::initializer_list<std::string> extensions);
......@@ -199,9 +204,11 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>,
protected:
static const GLint kMaxTextureSize = 2048;
static const GLint kNumTextureUnits = 8;
static const GLint kNumVertexAttribs = 16;
static const GLuint kServiceBufferId = 301;
static const GLuint kServiceTextureId = 304;
static const GLuint kServiceVertexArrayId = 310;
static const size_t kSharedBufferSize = 2048;
static const uint32_t kSharedMemoryOffset = 132;
......@@ -245,6 +252,7 @@ class RasterDecoderTestBase : public ::testing::TestWithParam<bool>,
ServiceDiscardableManager discardable_manager_;
scoped_refptr<gles2::ContextGroup> group_;
base::MessageLoop message_loop_;
gles2::MockCopyTextureResourceManager* copy_texture_manager_; // not owned
};
} // 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