Commit a4568da1 authored by Jonathan Backer's avatar Jonathan Backer Committed by Commit Bot

Add RasterDecoder autogen unittests

This CL adds a few things:
- autogenerated unittests
- associated mocks
- associated test drivers
- enough implementation in raster_decoder.cc to make the tests pass

No changes to GLES2 autogen.

Bug: 789238
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: Iac2ee4922a21f3bd11ff58693e2e5fb1fe26bd45
Reviewed-on: https://chromium-review.googlesource.com/891988
Commit-Queue: Jonathan Backer <backer@chromium.org>
Reviewed-by: default avatarVictor Miura <vmiura@chromium.org>
Cr-Commit-Position: refs/heads/master@{#533291}
parent 08757f1e
......@@ -147,6 +147,8 @@ static_library("test_support") {
"command_buffer/service/error_state_mock.h",
"command_buffer/service/gles2_cmd_decoder_mock.cc",
"command_buffer/service/gles2_cmd_decoder_mock.h",
"command_buffer/service/raster_decoder_mock.cc",
"command_buffer/service/raster_decoder_mock.h",
]
public_deps = [
......@@ -340,6 +342,9 @@ test("gpu_unittests") {
"command_buffer/service/program_cache_unittest.cc",
"command_buffer/service/program_manager_unittest.cc",
"command_buffer/service/query_manager_unittest.cc",
"command_buffer/service/raster_decoder_unittest_1.cc",
"command_buffer/service/raster_decoder_unittest_base.cc",
"command_buffer/service/raster_decoder_unittest_base.h",
"command_buffer/service/renderbuffer_manager_unittest.cc",
"command_buffer/service/scheduler_unittest.cc",
"command_buffer/service/service_discardable_manager_unittest.cc",
......
......@@ -6186,15 +6186,15 @@ namespace gles2 {
for test_num in range(0, num_tests, FUNCTIONS_PER_FILE):
count += 1
filename = filename_pattern % count
comment = "// It is included by gles2_cmd_decoder_unittest_%d.cc\n" \
% count
comment = "// It is included by %s_cmd_decoder_unittest_%d.cc\n" \
% (_lower_prefix, count)
with CHeaderWriter(filename, self.year, comment) as f:
end = test_num + FUNCTIONS_PER_FILE
if end > num_tests:
end = num_tests
for idx in range(test_num, end):
func = self.functions[idx]
test_name = 'GLES2DecoderTest%d' % count
test_name = '%sDecoderTest%d' % (_prefix, count)
if func.IsES3():
test_name = 'GLES3DecoderTest%d' % count
......@@ -6210,103 +6210,109 @@ namespace gles2 {
})
self.generated_cpp_filenames.append(filename)
comment = "// It is included by gles2_cmd_decoder_unittest_base.cc\n"
comment = ("// It is included by %s_cmd_decoder_unittest_base.cc\n"
% _lower_prefix)
filename = filename_pattern % 0
with CHeaderWriter(filename, self.year, comment) as f:
f.write(
if self.capability_flags:
f.write(
"""void GLES2DecoderTestBase::SetupInitCapabilitiesExpectations(
bool es3_capable) {""")
for capability in self.capability_flags:
capability_no_init = 'no_init' in capability and \
capability['no_init'] == True
if capability_no_init:
for capability in self.capability_flags:
capability_no_init = 'no_init' in capability and \
capability['no_init'] == True
if capability_no_init:
continue
capability_es3 = 'es3' in capability and capability['es3'] == True
if capability_es3:
continue
capability_es3 = 'es3' in capability and capability['es3'] == True
if capability_es3:
continue
if 'extension_flag' in capability:
f.write(" if (group_->feature_info()->feature_flags().%s) {\n" %
capability['extension_flag'])
f.write(" ")
f.write(" ExpectEnableDisable(GL_%s, %s);\n" %
(capability['name'].upper(),
('false', 'true')['default' in capability]))
if 'extension_flag' in capability:
f.write(" }")
f.write(" if (es3_capable) {")
for capability in self.capability_flags:
capability_es3 = 'es3' in capability and capability['es3'] == True
if capability_es3:
f.write(" ExpectEnableDisable(GL_%s, %s);\n" %
(capability['name'].upper(),
('false', 'true')['default' in capability]))
f.write(""" }
if 'extension_flag' in capability:
f.write(" if (group_->feature_info()->feature_flags().%s) {\n" %
capability['extension_flag'])
f.write(" ")
f.write(" ExpectEnableDisable(GL_%s, %s);\n" %
(capability['name'].upper(),
('false', 'true')['default' in capability]))
if 'extension_flag' in capability:
f.write(" }")
f.write(" if (es3_capable) {")
for capability in self.capability_flags:
capability_es3 = 'es3' in capability and capability['es3'] == True
if capability_es3:
f.write(" ExpectEnableDisable(GL_%s, %s);\n" %
(capability['name'].upper(),
('false', 'true')['default' in capability]))
f.write(""" }
}
""")
if _prefix != 'Raster':
f.write("""
void GLES2DecoderTestBase::SetupInitStateExpectations(bool es3_capable) {
auto* feature_info_ = group_->feature_info();
""")
# We need to sort the keys so the expectations match
for state_name in sorted(self.state_info.keys()):
state = self.state_info[state_name]
if state['type'] == 'FrontBack':
num_states = len(state['states'])
for ndx, group in enumerate(Grouper(num_states / 2, state['states'])):
# We need to sort the keys so the expectations match
for state_name in sorted(self.state_info.keys()):
state = self.state_info[state_name]
if state['type'] == 'FrontBack':
num_states = len(state['states'])
for ndx, group in enumerate(Grouper(num_states / 2,
state['states'])):
args = []
for item in group:
if 'expected' in item:
args.append(item['expected'])
else:
args.append(item['default'])
f.write(
" EXPECT_CALL(*gl_, %s(%s, %s))\n" %
(state['func'], ('GL_FRONT', 'GL_BACK')[ndx],
", ".join(args)))
f.write(" .Times(1)\n")
f.write(" .RetiresOnSaturation();\n")
elif state['type'] == 'NamedParameter':
for item in state['states']:
expect_value = item['default']
if isinstance(expect_value, list):
# TODO: Currently we do not check array values.
expect_value = "_"
operation = []
operation.append(
" EXPECT_CALL(*gl_, %s(%s, %s))\n" %
(state['func'],
(item['enum_set']
if 'enum_set' in item else item['enum']),
expect_value))
operation.append(" .Times(1)\n")
operation.append(" .RetiresOnSaturation();\n")
guarded_operation = GuardState(item, ''.join(operation))
f.write(guarded_operation)
elif 'no_init' not in state:
if 'extension_flag' in state:
f.write(" if (group_->feature_info()->feature_flags().%s) {\n" %
state['extension_flag'])
f.write(" ")
args = []
for item in group:
for item in state['states']:
if 'expected' in item:
args.append(item['expected'])
else:
args.append(item['default'])
f.write(
" EXPECT_CALL(*gl_, %s(%s, %s))\n" %
(state['func'], ('GL_FRONT', 'GL_BACK')[ndx], ", ".join(args)))
f.write(" .Times(1)\n")
f.write(" .RetiresOnSaturation();\n")
elif state['type'] == 'NamedParameter':
for item in state['states']:
expect_value = item['default']
if isinstance(expect_value, list):
# TODO: Currently we do not check array values.
expect_value = "_"
operation = []
operation.append(
" EXPECT_CALL(*gl_, %s(%s, %s))\n" %
(state['func'],
(item['enum_set']
if 'enum_set' in item else item['enum']),
expect_value))
operation.append(" .Times(1)\n")
operation.append(" .RetiresOnSaturation();\n")
guarded_operation = GuardState(item, ''.join(operation))
f.write(guarded_operation)
elif 'no_init' not in state:
if 'extension_flag' in state:
f.write(" if (group_->feature_info()->feature_flags().%s) {\n" %
state['extension_flag'])
f.write(" ")
args = []
for item in state['states']:
if 'expected' in item:
args.append(item['expected'])
# TODO: Currently we do not check array values.
args = ["_" if isinstance(arg, list) else arg for arg in args]
if 'custom_function' in state:
f.write(" SetupInitStateManualExpectationsFor%s(%s);\n" %
(state['func'], ", ".join(args)))
else:
args.append(item['default'])
# TODO: Currently we do not check array values.
args = ["_" if isinstance(arg, list) else arg for arg in args]
if 'custom_function' in state:
f.write(" SetupInitStateManualExpectationsFor%s(%s);\n" %
(state['func'], ", ".join(args)))
else:
f.write(" EXPECT_CALL(*gl_, %s(%s))\n" %
(state['func'], ", ".join(args)))
f.write(" .Times(1)\n")
f.write(" .RetiresOnSaturation();\n")
if 'extension_flag' in state:
f.write(" }\n")
f.write(" SetupInitStateManualExpectations(es3_capable);\n")
f.write("}\n")
f.write(" EXPECT_CALL(*gl_, %s(%s))\n" %
(state['func'], ", ".join(args)))
f.write(" .Times(1)\n")
f.write(" .RetiresOnSaturation();\n")
if 'extension_flag' in state:
f.write(" }\n")
f.write(" SetupInitStateManualExpectations(es3_capable);\n")
f.write("}\n")
self.generated_cpp_filenames.append(filename)
def WriteServiceUnitTestsForExtensions(self, filename):
......
......@@ -1010,6 +1010,7 @@ _FUNCTION_INFO = {
'internal': True,
'impl_func': True,
'client_test': False,
'unit_test': False,
'extension': True,
},
'DeleteTransferCacheEntryINTERNAL': {
......@@ -1018,6 +1019,7 @@ _FUNCTION_INFO = {
'internal': True,
'impl_func': True,
'client_test': False,
'unit_test': False,
'extension': True,
},
'UnlockTransferCacheEntryINTERNAL': {
......@@ -1026,6 +1028,7 @@ _FUNCTION_INFO = {
'internal': True,
'impl_func': True,
'client_test': False,
'unit_test': False,
'extension': True,
},
'TexStorage2DImageCHROMIUM': {
......@@ -1091,9 +1094,9 @@ def main(argv):
# gen.WriteCmdHelperHeader(
# "gpu/command_buffer/client/raster_cmd_helper_autogen.h")
gen.WriteServiceImplementation(
"gpu/command_buffer/service/raster_cmd_decoder_autogen.h")
# gen.WriteServiceUnitTests(
# "gpu/command_buffer/service/raster_cmd_decoder_unittest_%d_autogen.h")
"gpu/command_buffer/service/raster_decoder_autogen.h")
gen.WriteServiceUnitTests(
"gpu/command_buffer/service/raster_decoder_unittest_%d_autogen.h")
# gen.WriteServiceUnitTestsForExtensions(
# "gpu/command_buffer/service/"
# "raster_cmd_decoder_unittest_extensions_autogen.h")
......
......@@ -101,6 +101,13 @@ source_set("gles2_sources") {
"gles2_cmd_format_autogen.h",
"gles2_cmd_ids.h",
"gles2_cmd_ids_autogen.h",
# TODO(backer): Separate into distinct raster target.
"raster_cmd_format.cc",
"raster_cmd_format.h",
"raster_cmd_format_autogen.h",
"raster_cmd_ids.h",
"raster_cmd_ids_autogen.h",
]
configs += [ "//gpu:gpu_gles2_implementation" ]
......
// Copyright 2018 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.
// This file contains the binary format definition of the command buffer and
// command buffer commands.
// We explicitly do NOT include raster_cmd_format.h here because client side
// and service side have different requirements.
#include "gpu/command_buffer/common/cmd_buffer_common.h"
namespace gpu {
namespace raster {
#include <stddef.h>
#include "gpu/command_buffer/common/raster_cmd_ids_autogen.h"
const char* GetCommandName(CommandId id) {
static const char* const names[] = {
#define RASTER_CMD_OP(name) "k" #name,
RASTER_COMMAND_LIST(RASTER_CMD_OP)
#undef RASTER_CMD_OP
};
size_t index = static_cast<size_t>(id) - kFirstRasterCommand;
return (index < arraysize(names)) ? names[index] : "*unknown-command*";
}
} // namespace raster
} // namespace gpu
......@@ -15,6 +15,8 @@ namespace gpu {
class DecoderClient;
namespace gles2 {
class GLES2Util;
class Logger;
class Outputter;
} // namespace gles2
......@@ -32,20 +34,32 @@ class GPU_GLES2_EXPORT RasterDecoder : public DecoderContext,
~RasterDecoder() override;
bool debug() const { return debug_; }
// DecoderContext implementation.
bool initialized() const override;
TextureBase* GetTextureBase(uint32_t client_id) override;
void BeginDecoding() override;
void EndDecoding() override;
base::StringPiece GetLogPrefix() override;
virtual gles2::GLES2Util* GetGLES2Util() = 0;
virtual gles2::Logger* GetLogger() = 0;
virtual void SetIgnoreCachedStateForTest(bool ignore) = 0;
void set_initialized() { initialized_ = true; }
// Set to true to call glGetError after every command.
void set_debug(bool debug) { debug_ = debug; }
bool log_commands() const { return log_commands_; }
bool debug() const { return debug_; }
// Set to true to LOG every command.
void set_log_commands(bool log_commands) { log_commands_ = log_commands; }
bool log_commands() const { return log_commands_; }
protected:
RasterDecoder(CommandBufferServiceBase* command_buffer_service);
private:
bool initialized_;
bool debug_;
bool log_commands_;
......
This diff is collapsed.
// Copyright 2018 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/raster_decoder_mock.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
namespace gpu {
namespace raster {
MockRasterDecoder::MockRasterDecoder(
CommandBufferServiceBase* command_buffer_service)
: RasterDecoder(command_buffer_service), weak_ptr_factory_(this) {
ON_CALL(*this, MakeCurrent()).WillByDefault(testing::Return(true));
}
MockRasterDecoder::~MockRasterDecoder() = default;
base::WeakPtr<DecoderContext> MockRasterDecoder::AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
} // namespace raster
} // namespace gpu
// Copyright 2018 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.
// This file contains the mock RasterDecoder class.
#ifndef GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_MOCK_H_
#define GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_MOCK_H_
#include <stdint.h>
#include <vector>
#include "base/callback.h"
#include "base/macros.h"
#include "gpu/command_buffer/common/context_creation_attribs.h"
#include "gpu/command_buffer/common/mailbox.h"
#include "gpu/command_buffer/service/raster_decoder.h"
#include "gpu/command_buffer/service/shader_translator.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "ui/gfx/geometry/size.h"
namespace gl {
class GLContext;
class GLSurface;
} // namespace gl
namespace gpu {
namespace gles2 {
class ContextGroup;
class ErrorState;
class GpuFenceManager;
class QueryManager;
class GLES2Util;
struct ContextState;
class FeatureInfo;
class Logger;
} // namespace gles2
namespace raster {
class MockRasterDecoder : public RasterDecoder {
public:
MockRasterDecoder(CommandBufferServiceBase* command_buffer_service);
~MockRasterDecoder() override;
base::WeakPtr<DecoderContext> AsWeakPtr() override;
MOCK_METHOD5(
Initialize,
gpu::ContextResult(const scoped_refptr<gl::GLSurface>& surface,
const scoped_refptr<gl::GLContext>& context,
bool offscreen,
const gles2::DisallowedFeatures& disallowed_features,
const ContextCreationAttribs& attrib_helper));
MOCK_METHOD1(Destroy, void(bool have_context));
MOCK_METHOD0(MakeCurrent, bool());
MOCK_METHOD1(GetServiceIdForTesting, uint32_t(uint32_t client_id));
MOCK_METHOD0(GetGLES2Util, gles2::GLES2Util*());
MOCK_METHOD0(GetGLSurface, gl::GLSurface*());
MOCK_METHOD0(GetGLContext, gl::GLContext*());
MOCK_METHOD0(GetContextGroup, gles2::ContextGroup*());
MOCK_CONST_METHOD0(GetFeatureInfo, const gles2::FeatureInfo*());
MOCK_METHOD0(GetContextState, const gles2::ContextState*());
MOCK_METHOD0(GetCapabilities, Capabilities());
MOCK_CONST_METHOD0(HasPendingQueries, bool());
MOCK_METHOD1(ProcessPendingQueries, void(bool));
MOCK_CONST_METHOD0(HasMoreIdleWork, bool());
MOCK_METHOD0(PerformIdleWork, void());
MOCK_CONST_METHOD0(HasPollingWork, bool());
MOCK_METHOD0(PerformPollingWork, void());
MOCK_METHOD1(RestoreState, void(const gles2::ContextState* prev_state));
MOCK_CONST_METHOD0(RestoreActiveTexture, void());
MOCK_CONST_METHOD1(RestoreAllTextureUnitAndSamplerBindings,
void(const gles2::ContextState* state));
MOCK_CONST_METHOD1(RestoreActiveTextureUnitBinding,
void(unsigned int target));
MOCK_METHOD0(RestoreAllExternalTextureBindingsIfNeeded, void());
MOCK_METHOD1(RestoreBufferBinding, void(unsigned int target));
MOCK_CONST_METHOD0(RestoreBufferBindings, void());
MOCK_CONST_METHOD0(RestoreFramebufferBindings, void());
MOCK_CONST_METHOD0(RestoreProgramBindings, void());
MOCK_METHOD0(RestoreRenderbufferBindings, void());
MOCK_CONST_METHOD1(RestoreTextureState, void(unsigned service_id));
MOCK_CONST_METHOD1(RestoreTextureUnitBindings, void(unsigned unit));
MOCK_METHOD1(RestoreVertexAttribArray, void(unsigned index));
MOCK_METHOD0(GetQueryManager, gles2::QueryManager*());
MOCK_METHOD0(GetGpuFenceManager, gpu::gles2::GpuFenceManager*());
MOCK_METHOD1(SetIgnoreCachedStateForTest, void(bool ignore));
MOCK_METHOD4(DoCommands,
error::Error(unsigned int num_commands,
const volatile void* buffer,
int num_entries,
int* entries_processed));
MOCK_METHOD2(GetServiceTextureId,
bool(uint32_t client_texture_id, uint32_t* service_texture_id));
MOCK_METHOD0(GetErrorState, gles2::ErrorState*());
MOCK_METHOD0(GetLogger, gles2::Logger*());
MOCK_CONST_METHOD0(WasContextLost, bool());
MOCK_CONST_METHOD0(WasContextLostByRobustnessExtension, bool());
MOCK_METHOD1(MarkContextLost, void(gpu::error::ContextLostReason reason));
MOCK_METHOD0(CheckResetStatus, bool());
MOCK_METHOD4(BindImage,
void(uint32_t client_texture_id,
uint32_t texture_target,
gl::GLImage* image,
bool can_bind_to_sampler));
private:
base::WeakPtrFactory<MockRasterDecoder> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(MockRasterDecoder);
};
} // namespace raster
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_MOCK_H_
// Copyright 2018 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.
// This file is auto-generated from
// gpu/command_buffer/build_raster_cmd_buffer.py
// It's formatted by clang-format using chromium coding style:
// clang-format -i -style=chromium filename
// DO NOT EDIT!
// It is included by raster_cmd_decoder_unittest_base.cc
#ifndef GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_0_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_0_AUTOGEN_H_
#endif // GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_0_AUTOGEN_H_
// Copyright 2018 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/raster_decoder.h"
#include "base/command_line.h"
#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/program_manager.h"
#include "gpu/command_buffer/service/raster_decoder_unittest_base.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"
using ::gl::MockGLInterface;
using ::testing::_;
using ::testing::DoAll;
using ::testing::InSequence;
using ::testing::MatcherCast;
using ::testing::Pointee;
using ::testing::Return;
using ::testing::SetArrayArgument;
using ::testing::SetArgPointee;
using ::testing::StrEq;
namespace gpu {
namespace raster {
class RasterDecoderTest1 : public RasterDecoderTestBase {
public:
RasterDecoderTest1() = default;
};
INSTANTIATE_TEST_CASE_P(Service, RasterDecoderTest1, ::testing::Bool());
template <>
void RasterDecoderTestBase::SpecializedSetup<cmds::TexParameteri, 0>(
bool /* valid */) {
DoBindTexture(GL_TEXTURE_2D, client_texture_id_, kServiceTextureId);
};
#include "gpu/command_buffer/service/raster_decoder_unittest_1_autogen.h"
} // namespace raster
} // namespace gpu
// Copyright 2018 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.
// This file is auto-generated from
// gpu/command_buffer/build_raster_cmd_buffer.py
// It's formatted by clang-format using chromium coding style:
// clang-format -i -style=chromium filename
// DO NOT EDIT!
// It is included by raster_cmd_decoder_unittest_1.cc
#ifndef GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_1_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_1_AUTOGEN_H_
TEST_P(RasterDecoderTest1, DeleteTexturesImmediateValidArgs) {
EXPECT_CALL(*gl_, DeleteTextures(1, Pointee(kServiceTextureId))).Times(1);
cmds::DeleteTexturesImmediate& cmd =
*GetImmediateAs<cmds::DeleteTexturesImmediate>();
SpecializedSetup<cmds::DeleteTexturesImmediate, 0>(true);
cmd.Init(1, &client_texture_id_);
EXPECT_EQ(error::kNoError,
ExecuteImmediateCmd(cmd, sizeof(client_texture_id_)));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
EXPECT_TRUE(GetTexture(client_texture_id_) == NULL);
}
TEST_P(RasterDecoderTest1, DeleteTexturesImmediateInvalidArgs) {
cmds::DeleteTexturesImmediate& cmd =
*GetImmediateAs<cmds::DeleteTexturesImmediate>();
SpecializedSetup<cmds::DeleteTexturesImmediate, 0>(false);
GLuint temp = kInvalidClientId;
cmd.Init(1, &temp);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
}
TEST_P(RasterDecoderTest1, FinishValidArgs) {
EXPECT_CALL(*gl_, Finish());
SpecializedSetup<cmds::Finish, 0>(true);
cmds::Finish cmd;
cmd.Init();
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
TEST_P(RasterDecoderTest1, FlushValidArgs) {
EXPECT_CALL(*gl_, Flush());
SpecializedSetup<cmds::Flush, 0>(true);
cmds::Flush cmd;
cmd.Init();
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
TEST_P(RasterDecoderTest1, GenTexturesImmediateValidArgs) {
EXPECT_CALL(*gl_, GenTextures(1, _))
.WillOnce(SetArgPointee<1>(kNewServiceId));
cmds::GenTexturesImmediate* cmd =
GetImmediateAs<cmds::GenTexturesImmediate>();
GLuint temp = kNewClientId;
SpecializedSetup<cmds::GenTexturesImmediate, 0>(true);
cmd->Init(1, &temp);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(*cmd, sizeof(temp)));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
EXPECT_TRUE(GetTexture(kNewClientId) != NULL);
}
TEST_P(RasterDecoderTest1, GenTexturesImmediateDuplicateOrNullIds) {
EXPECT_CALL(*gl_, GenTextures(_, _)).Times(0);
cmds::GenTexturesImmediate* cmd =
GetImmediateAs<cmds::GenTexturesImmediate>();
GLuint temp[3] = {kNewClientId, kNewClientId + 1, kNewClientId};
SpecializedSetup<cmds::GenTexturesImmediate, 1>(true);
cmd->Init(3, temp);
EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
EXPECT_TRUE(GetTexture(kNewClientId) == NULL);
EXPECT_TRUE(GetTexture(kNewClientId + 1) == NULL);
GLuint null_id[2] = {kNewClientId, 0};
cmd->Init(2, null_id);
EXPECT_EQ(error::kInvalidArguments, ExecuteImmediateCmd(*cmd, sizeof(temp)));
EXPECT_TRUE(GetTexture(kNewClientId) == NULL);
}
TEST_P(RasterDecoderTest1, GenTexturesImmediateInvalidArgs) {
EXPECT_CALL(*gl_, GenTextures(_, _)).Times(0);
cmds::GenTexturesImmediate* cmd =
GetImmediateAs<cmds::GenTexturesImmediate>();
SpecializedSetup<cmds::GenTexturesImmediate, 0>(false);
cmd->Init(1, &client_texture_id_);
EXPECT_EQ(error::kInvalidArguments,
ExecuteImmediateCmd(*cmd, sizeof(&client_texture_id_)));
}
TEST_P(RasterDecoderTest1, GetErrorValidArgs) {
EXPECT_CALL(*gl_, GetError());
SpecializedSetup<cmds::GetError, 0>(true);
cmds::GetError cmd;
cmd.Init(shared_memory_id_, shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
TEST_P(RasterDecoderTest1, GetErrorInvalidArgsBadSharedMemoryId) {
EXPECT_CALL(*gl_, GetError()).Times(0);
SpecializedSetup<cmds::GetError, 0>(false);
cmds::GetError cmd;
cmd.Init(kInvalidSharedMemoryId, shared_memory_offset_);
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
cmd.Init(shared_memory_id_, kInvalidSharedMemoryOffset);
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
}
TEST_P(RasterDecoderTest1, GetIntegervValidArgs) {
EXPECT_CALL(*gl_, GetError()).WillRepeatedly(Return(GL_NO_ERROR));
SpecializedSetup<cmds::GetIntegerv, 0>(true);
typedef cmds::GetIntegerv::Result Result;
Result* result = static_cast<Result*>(shared_memory_address_);
EXPECT_CALL(*gl_, GetIntegerv(GL_ACTIVE_TEXTURE, result->GetData()));
result->size = 0;
cmds::GetIntegerv cmd;
cmd.Init(GL_ACTIVE_TEXTURE, shared_memory_id_, shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(decoder_->GetGLES2Util()->GLGetNumValuesReturned(GL_ACTIVE_TEXTURE),
result->GetNumResults());
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
TEST_P(RasterDecoderTest1, GetIntegervInvalidArgs0_0) {
EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0);
SpecializedSetup<cmds::GetIntegerv, 0>(false);
cmds::GetIntegerv::Result* result =
static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
result->size = 0;
cmds::GetIntegerv cmd;
cmd.Init(GL_FOG_HINT, shared_memory_id_, shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(0u, result->size);
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
TEST_P(RasterDecoderTest1, GetIntegervInvalidArgs1_0) {
EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0);
SpecializedSetup<cmds::GetIntegerv, 0>(false);
cmds::GetIntegerv::Result* result =
static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
result->size = 0;
cmds::GetIntegerv cmd;
cmd.Init(GL_ACTIVE_TEXTURE, kInvalidSharedMemoryId, 0);
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
EXPECT_EQ(0u, result->size);
}
TEST_P(RasterDecoderTest1, GetIntegervInvalidArgs1_1) {
EXPECT_CALL(*gl_, GetIntegerv(_, _)).Times(0);
SpecializedSetup<cmds::GetIntegerv, 0>(false);
cmds::GetIntegerv::Result* result =
static_cast<cmds::GetIntegerv::Result*>(shared_memory_address_);
result->size = 0;
cmds::GetIntegerv cmd;
cmd.Init(GL_ACTIVE_TEXTURE, shared_memory_id_, kInvalidSharedMemoryOffset);
EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd));
EXPECT_EQ(0u, result->size);
}
TEST_P(RasterDecoderTest1, TexParameteriValidArgs) {
EXPECT_CALL(*gl_,
TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
SpecializedSetup<cmds::TexParameteri, 0>(true);
cmds::TexParameteri cmd;
cmd.Init(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_NO_ERROR, GetGLError());
}
TEST_P(RasterDecoderTest1, TexParameteriInvalidArgs0_0) {
EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
SpecializedSetup<cmds::TexParameteri, 0>(false);
cmds::TexParameteri cmd;
cmd.Init(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
TEST_P(RasterDecoderTest1, TexParameteriInvalidArgs0_1) {
EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
SpecializedSetup<cmds::TexParameteri, 0>(false);
cmds::TexParameteri cmd;
cmd.Init(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
TEST_P(RasterDecoderTest1, TexParameteriInvalidArgs1_0) {
EXPECT_CALL(*gl_, TexParameteri(_, _, _)).Times(0);
SpecializedSetup<cmds::TexParameteri, 0>(false);
cmds::TexParameteri cmd;
cmd.Init(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_NEAREST);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
#endif // GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_1_AUTOGEN_H_
This diff is collapsed.
// Copyright 2018 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_RASTER_DECODER_UNITTEST_BASE_H_
#define GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_BASE_H_
#include <stddef.h>
#include <stdint.h>
#include <array>
#include <memory>
#include "base/message_loop/message_loop.h"
#include "gpu/command_buffer/client/client_test_helper.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/common/raster_cmd_format.h"
#include "gpu/command_buffer/service/buffer_manager.h"
#include "gpu/command_buffer/service/context_group.h"
#include "gpu/command_buffer/service/decoder_client.h"
#include "gpu/command_buffer/service/framebuffer_manager.h"
#include "gpu/command_buffer/service/gl_context_mock.h"
#include "gpu/command_buffer/service/gpu_preferences.h"
#include "gpu/command_buffer/service/gpu_tracer.h"
#include "gpu/command_buffer/service/image_manager.h"
#include "gpu/command_buffer/service/mailbox_manager_impl.h"
#include "gpu/command_buffer/service/raster_decoder.h"
#include "gpu/command_buffer/service/raster_decoder_mock.h"
#include "gpu/command_buffer/service/service_discardable_manager.h"
#include "gpu/command_buffer/service/shader_manager.h"
#include "gpu/command_buffer/service/test_helper.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"
#include "ui/gl/gl_surface_stub.h"
#include "ui/gl/gl_version_info.h"
namespace gpu {
namespace gles2 {
class MemoryTracker;
} // namespace gles2
namespace raster {
class RasterDecoderTestBase : public ::testing::TestWithParam<bool>,
public DecoderClient {
public:
RasterDecoderTestBase();
~RasterDecoderTestBase() override;
void OnConsoleMessage(int32_t id, const std::string& message) override;
void CacheShader(const std::string& key, const std::string& shader) override;
void OnFenceSyncRelease(uint64_t release) override;
bool OnWaitSyncToken(const gpu::SyncToken&) override;
void OnDescheduleUntilFinished() override;
void OnRescheduleAfterFinished() override;
// Template to call glGenXXX functions.
template <typename T>
void GenHelper(GLuint client_id) {
int8_t buffer[sizeof(T) + sizeof(client_id)];
T& cmd = *reinterpret_cast<T*>(&buffer);
cmd.Init(1, &client_id);
EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(client_id)));
}
// This template exists solely so we can specialize it for
// certain commands.
template <typename T, int id>
void SpecializedSetup(bool valid) {}
template <typename T>
T* GetImmediateAs() {
return reinterpret_cast<T*>(immediate_buffer_);
}
void ClearSharedMemory() {
memset(shared_memory_base_, kInitialMemoryValue, kSharedBufferSize);
}
void SetUp() override;
void TearDown() override;
template <typename T>
error::Error ExecuteCmd(const T& cmd) {
static_assert(T::kArgFlags == cmd::kFixed,
"T::kArgFlags should equal cmd::kFixed");
int entries_processed = 0;
return decoder_->DoCommands(1, (const void*)&cmd,
ComputeNumEntries(sizeof(cmd)),
&entries_processed);
}
template <typename T>
error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) {
static_assert(T::kArgFlags == cmd::kAtLeastN,
"T::kArgFlags should equal cmd::kAtLeastN");
int entries_processed = 0;
return decoder_->DoCommands(1, (const void*)&cmd,
ComputeNumEntries(sizeof(cmd) + data_size),
&entries_processed);
}
template <typename T>
T GetSharedMemoryAs() {
return reinterpret_cast<T>(shared_memory_address_);
}
template <typename T>
T GetSharedMemoryAsWithOffset(uint32_t offset) {
void* ptr = reinterpret_cast<int8_t*>(shared_memory_address_) + offset;
return reinterpret_cast<T>(ptr);
}
gles2::TextureRef* GetTexture(GLuint client_id) {
return group_->texture_manager()->GetTexture(client_id);
}
void SetBucketData(uint32_t bucket_id, const void* data, uint32_t data_size);
void SetBucketAsCString(uint32_t bucket_id, const char* str);
// If we want a valid bucket, just set |count_in_header| as |count|,
// and set |str_end| as 0.
void SetBucketAsCStrings(uint32_t bucket_id,
GLsizei count,
const char** str,
GLsizei count_in_header,
char str_end);
void InitDecoderWithWorkarounds();
void ResetDecoder();
const gles2::ContextGroup& group() const { return *group_.get(); }
void LoseContexts(error::ContextLostReason reason) const {
group_->LoseContexts(reason);
}
error::ContextLostReason GetContextLostReason() const {
return command_buffer_service_->GetState().context_lost_reason;
}
::testing::StrictMock<::gl::MockGLInterface>* GetGLMock() const {
return gl_.get();
}
RasterDecoder* GetDecoder() const { return decoder_.get(); }
typedef gles2::TestHelper::AttribInfo AttribInfo;
typedef gles2::TestHelper::UniformInfo UniformInfo;
void SetupInitStateExpectations(bool es3_capable);
void SetupTexture();
// Note that the error is returned as GLint instead of GLenum.
// This is because there is a mismatch in the types of GLenum and
// the error values GL_NO_ERROR, GL_INVALID_ENUM, etc. GLenum is
// typedef'd as unsigned int while the error values are defined as
// integers. This is problematic for template functions such as
// EXPECT_EQ that expect both types to be the same.
GLint GetGLError();
void DoBindTexture(GLenum target, GLuint client_id, GLuint service_id);
void DoDeleteTexture(GLuint client_id, GLuint service_id);
void DoPixelStorei(GLenum pname, GLint param);
GLvoid* BufferOffset(unsigned i) { return static_cast<int8_t*>(NULL) + (i); }
protected:
static const GLint kMaxTextureSize = 2048;
static const GLint kNumTextureUnits = 8;
static const GLuint kServiceBufferId = 301;
static const GLuint kServiceTextureId = 304;
static const size_t kSharedBufferSize = 2048;
static const uint32_t kSharedMemoryOffset = 132;
static const int32_t kInvalidSharedMemoryId =
FakeCommandBufferServiceBase::kTransferBufferBaseId - 1;
static const uint32_t kInvalidSharedMemoryOffset = kSharedBufferSize + 1;
static const uint32_t kInitialResult = 0xBDBDBDBDu;
static const uint8_t kInitialMemoryValue = 0xBDu;
static const uint32_t kNewClientId = 501;
static const uint32_t kNewServiceId = 502;
static const uint32_t kInvalidClientId = 601;
// Use StrictMock to make 100% sure we know how GL will be called.
std::unique_ptr<::testing::StrictMock<::gl::MockGLInterface>> gl_;
scoped_refptr<gl::GLSurfaceStub> surface_;
scoped_refptr<GLContextMock> context_;
std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
gles2::TraceOutputter outputter_;
std::unique_ptr<MockRasterDecoder> mock_decoder_;
std::unique_ptr<RasterDecoder> decoder_;
gles2::MemoryTracker* memory_tracker_;
GLuint client_texture_id_;
int32_t shared_memory_id_;
uint32_t shared_memory_offset_;
void* shared_memory_address_;
void* shared_memory_base_;
uint32_t immediate_buffer_[64];
const bool ignore_cached_state_for_test_;
private:
GpuPreferences gpu_preferences_;
gles2::MailboxManagerImpl mailbox_manager_;
gles2::ShaderTranslatorCache shader_translator_cache_;
gles2::FramebufferCompletenessCache framebuffer_completeness_cache_;
gles2::ImageManager image_manager_;
ServiceDiscardableManager discardable_manager_;
scoped_refptr<gles2::ContextGroup> group_;
base::MessageLoop message_loop_;
};
} // namespace raster
} // namespace gpu
#endif // GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_BASE_H_
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