Index: gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc |
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc |
index f87a4bd24b52cb5f4133ec07b83935468e337056..916f2aa76b18b4e2320d690100557bbc324b3988 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions.cc |
@@ -4,21 +4,134 @@ |
#include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
+#include "base/command_line.h" |
#include "gpu/command_buffer/common/gles2_cmd_format.h" |
#include "gpu/command_buffer/common/gles2_cmd_utils.h" |
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h" |
+#include "gpu/command_buffer/service/gpu_switches.h" |
#include "testing/gtest/include/gtest/gtest.h" |
#include "ui/gl/gl_mock.h" |
using ::gfx::MockGLInterface; |
using ::testing::_; |
+using ::testing::Return; |
namespace gpu { |
namespace gles2 { |
+// Class to use to test that functions which need feature flags or |
+// extensions always return INVALID_OPERATION if the feature flags is not |
+// enabled or extension is not present. |
+class GLES2DecoderTestDisabledExtensions : public GLES2DecoderTest { |
+ public: |
+ GLES2DecoderTestDisabledExtensions() {} |
+}; |
+INSTANTIATE_TEST_CASE_P(Service, |
+ GLES2DecoderTestDisabledExtensions, |
+ ::testing::Bool()); |
+ |
+TEST_P(GLES2DecoderTestDisabledExtensions, CHROMIUMPathRenderingDisabled) { |
+ const GLuint kClientPathId = 0; |
+ { |
+ cmds::MatrixLoadfCHROMIUMImmediate& cmd = |
+ *GetImmediateAs<cmds::MatrixLoadfCHROMIUMImmediate>(); |
+ GLfloat temp[16] = { |
+ 0, |
+ }; |
+ cmd.Init(GL_PATH_MODELVIEW_CHROMIUM, temp); |
+ EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp))); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::MatrixLoadIdentityCHROMIUM cmd; |
+ cmd.Init(GL_PATH_PROJECTION_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::GenPathsCHROMIUM cmd; |
+ cmd.Init(0, 0); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::DeletePathsCHROMIUM cmd; |
+ cmd.Init(0, 0); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::IsPathCHROMIUM cmd; |
+ cmd.Init(kClientPathId, shared_memory_id_, shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::PathCommandsCHROMIUM cmd; |
+ cmd.Init(kClientPathId, 0, 0, 0, 0, GL_FLOAT, 0, 0); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::PathParameterfCHROMIUM cmd; |
+ cmd.Init(kClientPathId, GL_PATH_STROKE_WIDTH_CHROMIUM, 1.0f); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::PathParameteriCHROMIUM cmd; |
+ cmd.Init(kClientPathId, GL_PATH_STROKE_WIDTH_CHROMIUM, 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::PathStencilFuncCHROMIUM cmd; |
+ cmd.Init(GL_NEVER, 2, 3); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::StencilFillPathCHROMIUM cmd; |
+ cmd.Init(kClientPathId, GL_COUNT_UP_CHROMIUM, 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::StencilStrokePathCHROMIUM cmd; |
+ cmd.Init(kClientPathId, 1, 2); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::CoverFillPathCHROMIUM cmd; |
+ cmd.Init(kClientPathId, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::CoverStrokePathCHROMIUM cmd; |
+ cmd.Init(kClientPathId, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::StencilThenCoverFillPathCHROMIUM cmd; |
+ cmd.Init(kClientPathId, GL_COUNT_UP_CHROMIUM, 1, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ cmds::StencilThenCoverStrokePathCHROMIUM cmd; |
+ cmd.Init(kClientPathId, 1, 2, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+} |
+ |
class GLES2DecoderTestWithCHROMIUMPathRendering : public GLES2DecoderTest { |
public: |
- GLES2DecoderTestWithCHROMIUMPathRendering() {} |
+ GLES2DecoderTestWithCHROMIUMPathRendering() : client_path_id_(125) {} |
+ |
void SetUp() override { |
InitState init; |
init.gl_version = "opengl es 3.1"; |
@@ -28,8 +141,24 @@ class GLES2DecoderTestWithCHROMIUMPathRendering : public GLES2DecoderTest { |
init.request_depth = true; |
init.bind_generates_resource = true; |
init.extensions = "GL_NV_path_rendering"; |
- InitDecoder(init); |
+ base::CommandLine command_line(0, NULL); |
+ command_line.AppendSwitch(switches::kEnableGLPathRendering); |
+ InitDecoderWithCommandLine(init, &command_line); |
+ |
+ EXPECT_CALL(*gl_, GenPathsNV(1)) |
+ .WillOnce(Return(kServicePathId)) |
+ .RetiresOnSaturation(); |
+ cmds::GenPathsCHROMIUM cmd; |
+ cmd.Init(client_path_id_, 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
} |
+ |
+ protected: |
+ template <typename TypeParam> |
+ void TestPathCommandsCHROMIUMCoordTypes(); |
+ |
+ GLuint client_path_id_; |
+ static const GLuint kServicePathId = 311; |
}; |
INSTANTIATE_TEST_CASE_P(Service, |
@@ -56,6 +185,814 @@ INSTANTIATE_TEST_CASE_P(Service, |
GLES2DecoderTestWithBlendEquationAdvanced, |
::testing::Bool()); |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, GenDeletePaths) { |
+ static GLuint kFirstClientID = client_path_id_ + 88; |
+ static GLsizei kPathCount = 58; |
+ static GLuint kFirstCreatedServiceID = 8000; |
+ |
+ // GenPaths range 0 causes no calls. |
+ cmds::GenPathsCHROMIUM gen_cmd; |
+ gen_cmd.Init(kFirstClientID, 0); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // DeletePaths range 0 causes no calls. |
+ cmds::DeletePathsCHROMIUM delete_cmd; |
+ delete_cmd.Init(kFirstClientID, 0); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // DeletePaths client 0 causes no calls and no errors. |
+ delete_cmd.Init(0, 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // DeletePaths with a big range should not cause any deletes. |
+ delete_cmd.Init(client_path_id_ + 1, |
+ std::numeric_limits<GLsizei>::max() - client_path_id_ - 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ delete_cmd.Init(std::numeric_limits<GLsizei>::max() + 1, |
+ std::numeric_limits<GLsizei>::max()); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Normal Gen and Delete should cause the normal calls. |
+ EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) |
+ .WillOnce(Return(kFirstCreatedServiceID)) |
+ .RetiresOnSaturation(); |
+ |
+ gen_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) |
+ .RetiresOnSaturation(); |
+ |
+ delete_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, GenDeleteRanges) { |
+ static GLuint kFirstClientID = client_path_id_ + 77; |
+ static GLsizei kPathCount = 5800; |
+ static GLuint kFirstCreatedServiceID = 8000; |
+ |
+ // Create a range of path names, delete one in middle and then |
+ // the rest. Expect 3 DeletePath calls. |
+ EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) |
+ .WillOnce(Return(kFirstCreatedServiceID)) |
+ .RetiresOnSaturation(); |
+ cmds::GenPathsCHROMIUM gen_cmd; |
+ gen_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID + (kPathCount / 2), 1)) |
+ .RetiresOnSaturation(); |
+ |
+ cmds::DeletePathsCHROMIUM delete_cmd; |
+ delete_cmd.Init(kFirstClientID + (kPathCount / 2), 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, (kPathCount / 2))) |
+ .RetiresOnSaturation(); |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID + (kPathCount / 2) + 1, |
+ (kPathCount / 2) - 1)).RetiresOnSaturation(); |
+ |
+ delete_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, GenDeleteManyPaths) { |
+ static GLuint kFirstClientID = client_path_id_ + 1; |
+ static GLsizei kPathCount = std::numeric_limits<GLsizei>::max(); |
+ static GLuint kFirstCreatedServiceID = 8000; |
+ |
+ EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) |
+ .WillOnce(Return(kFirstCreatedServiceID)) |
+ .RetiresOnSaturation(); |
+ |
+ // GenPaths with big range. |
+ cmds::GenPathsCHROMIUM gen_cmd; |
+ gen_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Path range wraps, so we get connection error. |
+ gen_cmd.Init(kFirstClientID + kPathCount, kPathCount); |
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) |
+ .RetiresOnSaturation(); |
+ |
+ cmds::DeletePathsCHROMIUM delete_cmd; |
+ delete_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Delete every possible path. |
+ // We run into the one created for client_path_id_. |
+ EXPECT_CALL(*gl_, DeletePathsNV(kServicePathId, 1)).RetiresOnSaturation(); |
+ |
+ delete_cmd.Init(1u, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ delete_cmd.Init(static_cast<GLuint>(kPathCount) + 1u, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Allocate every possible path, delete few, allocate them back and |
+ // expect minimum amount of calls. |
+ EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) |
+ .WillOnce(Return(static_cast<GLuint>(1u))) |
+ .WillOnce(Return(static_cast<GLuint>(kPathCount) + 1u)) |
+ .RetiresOnSaturation(); |
+ |
+ gen_cmd.Init(1u, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ gen_cmd.Init(static_cast<GLuint>(kPathCount) + 1u, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ gen_cmd.Init(static_cast<GLuint>(kPathCount) * 2u + 2u, kPathCount); |
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstClientID, 4)).RetiresOnSaturation(); |
+ |
+ delete_cmd.Init(kFirstClientID, 4); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstClientID * 3, 1)).RetiresOnSaturation(); |
+ |
+ delete_cmd.Init(kFirstClientID * 3, 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, GenPathsNV(1)) |
+ .WillOnce(Return(kFirstClientID)) |
+ .WillOnce(Return(kFirstClientID + 1)) |
+ .WillOnce(Return(kFirstClientID + 2)) |
+ .WillOnce(Return(kFirstClientID + 3)) |
+ .RetiresOnSaturation(); |
+ |
+ for (int i = 0; i < 4; ++i) { |
+ gen_cmd.Init(kFirstClientID + i, 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ } |
+ |
+ EXPECT_CALL(*gl_, GenPathsNV(1)) |
+ .WillOnce(Return(kFirstClientID * 3)) |
+ .RetiresOnSaturation(); |
+ gen_cmd.Init(kFirstClientID * 3, 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, DeletePathsNV(1u, kPathCount)).RetiresOnSaturation(); |
+ EXPECT_CALL(*gl_, DeletePathsNV(static_cast<GLuint>(kPathCount) + 1u, |
+ kPathCount)).RetiresOnSaturation(); |
+ |
+ delete_cmd.Init(1u, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ delete_cmd.Init(static_cast<GLuint>(kPathCount) + 1u, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Cleanup: return the client_path_id_ as a path. |
+ EXPECT_CALL(*gl_, GenPathsNV(1)) |
+ .WillOnce(Return(static_cast<GLuint>(kServicePathId))) |
+ .RetiresOnSaturation(); |
+ |
+ gen_cmd.Init(client_path_id_, 1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
+ GenPathsCHROMIUMInvalidCalls) { |
+ static GLuint kFirstClientID = client_path_id_ + 88; |
+ static GLsizei kPathCount = 5800; |
+ static GLuint kFirstCreatedServiceID = 8000; |
+ |
+ // Range < 0 is causes gl error. |
+ cmds::GenPathsCHROMIUM gen_cmd; |
+ gen_cmd.Init(kFirstClientID, -1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); |
+ |
+ // Path 0 is invalid client id, connection error. |
+ gen_cmd.Init(0, kPathCount); |
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Too big range causes client id to wrap, connection error. |
+ gen_cmd.Init(std::numeric_limits<GLsizei>::max() + 3, |
+ std::numeric_limits<GLsizei>::max()); |
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Creating duplicate client_ids cause connection error. |
+ EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) |
+ .WillOnce(Return(kFirstCreatedServiceID)) |
+ .RetiresOnSaturation(); |
+ |
+ gen_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Create duplicate by executing the same cmd. |
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Create duplicate by creating a range that contains |
+ // an already existing client path id. |
+ gen_cmd.Init(kFirstClientID - 1, 2); |
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Cleanup. |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) |
+ .RetiresOnSaturation(); |
+ cmds::DeletePathsCHROMIUM delete_cmd; |
+ delete_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
+ DeletePathsCHROMIUMInvalidCalls) { |
+ static GLuint kFirstClientID = client_path_id_ + 88; |
+ |
+ // Range < 0 is causes gl error. |
+ cmds::DeletePathsCHROMIUM delete_cmd; |
+ delete_cmd.Init(kFirstClientID, -1); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); |
+ |
+ // Too big range causes client id to wrap, connection error. |
+ delete_cmd.Init(std::numeric_limits<GLsizei>::max() + 3, |
+ std::numeric_limits<GLsizei>::max()); |
+ EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
+ PathCommandsCHROMIUMInvalidCalls) { |
+ static const GLsizei kCorrectCoordCount = 19; |
+ static const GLsizei kCorrectCommandCount = 6; |
+ static const GLenum kInvalidCoordType = GL_NONE; |
+ |
+ GLfloat* coords = GetSharedMemoryAs<GLfloat*>(); |
+ unsigned commands_offset = sizeof(GLfloat) * kCorrectCoordCount; |
+ GLubyte* commands = GetSharedMemoryAsWithOffset<GLubyte*>(commands_offset); |
+ for (int i = 0; i < kCorrectCoordCount; ++i) { |
+ coords[i] = 5.0f * i; |
+ } |
+ commands[0] = GL_MOVE_TO_CHROMIUM; |
+ commands[1] = GL_CLOSE_PATH_CHROMIUM; |
+ commands[2] = GL_LINE_TO_CHROMIUM; |
+ commands[3] = GL_QUADRATIC_CURVE_TO_CHROMIUM; |
+ commands[4] = GL_CUBIC_CURVE_TO_CHROMIUM; |
+ commands[5] = GL_CONIC_CURVE_TO_CHROMIUM; |
+ |
+ EXPECT_CALL(*gl_, PathCommandsNV(kServicePathId, kCorrectCommandCount, |
+ commands, kCorrectCoordCount, GL_FLOAT, |
+ coords)).RetiresOnSaturation(); |
+ |
+ cmds::PathCommandsCHROMIUM cmd; |
+ |
+ // Reference call -- this succeeds. |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_ + commands_offset, kCorrectCoordCount, |
+ GL_FLOAT, shared_memory_id_, shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, PathCommandsNV(_, _, _, _, _, _)).Times(0); |
+ |
+ // Invalid client id fails. |
+ cmd.Init(client_path_id_ - 1, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_, kCorrectCoordCount, GL_FLOAT, |
+ shared_memory_id_, shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ |
+ // The numCommands < 0. |
+ cmd.Init(client_path_id_, -1, shared_memory_id_, shared_memory_offset_, |
+ kCorrectCoordCount, GL_FLOAT, shared_memory_id_, |
+ shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); |
+ |
+ // The numCoords < 0. |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_, -1, GL_FLOAT, shared_memory_id_, |
+ shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); |
+ |
+ // Invalid coordType fails. |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_, kCorrectCoordCount, kInvalidCoordType, |
+ shared_memory_id_, shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); |
+ |
+ // Big command counts. |
+ cmd.Init(client_path_id_, std::numeric_limits<GLsizei>::max(), |
+ shared_memory_id_, shared_memory_offset_ + commands_offset, |
+ kCorrectCoordCount, GL_FLOAT, shared_memory_id_, |
+ shared_memory_offset_); |
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Invalid SHM cases. |
+ cmd.Init(client_path_id_, kCorrectCommandCount, kInvalidSharedMemoryId, |
+ shared_memory_offset_ + commands_offset, kCorrectCoordCount, |
+ GL_FLOAT, shared_memory_id_, shared_memory_offset_); |
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ kInvalidSharedMemoryOffset, kCorrectCoordCount, GL_FLOAT, |
+ shared_memory_id_, shared_memory_offset_); |
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_ + commands_offset, kCorrectCoordCount, |
+ GL_FLOAT, kInvalidSharedMemoryId, shared_memory_offset_); |
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_ + commands_offset, kCorrectCoordCount, |
+ GL_FLOAT, shared_memory_id_, kInvalidSharedMemoryOffset); |
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // NULL shm command id with non-zero command count. |
+ cmd.Init(client_path_id_, kCorrectCommandCount, 0, 0, kCorrectCoordCount, |
+ GL_FLOAT, shared_memory_id_, shared_memory_offset_); |
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // NULL shm coord id with non-zero coord count. |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_ + commands_offset, kCorrectCoordCount, |
+ GL_FLOAT, 0, 0); |
+ EXPECT_EQ(error::kOutOfBounds, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // The coordCount not matching what is in commands. |
+ // Expects kCorrectCoordCount+2 coords. |
+ commands[1] = GL_MOVE_TO_CHROMIUM; |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_ + commands_offset, kCorrectCoordCount, |
+ GL_FLOAT, shared_memory_id_, shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ |
+ // The coordCount not matching what is in commands. |
+ // Expects kCorrectCoordCount-2 coords. |
+ commands[0] = GL_CLOSE_PATH_CHROMIUM; |
+ commands[1] = GL_CLOSE_PATH_CHROMIUM; |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ |
+ // NULL shm coord ids. Currently causes gl error, though client should not let |
+ // this through. |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_ + commands_offset, kCorrectCoordCount, |
+ GL_FLOAT, 0, 0); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
+ PathCommandsCHROMIUMEmptyCommands) { |
+ EXPECT_CALL(*gl_, PathCommandsNV(kServicePathId, 0, NULL, 0, GL_FLOAT, NULL)) |
+ .RetiresOnSaturation(); |
+ cmds::PathCommandsCHROMIUM cmd; |
+ cmd.Init(client_path_id_, 0, 0, 0, 0, GL_FLOAT, 0, 0); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
+ PathCommandsCHROMIUMInvalidCommands) { |
+ EXPECT_CALL(*gl_, PathCommandsNV(_, _, _, _, _, _)).Times(0); |
+ |
+ cmds::PathCommandsCHROMIUM cmd; |
+ |
+ { |
+ const GLsizei kCoordCount = 2; |
+ const GLsizei kCommandCount = 2; |
+ GLfloat* coords = GetSharedMemoryAs<GLfloat*>(); |
+ unsigned commands_offset = sizeof(GLfloat) * kCoordCount; |
+ GLubyte* commands = GetSharedMemoryAsWithOffset<GLubyte*>(commands_offset); |
+ |
+ coords[0] = 5.0f; |
+ coords[1] = 5.0f; |
+ commands[0] = 0x3; // Token MOVE_TO_RELATIVE in NV_path_rendering. |
+ commands[1] = GL_CLOSE_PATH_CHROMIUM; |
+ |
+ cmd.Init(client_path_id_ - 1, kCommandCount, shared_memory_id_, |
+ shared_memory_offset_, kCoordCount, GL_FLOAT, shared_memory_id_, |
+ shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+ { |
+ const GLsizei kCoordCount = 8; |
+ const GLsizei kCommandCount = 4; |
+ GLfloat* coords = GetSharedMemoryAs<GLfloat*>(); |
+ unsigned commands_offset = sizeof(GLfloat) * kCoordCount; |
+ GLubyte* commands = GetSharedMemoryAsWithOffset<GLubyte*>(commands_offset); |
+ |
+ for (int i = 0; i < kCoordCount; ++i) { |
+ coords[i] = 5.0f * i; |
+ } |
+ commands[0] = GL_MOVE_TO_CHROMIUM; |
+ commands[1] = GL_MOVE_TO_CHROMIUM; |
+ commands[2] = 'M'; // Synonym to MOVE_TO in NV_path_rendering. |
+ commands[3] = GL_MOVE_TO_CHROMIUM; |
+ |
+ cmd.Init(client_path_id_ - 1, kCommandCount, shared_memory_id_, |
+ shared_memory_offset_, kCoordCount, GL_FLOAT, shared_memory_id_, |
+ shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); |
+ } |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, PathParameterXCHROMIUM) { |
+ static GLuint kFirstClientID = client_path_id_ + 88; |
+ static GLsizei kPathCount = 2; |
+ static GLuint kFirstCreatedServiceID = 8000; |
+ |
+ // Create a paths so that we do not modify client_path_id_ |
+ EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) |
+ .WillOnce(Return(kFirstCreatedServiceID)) |
+ .RetiresOnSaturation(); |
+ cmds::GenPathsCHROMIUM gen_cmd; |
+ gen_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ cmds::PathParameterfCHROMIUM fcmd; |
+ cmds::PathParameteriCHROMIUM icmd; |
+ const struct { |
+ GLenum pname; |
+ GLfloat value; |
+ GLfloat expected_value; |
+ } kTestcases[] = { |
+ {GL_PATH_STROKE_WIDTH_CHROMIUM, 1.0f, 1.0f}, |
+ {GL_PATH_STROKE_WIDTH_CHROMIUM, 0.0f, 0.0f}, |
+ {GL_PATH_MITER_LIMIT_CHROMIUM, 500.0f, 500.0f}, |
+ {GL_PATH_STROKE_BOUND_CHROMIUM, .80f, .80f}, |
+ {GL_PATH_STROKE_BOUND_CHROMIUM, 1.80f, 1.0f}, |
+ {GL_PATH_STROKE_BOUND_CHROMIUM, -1.0f, 0.0f}, |
+ {GL_PATH_END_CAPS_CHROMIUM, GL_FLAT_CHROMIUM, GL_FLAT_CHROMIUM}, |
+ {GL_PATH_END_CAPS_CHROMIUM, GL_SQUARE_CHROMIUM, GL_SQUARE_CHROMIUM}, |
+ {GL_PATH_JOIN_STYLE_CHROMIUM, |
+ GL_MITER_REVERT_CHROMIUM, |
+ GL_MITER_REVERT_CHROMIUM}, |
+ }; |
+ |
+ for (auto& testcase : kTestcases) { |
+ EXPECT_CALL(*gl_, PathParameterfNV(kFirstCreatedServiceID, testcase.pname, |
+ testcase.expected_value)) |
+ .Times(1) |
+ .RetiresOnSaturation(); |
+ fcmd.Init(kFirstClientID, testcase.pname, testcase.value); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(fcmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, |
+ PathParameteriNV(kFirstCreatedServiceID + 1, testcase.pname, |
+ static_cast<GLint>(testcase.expected_value))) |
+ .Times(1) |
+ .RetiresOnSaturation(); |
+ icmd.Init(kFirstClientID + 1, testcase.pname, |
+ static_cast<GLint>(testcase.value)); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(icmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ } |
+ |
+ // Cleanup. |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) |
+ .RetiresOnSaturation(); |
+ |
+ cmds::DeletePathsCHROMIUM delete_cmd; |
+ delete_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
+ PathParameterXCHROMIUMInvalidArgs) { |
+ static GLuint kFirstClientID = client_path_id_ + 88; |
+ static GLsizei kPathCount = 2; |
+ static GLuint kFirstCreatedServiceID = 8000; |
+ |
+ // Create a paths so that we do not modify client_path_id_ |
+ EXPECT_CALL(*gl_, GenPathsNV(kPathCount)) |
+ .WillOnce(Return(kFirstCreatedServiceID)) |
+ .RetiresOnSaturation(); |
+ cmds::GenPathsCHROMIUM gen_cmd; |
+ gen_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(gen_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ cmds::PathParameterfCHROMIUM fcmd; |
+ cmds::PathParameteriCHROMIUM icmd; |
+ const struct { |
+ GLenum pname; |
+ GLfloat value; |
+ bool try_int_version; |
+ GLint error; |
+ } kTestcases[] = { |
+ {GL_PATH_STROKE_WIDTH_CHROMIUM, -1.0f, true, GL_INVALID_VALUE}, |
+ {GL_PATH_MITER_LIMIT_CHROMIUM, |
+ std::numeric_limits<float>::infinity(), |
+ false, |
+ GL_INVALID_VALUE}, |
+ {GL_PATH_MITER_LIMIT_CHROMIUM, |
+ std::numeric_limits<float>::quiet_NaN(), |
+ false, |
+ GL_INVALID_VALUE}, |
+ {GL_PATH_END_CAPS_CHROMIUM, 0x4, true, GL_INVALID_VALUE}, |
+ {GL_PATH_END_CAPS_CHROMIUM, |
+ GL_MITER_REVERT_CHROMIUM, |
+ true, |
+ GL_INVALID_VALUE}, |
+ {GL_PATH_JOIN_STYLE_CHROMIUM, GL_FLAT_CHROMIUM, true, GL_INVALID_VALUE}, |
+ {GL_PATH_MODELVIEW_CHROMIUM, GL_FLAT_CHROMIUM, true, GL_INVALID_ENUM}, |
+ }; |
+ |
+ EXPECT_CALL(*gl_, PathParameterfNV(_, _, _)).Times(0); |
+ EXPECT_CALL(*gl_, PathParameteriNV(_, _, _)).Times(0); |
+ |
+ for (auto& testcase : kTestcases) { |
+ fcmd.Init(kFirstClientID, testcase.pname, testcase.value); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(fcmd)); |
+ EXPECT_EQ(testcase.error, GetGLError()); |
+ if (!testcase.try_int_version) |
+ continue; |
+ |
+ icmd.Init(kFirstClientID + 1, testcase.pname, |
+ static_cast<GLint>(testcase.value)); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(icmd)); |
+ EXPECT_EQ(testcase.error, GetGLError()); |
+ } |
+ |
+ // Cleanup. |
+ EXPECT_CALL(*gl_, DeletePathsNV(kFirstCreatedServiceID, kPathCount)) |
+ .RetiresOnSaturation(); |
+ |
+ cmds::DeletePathsCHROMIUM delete_cmd; |
+ delete_cmd.Init(kFirstClientID, kPathCount); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(delete_cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, StencilFillPathCHROMIUM) { |
+ SetupExpectationsForApplyingDefaultDirtyState(); |
+ |
+ cmds::StencilFillPathCHROMIUM cmd; |
+ cmds::StencilThenCoverFillPathCHROMIUM tcmd; |
+ |
+ static const GLenum kFillModes[] = { |
+ GL_INVERT, GL_COUNT_UP_CHROMIUM, GL_COUNT_DOWN_CHROMIUM}; |
+ static const GLuint kMask = 0x7F; |
+ |
+ for (auto& fill_mode : kFillModes) { |
+ EXPECT_CALL(*gl_, StencilFillPathNV(kServicePathId, fill_mode, kMask)) |
+ .RetiresOnSaturation(); |
+ cmd.Init(client_path_id_, fill_mode, kMask); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, StencilThenCoverFillPathNV(kServicePathId, fill_mode, |
+ kMask, GL_BOUNDING_BOX_NV)) |
+ .RetiresOnSaturation(); |
+ tcmd.Init(client_path_id_, fill_mode, kMask, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ } |
+ |
+ // Non-existent path: no error, no call. |
+ cmd.Init(client_path_id_ - 1, GL_INVERT, 0x80); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ tcmd.Init(client_path_id_ - 1, GL_INVERT, 0x80, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
+ StencilFillPathCHROMIUMInvalidArgs) { |
+ EXPECT_CALL(*gl_, StencilFillPathNV(_, _, _)).Times(0); |
+ EXPECT_CALL(*gl_, StencilThenCoverFillPathNV(_, _, _, GL_BOUNDING_BOX_NV)) |
+ .Times(0); |
+ |
+ cmds::StencilFillPathCHROMIUM cmd; |
+ cmds::StencilThenCoverFillPathCHROMIUM tcmd; |
+ |
+ cmd.Init(client_path_id_, GL_INVERT - 1, 0x80); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); |
+ |
+ tcmd.Init(client_path_id_, GL_INVERT - 1, 0x80, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); |
+ EXPECT_EQ(GL_INVALID_ENUM, GetGLError()); |
+ |
+ // The /mask/+1 is not power of two -> invalid value. |
+ cmd.Init(client_path_id_, GL_COUNT_UP_CHROMIUM, 0x80); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); |
+ |
+ tcmd.Init(client_path_id_, GL_COUNT_UP_CHROMIUM, 0x80, |
+ GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); |
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); |
+ |
+ cmd.Init(client_path_id_, GL_COUNT_DOWN_CHROMIUM, 5); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); |
+ |
+ tcmd.Init(client_path_id_, GL_COUNT_DOWN_CHROMIUM, 5, |
+ GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); |
+ EXPECT_EQ(GL_INVALID_VALUE, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, StencilStrokePathCHROMIUM) { |
+ SetupExpectationsForApplyingDefaultDirtyState(); |
+ |
+ EXPECT_CALL(*gl_, StencilStrokePathNV(kServicePathId, 1, 0x80)) |
+ .RetiresOnSaturation(); |
+ EXPECT_CALL(*gl_, StencilThenCoverStrokePathNV(kServicePathId, 1, 0x80, |
+ GL_BOUNDING_BOX_NV)) |
+ .RetiresOnSaturation(); |
+ |
+ cmds::StencilStrokePathCHROMIUM cmd; |
+ cmds::StencilThenCoverStrokePathCHROMIUM tcmd; |
+ |
+ cmd.Init(client_path_id_, 1, 0x80); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ tcmd.Init(client_path_id_, 1, 0x80, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, StencilThenCoverStrokePathNV(kServicePathId, 1, 0x80, |
+ GL_CONVEX_HULL_NV)) |
+ .RetiresOnSaturation(); |
+ |
+ tcmd.Init(client_path_id_, 1, 0x80, GL_CONVEX_HULL_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Non-existent path: no error, no call. |
+ cmd.Init(client_path_id_ - 1, 1, 0x80); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ tcmd.Init(client_path_id_ - 1, 1, 0x80, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(tcmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, CoverFillPathCHROMIUM) { |
+ SetupExpectationsForApplyingDefaultDirtyState(); |
+ |
+ EXPECT_CALL(*gl_, CoverFillPathNV(kServicePathId, GL_BOUNDING_BOX_NV)) |
+ .RetiresOnSaturation(); |
+ cmds::CoverFillPathCHROMIUM cmd; |
+ cmd.Init(client_path_id_, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, CoverFillPathNV(kServicePathId, GL_CONVEX_HULL_NV)) |
+ .RetiresOnSaturation(); |
+ cmd.Init(client_path_id_, GL_CONVEX_HULL_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Non-existent path: no error, no call. |
+ cmd.Init(client_path_id_ - 1, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, CoverStrokePathCHROMIUM) { |
+ SetupExpectationsForApplyingDefaultDirtyState(); |
+ EXPECT_CALL(*gl_, CoverStrokePathNV(kServicePathId, GL_BOUNDING_BOX_NV)) |
+ .RetiresOnSaturation(); |
+ cmds::CoverStrokePathCHROMIUM cmd; |
+ cmd.Init(client_path_id_, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ EXPECT_CALL(*gl_, CoverStrokePathNV(kServicePathId, GL_CONVEX_HULL_NV)) |
+ .RetiresOnSaturation(); |
+ cmd.Init(client_path_id_, GL_CONVEX_HULL_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+ |
+ // Non-existent path: no error, no call. |
+ cmd.Init(client_path_id_ - 1, GL_BOUNDING_BOX_CHROMIUM); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+namespace { |
+template <typename T> |
+struct gl_type_enum {}; |
+template <> |
+struct gl_type_enum<GLbyte> { |
+ enum { kGLType = GL_BYTE }; |
+}; |
+template <> |
+struct gl_type_enum<GLubyte> { |
+ enum { kGLType = GL_UNSIGNED_BYTE }; |
+}; |
+template <> |
+struct gl_type_enum<GLshort> { |
+ enum { kGLType = GL_SHORT }; |
+}; |
+template <> |
+struct gl_type_enum<GLushort> { |
+ enum { kGLType = GL_UNSIGNED_SHORT }; |
+}; |
+template <> |
+struct gl_type_enum<GLfloat> { |
+ enum { kGLType = GL_FLOAT }; |
+}; |
+} |
+ |
+template <typename TypeParam> |
+void GLES2DecoderTestWithCHROMIUMPathRendering:: |
+ TestPathCommandsCHROMIUMCoordTypes() { |
+ static const GLsizei kCorrectCoordCount = 19; |
+ static const GLsizei kCorrectCommandCount = 6; |
+ |
+ TypeParam* coords = GetSharedMemoryAs<TypeParam*>(); |
+ unsigned commands_offset = sizeof(TypeParam) * kCorrectCoordCount; |
+ GLubyte* commands = GetSharedMemoryAsWithOffset<GLubyte*>(commands_offset); |
+ for (int i = 0; i < kCorrectCoordCount; ++i) { |
+ coords[i] = static_cast<TypeParam>(5 * i); |
+ } |
+ commands[0] = GL_MOVE_TO_CHROMIUM; |
+ commands[1] = GL_CLOSE_PATH_CHROMIUM; |
+ commands[2] = GL_LINE_TO_CHROMIUM; |
+ commands[3] = GL_QUADRATIC_CURVE_TO_CHROMIUM; |
+ commands[4] = GL_CUBIC_CURVE_TO_CHROMIUM; |
+ commands[5] = GL_CONIC_CURVE_TO_CHROMIUM; |
+ |
+ EXPECT_CALL(*gl_, PathCommandsNV(kServicePathId, kCorrectCommandCount, |
+ commands, kCorrectCoordCount, |
+ gl_type_enum<TypeParam>::kGLType, coords)) |
+ .RetiresOnSaturation(); |
+ |
+ cmds::PathCommandsCHROMIUM cmd; |
+ |
+ cmd.Init(client_path_id_, kCorrectCommandCount, shared_memory_id_, |
+ shared_memory_offset_ + commands_offset, kCorrectCoordCount, |
+ gl_type_enum<TypeParam>::kGLType, shared_memory_id_, |
+ shared_memory_offset_); |
+ EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
+ EXPECT_EQ(GL_NO_ERROR, GetGLError()); |
+} |
+ |
+TEST_P(GLES2DecoderTestWithCHROMIUMPathRendering, |
+ PathCommandsCHROMIUMCoordTypes) { |
+ // Not using a typed test case, because the base class is already parametrized |
+ // test case and uses GetParam. |
+ TestPathCommandsCHROMIUMCoordTypes<GLbyte>(); |
+ TestPathCommandsCHROMIUMCoordTypes<GLubyte>(); |
+ TestPathCommandsCHROMIUMCoordTypes<GLshort>(); |
+ TestPathCommandsCHROMIUMCoordTypes<GLushort>(); |
+ TestPathCommandsCHROMIUMCoordTypes<GLfloat>(); |
+} |
+ |
#include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_extensions_autogen.h" |
} // namespace gles2 |