1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_BASE_H_
6 #define GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_BASE_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <array>
12 #include <initializer_list>
13 #include <memory>
14 #include <string>
15 #include <vector>
16 
17 #include "base/test/task_environment.h"
18 #include "components/viz/common/resources/resource_format.h"
19 #include "gpu/command_buffer/client/client_test_helper.h"
20 #include "gpu/command_buffer/common/raster_cmd_format.h"
21 #include "gpu/command_buffer/service/decoder_client.h"
22 #include "gpu/command_buffer/service/gl_context_mock.h"
23 #include "gpu/command_buffer/service/gpu_tracer.h"
24 #include "gpu/command_buffer/service/memory_tracking.h"
25 #include "gpu/command_buffer/service/raster_decoder.h"
26 #include "gpu/command_buffer/service/shared_image_manager.h"
27 #include "gpu/command_buffer/service/shared_image_representation.h"
28 #include "gpu/command_buffer/service/test_helper.h"
29 #include "gpu/config/gpu_driver_bug_workarounds.h"
30 #include "gpu/config/gpu_preferences.h"
31 #include "testing/gtest/include/gtest/gtest.h"
32 #include "ui/gl/gl_mock.h"
33 #include "ui/gl/gl_surface_stub.h"
34 #include "ui/gl/gl_version_info.h"
35 
36 namespace gpu {
37 
38 namespace gles2 {
39 class MockCopyTextureResourceManager;
40 }  // namespace gles2
41 
42 namespace raster {
43 
44 class RasterDecoderTestBase : public ::testing::TestWithParam<bool>,
45                               public DecoderClient {
46  public:
47   RasterDecoderTestBase();
48   ~RasterDecoderTestBase() override;
49 
50   void OnConsoleMessage(int32_t id, const std::string& message) override;
51   void CacheShader(const std::string& key, const std::string& shader) override;
52   void OnFenceSyncRelease(uint64_t release) override;
53   void OnDescheduleUntilFinished() override;
54   void OnRescheduleAfterFinished() override;
55   void OnSwapBuffers(uint64_t swap_id, uint32_t flags) override;
ScheduleGrContextCleanup()56   void ScheduleGrContextCleanup() override {}
HandleReturnData(base::span<const uint8_t> data)57   void HandleReturnData(base::span<const uint8_t> data) override {}
58 
59   // Template to call glGenXXX functions.
60   template <typename T>
GenHelper(GLuint client_id)61   void GenHelper(GLuint client_id) {
62     int8_t buffer[sizeof(T) + sizeof(client_id)];
63     T& cmd = *reinterpret_cast<T*>(&buffer);
64     cmd.Init(1, &client_id);
65     EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(client_id)));
66   }
67 
68   // This template exists solely so we can specialize it for
69   // certain commands.
70   template <typename T, int id>
SpecializedSetup(bool valid)71   void SpecializedSetup(bool valid) {}
72 
73   template <typename T>
GetImmediateAs()74   T* GetImmediateAs() {
75     return reinterpret_cast<T*>(immediate_buffer_);
76   }
77 
ClearSharedMemory()78   void ClearSharedMemory() {
79     memset(shared_memory_base_, kInitialMemoryValue, kSharedBufferSize);
80   }
81 
82   void SetUp() override;
83   void TearDown() override;
84 
85   template <typename T>
ExecuteCmd(const T & cmd)86   error::Error ExecuteCmd(const T& cmd) {
87     static_assert(T::kArgFlags == cmd::kFixed,
88                   "T::kArgFlags should equal cmd::kFixed");
89     int entries_processed = 0;
90     return decoder_->DoCommands(1, (const void*)&cmd,
91                                 ComputeNumEntries(sizeof(cmd)),
92                                 &entries_processed);
93   }
94 
95   template <typename T>
ExecuteImmediateCmd(const T & cmd,size_t data_size)96   error::Error ExecuteImmediateCmd(const T& cmd, size_t data_size) {
97     static_assert(T::kArgFlags == cmd::kAtLeastN,
98                   "T::kArgFlags should equal cmd::kAtLeastN");
99     int entries_processed = 0;
100     return decoder_->DoCommands(1, (const void*)&cmd,
101                                 ComputeNumEntries(sizeof(cmd) + data_size),
102                                 &entries_processed);
103   }
104 
105   template <typename T>
GetSharedMemoryAs()106   T GetSharedMemoryAs() {
107     return reinterpret_cast<T>(shared_memory_address_);
108   }
109 
110   template <typename T>
GetSharedMemoryAsWithOffset(uint32_t offset)111   T GetSharedMemoryAsWithOffset(uint32_t offset) {
112     void* ptr = reinterpret_cast<int8_t*>(shared_memory_address_) + offset;
113     return reinterpret_cast<T>(ptr);
114   }
115 
116   void SetBucketData(uint32_t bucket_id, const void* data, uint32_t data_size);
117   void SetBucketAsCString(uint32_t bucket_id, const char* str);
118   // If we want a valid bucket, just set |count_in_header| as |count|,
119   // and set |str_end| as 0.
120   void SetBucketAsCStrings(uint32_t bucket_id,
121                            GLsizei count,
122                            const char** str,
123                            GLsizei count_in_header,
124                            char str_end);
125 
126   void AddExpectationsForVertexAttribManager();
127   void AddExpectationsForBindVertexArrayOES();
128   void AddExpectationsForRestoreAttribState(GLuint attrib);
129 
130   struct InitState {
131     InitState();
132     ~InitState();
133 
134     std::vector<std::string> extensions = {"GL_ARB_sync"};
135     bool lose_context_when_out_of_memory = false;
136     gpu::GpuDriverBugWorkarounds workarounds;
137     std::string gl_version = "2.1";
138   };
139 
140   void InitDecoder(const InitState& init);
141   void ResetDecoder();
142 
GetContextLostReason()143   error::ContextLostReason GetContextLostReason() const {
144     return command_buffer_service_->GetState().context_lost_reason;
145   }
146 
GetGLMock()147   ::testing::StrictMock<::gl::MockGLInterface>* GetGLMock() const {
148     return gl_.get();
149   }
150 
GetDecoder()151   RasterDecoder* GetDecoder() const { return decoder_.get(); }
152 
153   typedef gles2::TestHelper::AttribInfo AttribInfo;
154   typedef gles2::TestHelper::UniformInfo UniformInfo;
155 
156   gpu::Mailbox CreateFakeTexture(GLuint service_id,
157                                  viz::ResourceFormat resource_format,
158                                  GLsizei width,
159                                  GLsizei height,
160                                  bool cleared);
161 
162   // Note that the error is returned as GLint instead of GLenum.
163   // This is because there is a mismatch in the types of GLenum and
164   // the error values GL_NO_ERROR, GL_INVALID_ENUM, etc. GLenum is
165   // typedef'd as unsigned int while the error values are defined as
166   // integers. This is problematic for template functions such as
167   // EXPECT_EQ that expect both types to be the same.
168   GLint GetGLError();
169 
170   void SetScopedTextureBinderExpectations(GLenum target);
171 
172   void SetupClearTextureExpectations(GLuint service_id,
173                                      GLuint old_service_id,
174                                      GLenum bind_target,
175                                      GLenum target,
176                                      GLint level,
177                                      GLenum format,
178                                      GLenum type,
179                                      GLint xoffset,
180                                      GLint yoffset,
181                                      GLsizei width,
182                                      GLsizei height,
183                                      GLuint bound_pixel_unpack_buffer);
184 
BufferOffset(unsigned i)185   GLvoid* BufferOffset(unsigned i) { return reinterpret_cast<GLvoid*>(i); }
186 
shared_image_manager()187   SharedImageManager* shared_image_manager() { return &shared_image_manager_; }
feature_info()188   gles2::FeatureInfo* feature_info() { return feature_info_.get(); }
189 
190  protected:
191   static const GLint kMaxTextureSize = 2048;
192   static const GLint kNumTextureUnits = 8;
193   static const GLint kNumVertexAttribs = 16;
194 
195   static const GLuint kServiceBufferId = 301;
196   static const GLuint kServiceTextureId = 304;
197   static const GLuint kServiceVertexArrayId = 310;
198 
199   static const size_t kSharedBufferSize = 2048;
200   static const uint32_t kSharedMemoryOffset = 132;
201   static const int32_t kInvalidSharedMemoryId =
202       FakeCommandBufferServiceBase::kTransferBufferBaseId - 1;
203   static const uint32_t kInvalidSharedMemoryOffset = kSharedBufferSize + 1;
204   static const uint32_t kInitialResult = 0xBDBDBDBDu;
205   static const uint8_t kInitialMemoryValue = 0xBDu;
206 
207   static const uint32_t kNewClientId = 501;
208   static const uint32_t kNewServiceId = 502;
209   static const uint32_t kInvalidClientId = 601;
210 
211   // Use StrictMock to make 100% sure we know how GL will be called.
212   std::unique_ptr<::testing::StrictMock<::gl::MockGLInterface>> gl_;
213   scoped_refptr<gles2::FeatureInfo> feature_info_;
214   scoped_refptr<gl::GLSurfaceStub> surface_;
215   scoped_refptr<GLContextMock> context_;
216   std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
217   gles2::TraceOutputter outputter_;
218   std::unique_ptr<RasterDecoder> decoder_;
219 
220   gpu::Mailbox client_texture_mailbox_;
221 
222   int32_t shared_memory_id_;
223   uint32_t shared_memory_offset_;
224   void* shared_memory_address_;
225   void* shared_memory_base_;
226 
227   uint32_t immediate_buffer_[64];
228 
229   const bool ignore_cached_state_for_test_;
230   scoped_refptr<SharedContextState> shared_context_state_;
231 
232  private:
233   GpuPreferences gpu_preferences_;
234   SharedImageManager shared_image_manager_;
235   MemoryTypeTracker memory_tracker_;
236   std::vector<std::unique_ptr<SharedImageRepresentationFactoryRef>>
237       shared_images_;
238   base::test::SingleThreadTaskEnvironment task_environment_;
239   gles2::MockCopyTextureResourceManager* copy_texture_manager_;  // not owned
240   GLuint next_fake_texture_client_id_ = 271828;
241 };
242 
243 class RasterDecoderManualInitTest : public RasterDecoderTestBase {
244  public:
245   RasterDecoderManualInitTest() = default;
246 
247   // Override default setup so nothing gets setup.
SetUp()248   void SetUp() override {}
249 };
250 
251 }  // namespace raster
252 }  // namespace gpu
253 
254 #endif  // GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_UNITTEST_BASE_H_
255