OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 client_renderbuffer_id_(103), | 41 client_renderbuffer_id_(103), |
42 client_shader_id_(104), | 42 client_shader_id_(104), |
43 client_texture_id_(106), | 43 client_texture_id_(106), |
44 client_element_buffer_id_(107) { | 44 client_element_buffer_id_(107) { |
45 memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_)); | 45 memset(immediate_buffer_, 0xEE, sizeof(immediate_buffer_)); |
46 } | 46 } |
47 | 47 |
48 GLES2DecoderTestBase::~GLES2DecoderTestBase() {} | 48 GLES2DecoderTestBase::~GLES2DecoderTestBase() {} |
49 | 49 |
50 void GLES2DecoderTestBase::SetUp() { | 50 void GLES2DecoderTestBase::SetUp() { |
51 InitDecoder("", true, true, false, true, true, false); | 51 InitDecoder("", true); |
52 } | 52 } |
53 | 53 |
54 void GLES2DecoderTestBase::InitDecoder( | 54 void GLES2DecoderTestBase::InitDecoder( |
55 const char* extensions, | 55 const char* extensions, bool has_alpha_backbuffer) { |
56 bool has_alpha, | |
57 bool has_depth, | |
58 bool has_stencil, | |
59 bool request_alpha, | |
60 bool request_depth, | |
61 bool request_stencil) { | |
62 gl_.reset(new StrictMock<MockGLInterface>()); | 56 gl_.reset(new StrictMock<MockGLInterface>()); |
63 ::gfx::GLInterface::SetGLInterface(gl_.get()); | 57 ::gfx::GLInterface::SetGLInterface(gl_.get()); |
64 surface_manager_.reset(new StrictMock<MockSurfaceManager>); | 58 surface_manager_.reset(new StrictMock<MockSurfaceManager>); |
65 group_ = ContextGroup::Ref(new ContextGroup()); | 59 group_ = ContextGroup::Ref(new ContextGroup()); |
66 | 60 |
67 InSequence sequence; | 61 InSequence sequence; |
68 | 62 |
69 TestHelper::SetupContextGroupInitExpectations(gl_.get(), | 63 TestHelper::SetupContextGroupInitExpectations(gl_.get(), |
70 DisallowedExtensions(), extensions); | 64 DisallowedExtensions(), extensions); |
71 | 65 |
72 EXPECT_TRUE(group_->Initialize(DisallowedExtensions(), extensions)); | 66 EXPECT_TRUE(group_->Initialize(DisallowedExtensions(), extensions)); |
73 | 67 |
| 68 EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _)) |
| 69 .WillOnce(SetArgumentPointee<1>(has_alpha_backbuffer ? 8 : 0)) |
| 70 .RetiresOnSaturation(); |
74 EXPECT_CALL(*gl_, EnableVertexAttribArray(0)) | 71 EXPECT_CALL(*gl_, EnableVertexAttribArray(0)) |
75 .Times(1) | 72 .Times(1) |
76 .RetiresOnSaturation(); | 73 .RetiresOnSaturation(); |
77 static GLuint attrib_0_id[] = { | 74 static GLuint attrib_0_id[] = { |
78 kServiceAttrib0BufferId, | 75 kServiceAttrib0BufferId, |
79 }; | 76 }; |
80 static GLuint fixed_attrib_buffer_id[] = { | 77 static GLuint fixed_attrib_buffer_id[] = { |
81 kServiceFixedAttribBufferId, | 78 kServiceFixedAttribBufferId, |
82 }; | 79 }; |
83 EXPECT_CALL(*gl_, GenBuffersARB(arraysize(attrib_0_id), _)) | 80 EXPECT_CALL(*gl_, GenBuffersARB(arraysize(attrib_0_id), _)) |
(...skipping 25 matching lines...) Expand all Loading... |
109 .RetiresOnSaturation(); | 106 .RetiresOnSaturation(); |
110 EXPECT_CALL(*gl_, BindTexture( | 107 EXPECT_CALL(*gl_, BindTexture( |
111 GL_TEXTURE_2D, TestHelper::kServiceDefaultTexture2dId)) | 108 GL_TEXTURE_2D, TestHelper::kServiceDefaultTexture2dId)) |
112 .Times(1) | 109 .Times(1) |
113 .RetiresOnSaturation(); | 110 .RetiresOnSaturation(); |
114 } | 111 } |
115 EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) | 112 EXPECT_CALL(*gl_, ActiveTexture(GL_TEXTURE0)) |
116 .Times(1) | 113 .Times(1) |
117 .RetiresOnSaturation(); | 114 .RetiresOnSaturation(); |
118 | 115 |
119 EXPECT_CALL(*gl_, GetIntegerv(GL_ALPHA_BITS, _)) | |
120 .WillOnce(SetArgumentPointee<1>(has_alpha ? 8 : 0)) | |
121 .RetiresOnSaturation(); | |
122 EXPECT_CALL(*gl_, GetIntegerv(GL_DEPTH_BITS, _)) | |
123 .WillOnce(SetArgumentPointee<1>(has_depth ? 24 : 0)) | |
124 .RetiresOnSaturation(); | |
125 EXPECT_CALL(*gl_, GetIntegerv(GL_STENCIL_BITS, _)) | |
126 .WillOnce(SetArgumentPointee<1>(has_stencil ? 8 : 0)) | |
127 .RetiresOnSaturation(); | |
128 | |
129 EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE)) | 116 EXPECT_CALL(*gl_, Enable(GL_VERTEX_PROGRAM_POINT_SIZE)) |
130 .Times(1) | 117 .Times(1) |
131 .RetiresOnSaturation(); | 118 .RetiresOnSaturation(); |
132 | 119 |
133 EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE)) | 120 EXPECT_CALL(*gl_, Enable(GL_POINT_SPRITE)) |
134 .Times(1) | 121 .Times(1) |
135 .RetiresOnSaturation(); | 122 .RetiresOnSaturation(); |
136 | 123 |
137 engine_.reset(new StrictMock<MockCommandBufferEngine>()); | 124 engine_.reset(new StrictMock<MockCommandBufferEngine>()); |
138 Buffer buffer = engine_->GetSharedMemoryBuffer(kSharedMemoryId); | 125 Buffer buffer = engine_->GetSharedMemoryBuffer(kSharedMemoryId); |
139 shared_memory_offset_ = kSharedMemoryOffset; | 126 shared_memory_offset_ = kSharedMemoryOffset; |
140 shared_memory_address_ = reinterpret_cast<int8*>(buffer.ptr) + | 127 shared_memory_address_ = reinterpret_cast<int8*>(buffer.ptr) + |
141 shared_memory_offset_; | 128 shared_memory_offset_; |
142 shared_memory_id_ = kSharedMemoryId; | 129 shared_memory_id_ = kSharedMemoryId; |
143 shared_memory_base_ = buffer.ptr; | 130 shared_memory_base_ = buffer.ptr; |
144 | 131 |
145 surface_ = new gfx::GLSurfaceStub; | 132 surface_ = new gfx::GLSurfaceStub; |
146 surface_->SetSize(gfx::Size(kBackBufferWidth, kBackBufferHeight)); | 133 surface_->SetSize(gfx::Size(kBackBufferWidth, kBackBufferHeight)); |
147 | 134 |
148 context_ = new gfx::GLContextStub; | 135 context_ = new gfx::GLContextStub; |
149 | 136 |
150 // From <EGL/egl.h>. | |
151 const int32 EGL_ALPHA_SIZE = 0x3021; | |
152 const int32 EGL_DEPTH_SIZE = 0x3025; | |
153 const int32 EGL_STENCIL_SIZE = 0x3026; | |
154 | |
155 int32 attributes[] = { | |
156 EGL_ALPHA_SIZE, request_alpha ? 8 : 0, | |
157 EGL_DEPTH_SIZE, request_depth ? 24 : 0, | |
158 EGL_STENCIL_SIZE, request_stencil ? 8 : 0, | |
159 }; | |
160 std::vector<int32> attribs(attributes, attributes + arraysize(attributes)); | |
161 | |
162 decoder_.reset(GLES2Decoder::Create(surface_manager_.get(), group_.get())); | 137 decoder_.reset(GLES2Decoder::Create(surface_manager_.get(), group_.get())); |
163 decoder_->Initialize( | 138 decoder_->Initialize( |
164 surface_, context_, surface_->GetSize(), DisallowedExtensions(), | 139 surface_, context_, surface_->GetSize(), DisallowedExtensions(), |
165 NULL, attribs, NULL, 0); | 140 NULL, std::vector<int32>(), NULL, 0); |
166 decoder_->set_engine(engine_.get()); | 141 decoder_->set_engine(engine_.get()); |
167 | 142 |
168 EXPECT_CALL(*gl_, GenBuffersARB(_, _)) | 143 EXPECT_CALL(*gl_, GenBuffersARB(_, _)) |
169 .WillOnce(SetArgumentPointee<1>(kServiceBufferId)) | 144 .WillOnce(SetArgumentPointee<1>(kServiceBufferId)) |
170 .RetiresOnSaturation(); | 145 .RetiresOnSaturation(); |
171 GenHelper<GenBuffersImmediate>(client_buffer_id_); | 146 GenHelper<GenBuffersImmediate>(client_buffer_id_); |
172 EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)) | 147 EXPECT_CALL(*gl_, GenFramebuffersEXT(_, _)) |
173 .WillOnce(SetArgumentPointee<1>(kServiceFramebufferId)) | 148 .WillOnce(SetArgumentPointee<1>(kServiceFramebufferId)) |
174 .RetiresOnSaturation(); | 149 .RetiresOnSaturation(); |
175 GenHelper<GenFramebuffersImmediate>(client_framebuffer_id_); | 150 GenHelper<GenFramebuffersImmediate>(client_framebuffer_id_); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 ClearSharedMemory(); | 256 ClearSharedMemory(); |
282 } | 257 } |
283 } | 258 } |
284 | 259 |
285 void GLES2DecoderTestBase::SetupExpectationsForFramebufferAttachment( | 260 void GLES2DecoderTestBase::SetupExpectationsForFramebufferAttachment( |
286 GLuint clear_bits, | 261 GLuint clear_bits, |
287 GLclampf restore_red, | 262 GLclampf restore_red, |
288 GLclampf restore_green, | 263 GLclampf restore_green, |
289 GLclampf restore_blue, | 264 GLclampf restore_blue, |
290 GLclampf restore_alpha, | 265 GLclampf restore_alpha, |
| 266 GLuint restore_color_mask, |
291 GLuint restore_stencil, | 267 GLuint restore_stencil, |
| 268 GLuint restore_stencil_front_mask, |
| 269 GLuint restore_stencil_back_mask, |
292 GLclampf restore_depth, | 270 GLclampf restore_depth, |
| 271 GLboolean restore_depth_mask, |
293 bool restore_scissor_test) { | 272 bool restore_scissor_test) { |
294 InSequence sequence; | 273 InSequence sequence; |
295 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) | 274 EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER)) |
296 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) | 275 .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE)) |
297 .RetiresOnSaturation(); | 276 .RetiresOnSaturation(); |
298 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0) { | 277 if ((clear_bits & GL_COLOR_BUFFER_BIT) != 0) { |
299 EXPECT_CALL(*gl_, ClearColor(0, 0, 0, 0)) | 278 EXPECT_CALL(*gl_, ClearColor(0, 0, 0, 0)) |
300 .Times(1) | 279 .Times(1) |
301 .RetiresOnSaturation(); | 280 .RetiresOnSaturation(); |
302 EXPECT_CALL(*gl_, ColorMask(1, 1, 1, 1)) | 281 EXPECT_CALL(*gl_, ColorMask(1, 1, 1, 1)) |
(...skipping 19 matching lines...) Expand all Loading... |
322 EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST)) | 301 EXPECT_CALL(*gl_, Disable(GL_SCISSOR_TEST)) |
323 .Times(1) | 302 .Times(1) |
324 .RetiresOnSaturation(); | 303 .RetiresOnSaturation(); |
325 EXPECT_CALL(*gl_, Clear(clear_bits)) | 304 EXPECT_CALL(*gl_, Clear(clear_bits)) |
326 .Times(1) | 305 .Times(1) |
327 .RetiresOnSaturation(); | 306 .RetiresOnSaturation(); |
328 EXPECT_CALL(*gl_, ClearColor( | 307 EXPECT_CALL(*gl_, ClearColor( |
329 restore_red, restore_green, restore_blue, restore_alpha)) | 308 restore_red, restore_green, restore_blue, restore_alpha)) |
330 .Times(1) | 309 .Times(1) |
331 .RetiresOnSaturation(); | 310 .RetiresOnSaturation(); |
| 311 EXPECT_CALL(*gl_, ColorMask( |
| 312 ((restore_color_mask & 0x1000) != 0) ? 1 : 0, |
| 313 ((restore_color_mask & 0x0100) != 0) ? 1 : 0, |
| 314 ((restore_color_mask & 0x0010) != 0) ? 1 : 0, |
| 315 ((restore_color_mask & 0x0001) != 0) ? 1 : 0)) |
| 316 .Times(1) |
| 317 .RetiresOnSaturation(); |
332 EXPECT_CALL(*gl_, ClearStencil(restore_stencil)) | 318 EXPECT_CALL(*gl_, ClearStencil(restore_stencil)) |
333 .Times(1) | 319 .Times(1) |
334 .RetiresOnSaturation(); | 320 .RetiresOnSaturation(); |
| 321 EXPECT_CALL(*gl_, StencilMaskSeparate(GL_FRONT, restore_stencil_front_mask)) |
| 322 .Times(1) |
| 323 .RetiresOnSaturation(); |
| 324 EXPECT_CALL(*gl_, StencilMaskSeparate(GL_BACK, restore_stencil_back_mask)) |
| 325 .Times(1) |
| 326 .RetiresOnSaturation(); |
335 EXPECT_CALL(*gl_, ClearDepth(restore_depth)) | 327 EXPECT_CALL(*gl_, ClearDepth(restore_depth)) |
336 .Times(1) | 328 .Times(1) |
337 .RetiresOnSaturation(); | 329 .RetiresOnSaturation(); |
| 330 EXPECT_CALL(*gl_, DepthMask(restore_depth_mask)) |
| 331 .Times(1) |
| 332 .RetiresOnSaturation(); |
338 if (restore_scissor_test) { | 333 if (restore_scissor_test) { |
339 EXPECT_CALL(*gl_, Enable(GL_SCISSOR_TEST)) | 334 EXPECT_CALL(*gl_, Enable(GL_SCISSOR_TEST)) |
340 .Times(1) | 335 .Times(1) |
341 .RetiresOnSaturation(); | 336 .RetiresOnSaturation(); |
342 } | 337 } |
343 } | 338 } |
344 | 339 |
345 void GLES2DecoderTestBase::SetupShaderForUniform() { | 340 void GLES2DecoderTestBase::SetupShaderForUniform() { |
346 static AttribInfo attribs[] = { | 341 static AttribInfo attribs[] = { |
347 { "foo", 1, GL_FLOAT, 1, }, | 342 { "foo", 1, GL_FLOAT, 1, }, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 GLuint client_id, GLuint service_id) { | 379 GLuint client_id, GLuint service_id) { |
385 EXPECT_CALL(*gl_, DeleteBuffersARB(1, Pointee(service_id))) | 380 EXPECT_CALL(*gl_, DeleteBuffersARB(1, Pointee(service_id))) |
386 .Times(1) | 381 .Times(1) |
387 .RetiresOnSaturation(); | 382 .RetiresOnSaturation(); |
388 DeleteBuffers cmd; | 383 DeleteBuffers cmd; |
389 cmd.Init(1, shared_memory_id_, shared_memory_offset_); | 384 cmd.Init(1, shared_memory_id_, shared_memory_offset_); |
390 memcpy(shared_memory_address_, &client_id, sizeof(client_id)); | 385 memcpy(shared_memory_address_, &client_id, sizeof(client_id)); |
391 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 386 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
392 } | 387 } |
393 | 388 |
394 void GLES2DecoderTestBase::SetupExpectationsForApplyingDirtyState( | |
395 bool framebuffer_is_rgb, | |
396 bool framebuffer_has_depth, | |
397 bool framebuffer_has_stencil, | |
398 GLuint color_bits, | |
399 bool depth_mask, | |
400 GLuint front_stencil_mask, | |
401 GLuint back_stencil_mask) { | |
402 EXPECT_CALL(*gl_, ColorMask( | |
403 (color_bits & 0x1000) != 0, | |
404 (color_bits & 0x0100) != 0, | |
405 (color_bits & 0x0010) != 0, | |
406 (color_bits & 0x0001) && !framebuffer_is_rgb)) | |
407 .Times(1) | |
408 .RetiresOnSaturation(); | |
409 EXPECT_CALL(*gl_, DepthMask(depth_mask)) | |
410 .Times(1) | |
411 .RetiresOnSaturation(); | |
412 EXPECT_CALL(*gl_, StencilMaskSeparate(GL_FRONT, front_stencil_mask)) | |
413 .Times(1) | |
414 .RetiresOnSaturation(); | |
415 EXPECT_CALL(*gl_, StencilMaskSeparate(GL_BACK, back_stencil_mask)) | |
416 .Times(1) | |
417 .RetiresOnSaturation(); | |
418 } | |
419 | |
420 void GLES2DecoderTestBase::SetupExpectationsForApplyingDefaultDirtyState() { | |
421 SetupExpectationsForApplyingDirtyState( | |
422 false, // Framebuffer is RGB | |
423 false, // Framebuffer has depth | |
424 false, // Framebuffer has stencil | |
425 0x1111, // color bits | |
426 true, // depth mask | |
427 0, // front stencil mask | |
428 0); // back stencil mask | |
429 } | |
430 | |
431 void GLES2DecoderTestBase::DoBindFramebuffer( | 389 void GLES2DecoderTestBase::DoBindFramebuffer( |
432 GLenum target, GLuint client_id, GLuint service_id) { | 390 GLenum target, GLuint client_id, GLuint service_id) { |
433 EXPECT_CALL(*gl_, BindFramebufferEXT(target, service_id)) | 391 EXPECT_CALL(*gl_, BindFramebufferEXT(target, service_id)) |
434 .Times(1) | 392 .Times(1) |
435 .RetiresOnSaturation(); | 393 .RetiresOnSaturation(); |
436 BindFramebuffer cmd; | 394 BindFramebuffer cmd; |
437 cmd.Init(target, client_id); | 395 cmd.Init(target, client_id); |
438 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); | 396 EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); |
439 } | 397 } |
440 | 398 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 const uint32 GLES2DecoderTestBase::kNewClientId; | 528 const uint32 GLES2DecoderTestBase::kNewClientId; |
571 const uint32 GLES2DecoderTestBase::kNewServiceId; | 529 const uint32 GLES2DecoderTestBase::kNewServiceId; |
572 const uint32 GLES2DecoderTestBase::kInvalidClientId; | 530 const uint32 GLES2DecoderTestBase::kInvalidClientId; |
573 | 531 |
574 const int GLES2DecoderTestBase::kBackBufferWidth; | 532 const int GLES2DecoderTestBase::kBackBufferWidth; |
575 const int GLES2DecoderTestBase::kBackBufferHeight; | 533 const int GLES2DecoderTestBase::kBackBufferHeight; |
576 #endif | 534 #endif |
577 | 535 |
578 void GLES2DecoderWithShaderTestBase::SetUp() { | 536 void GLES2DecoderWithShaderTestBase::SetUp() { |
579 GLES2DecoderTestBase::SetUp(); | 537 GLES2DecoderTestBase::SetUp(); |
580 SetupDefaultProgram(); | |
581 } | |
582 | 538 |
583 void GLES2DecoderWithShaderTestBase::SetupDefaultProgram() { | |
584 { | 539 { |
585 static AttribInfo attribs[] = { | 540 static AttribInfo attribs[] = { |
586 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, }, | 541 { kAttrib1Name, kAttrib1Size, kAttrib1Type, kAttrib1Location, }, |
587 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, }, | 542 { kAttrib2Name, kAttrib2Size, kAttrib2Type, kAttrib2Location, }, |
588 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, }, | 543 { kAttrib3Name, kAttrib3Size, kAttrib3Type, kAttrib3Location, }, |
589 }; | 544 }; |
590 static UniformInfo uniforms[] = { | 545 static UniformInfo uniforms[] = { |
591 { kUniform1Name, kUniform1Size, kUniform1Type, kUniform1Location, }, | 546 { kUniform1Name, kUniform1Size, kUniform1Type, kUniform1Location, }, |
592 { kUniform2Name, kUniform2Size, kUniform2Type, kUniform2Location, }, | 547 { kUniform2Name, kUniform2Size, kUniform2Type, kUniform2Location, }, |
593 { kUniform3Name, kUniform3Size, kUniform3Type, kUniform3Location, }, | 548 { kUniform3Name, kUniform3Size, kUniform3Type, kUniform3Location, }, |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 | 807 |
853 const char* GLES2DecoderWithShaderTestBase::kAttrib1Name = "attrib1"; | 808 const char* GLES2DecoderWithShaderTestBase::kAttrib1Name = "attrib1"; |
854 const char* GLES2DecoderWithShaderTestBase::kAttrib2Name = "attrib2"; | 809 const char* GLES2DecoderWithShaderTestBase::kAttrib2Name = "attrib2"; |
855 const char* GLES2DecoderWithShaderTestBase::kAttrib3Name = "attrib3"; | 810 const char* GLES2DecoderWithShaderTestBase::kAttrib3Name = "attrib3"; |
856 const char* GLES2DecoderWithShaderTestBase::kUniform1Name = "uniform1"; | 811 const char* GLES2DecoderWithShaderTestBase::kUniform1Name = "uniform1"; |
857 const char* GLES2DecoderWithShaderTestBase::kUniform2Name = "uniform2[0]"; | 812 const char* GLES2DecoderWithShaderTestBase::kUniform2Name = "uniform2[0]"; |
858 const char* GLES2DecoderWithShaderTestBase::kUniform3Name = "uniform3[0]"; | 813 const char* GLES2DecoderWithShaderTestBase::kUniform3Name = "uniform3[0]"; |
859 | 814 |
860 } // namespace gles2 | 815 } // namespace gles2 |
861 } // namespace gpu | 816 } // namespace gpu |
OLD | NEW |