Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(507)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTestHelpers.h

Issue 2402273002: DrawingBuffer: Clean up GL state restoration (Closed)
Patch Set: Incorporate review feedback Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/common/capabilities.h" 5 #include "gpu/command_buffer/common/capabilities.h"
6 #include "platform/RuntimeEnabledFeatures.h" 6 #include "platform/RuntimeEnabledFeatures.h"
7 #include "platform/graphics/gpu/DrawingBuffer.h" 7 #include "platform/graphics/gpu/DrawingBuffer.h"
8 #include "platform/graphics/gpu/Extensions3DUtil.h" 8 #include "platform/graphics/gpu/Extensions3DUtil.h"
9 #include "public/platform/WebGraphicsContext3DProvider.h" 9 #include "public/platform/WebGraphicsContext3DProvider.h"
10 #include "testing/gmock/include/gmock/gmock.h" 10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
11 12
12 namespace blink { 13 namespace blink {
13 14
14 enum { 15 enum {
15 InitialWidth = 100, 16 InitialWidth = 100,
16 InitialHeight = 100, 17 InitialHeight = 100,
17 AlternateHeight = 50, 18 AlternateHeight = 50,
18 }; 19 };
19 20
20 class DrawingBufferForTests : public DrawingBuffer { 21 class DrawingBufferForTests : public DrawingBuffer {
21 public: 22 public:
22 static PassRefPtr<DrawingBufferForTests> create( 23 static PassRefPtr<DrawingBufferForTests> create(
23 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, 24 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
25 DrawingBuffer::Client* client,
24 const IntSize& size, 26 const IntSize& size,
25 PreserveDrawingBuffer preserve) { 27 PreserveDrawingBuffer preserve) {
26 std::unique_ptr<Extensions3DUtil> extensionsUtil = 28 std::unique_ptr<Extensions3DUtil> extensionsUtil =
27 Extensions3DUtil::create(contextProvider->contextGL()); 29 Extensions3DUtil::create(contextProvider->contextGL());
28 RefPtr<DrawingBufferForTests> drawingBuffer = 30 RefPtr<DrawingBufferForTests> drawingBuffer = adoptRef(
29 adoptRef(new DrawingBufferForTests( 31 new DrawingBufferForTests(std::move(contextProvider),
30 std::move(contextProvider), std::move(extensionsUtil), preserve)); 32 std::move(extensionsUtil), client, preserve));
31 bool multisampleExtensionSupported = false; 33 bool multisampleExtensionSupported = false;
32 if (!drawingBuffer->initialize(size, multisampleExtensionSupported)) { 34 if (!drawingBuffer->initialize(size, multisampleExtensionSupported)) {
33 drawingBuffer->beginDestruction(); 35 drawingBuffer->beginDestruction();
34 return nullptr; 36 return nullptr;
35 } 37 }
36 return drawingBuffer.release(); 38 return drawingBuffer.release();
37 } 39 }
38 40
39 DrawingBufferForTests( 41 DrawingBufferForTests(
40 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, 42 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
41 std::unique_ptr<Extensions3DUtil> extensionsUtil, 43 std::unique_ptr<Extensions3DUtil> extensionsUtil,
44 DrawingBuffer::Client* client,
42 PreserveDrawingBuffer preserve) 45 PreserveDrawingBuffer preserve)
43 : DrawingBuffer( 46 : DrawingBuffer(
44 std::move(contextProvider), 47 std::move(contextProvider),
45 std::move(extensionsUtil), 48 std::move(extensionsUtil),
49 client,
46 false /* discardFramebufferSupported */, 50 false /* discardFramebufferSupported */,
47 true /* wantAlphaChannel */, 51 true /* wantAlphaChannel */,
48 false /* premultipliedAlpha */, 52 false /* premultipliedAlpha */,
49 preserve, 53 preserve,
50 WebGL1, 54 WebGL1,
51 false /* wantDepth */, 55 false /* wantDepth */,
52 false /* wantStencil */, 56 false /* wantStencil */,
53 DrawingBuffer::AllowChromiumImage /* ChromiumImageUsage */), 57 DrawingBuffer::AllowChromiumImage /* ChromiumImageUsage */),
54 m_live(0) {} 58 m_live(0) {}
55 59
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 #endif 99 #endif
96 } 100 }
97 101
98 // The target to use when preparing a mailbox texture. 102 // The target to use when preparing a mailbox texture.
99 GLenum drawingBufferTextureTarget() { 103 GLenum drawingBufferTextureTarget() {
100 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) 104 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled())
101 return imageCHROMIUMTextureTarget(); 105 return imageCHROMIUMTextureTarget();
102 return GL_TEXTURE_2D; 106 return GL_TEXTURE_2D;
103 } 107 }
104 108
105 class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { 109 class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub,
110 public DrawingBuffer::Client {
106 public: 111 public:
112 // GLES2InterfaceStub implementation:
107 void BindTexture(GLenum target, GLuint texture) override { 113 void BindTexture(GLenum target, GLuint texture) override {
108 if (target != m_boundTextureTarget && texture == 0) 114 if (target == GL_TEXTURE_2D)
109 return; 115 m_state.activeTexture2DBinding = texture;
116 m_boundTextures[target] = texture;
117 }
110 118
111 // For simplicity, only allow one target to ever be bound. 119 void BindFramebuffer(GLenum target, GLuint framebuffer) override {
112 ASSERT_TRUE(m_boundTextureTarget == 0 || target == m_boundTextureTarget); 120 switch (target) {
113 m_boundTextureTarget = target; 121 case GL_FRAMEBUFFER:
114 m_boundTexture = texture; 122 m_state.drawFramebufferBinding = framebuffer;
123 m_state.readFramebufferBinding = framebuffer;
124 break;
125 case GL_DRAW_FRAMEBUFFER:
126 m_state.drawFramebufferBinding = framebuffer;
127 break;
128 case GL_READ_FRAMEBUFFER:
129 m_state.readFramebufferBinding = framebuffer;
130 break;
131 default:
132 break;
133 }
134 }
135
136 void BindRenderbuffer(GLenum target, GLuint renderbuffer) override {
137 m_state.renderbufferBinding = renderbuffer;
138 }
139
140 void Enable(GLenum cap) {
141 if (cap == GL_SCISSOR_TEST)
142 m_state.scissorEnabled = true;
143 }
144
145 void Disable(GLenum cap) {
146 if (cap == GL_SCISSOR_TEST)
147 m_state.scissorEnabled = false;
148 }
149
150 void ClearColor(GLfloat red,
151 GLfloat green,
152 GLfloat blue,
153 GLfloat alpha) override {
154 m_state.clearColor[0] = red;
155 m_state.clearColor[1] = green;
156 m_state.clearColor[2] = blue;
157 m_state.clearColor[3] = alpha;
158 }
159
160 void ClearDepthf(GLfloat depth) override { m_state.clearDepth = depth; }
161
162 void ClearStencil(GLint s) override { m_state.clearStencil = s; }
163
164 void ColorMask(GLboolean red,
165 GLboolean green,
166 GLboolean blue,
167 GLboolean alpha) override {
168 m_state.colorMask[0] = red;
169 m_state.colorMask[1] = green;
170 m_state.colorMask[2] = blue;
171 m_state.colorMask[3] = alpha;
172 }
173
174 void DepthMask(GLboolean flag) override { m_state.depthMask = flag; }
175
176 void StencilMask(GLuint mask) override { m_state.stencilMask = mask; }
177
178 void StencilMaskSeparate(GLenum face, GLuint mask) override {
179 if (face == GL_FRONT)
180 m_state.stencilMask = mask;
181 }
182
183 void PixelStorei(GLenum pname, GLint param) override {
184 if (pname == GL_PACK_ALIGNMENT)
185 m_state.packAlignment = param;
186 }
187
188 void BindBuffer(GLenum target, GLuint buffer) override {
189 if (target == GL_PIXEL_UNPACK_BUFFER)
190 m_state.pixelUnpackBufferBinding = buffer;
115 } 191 }
116 192
117 GLuint64 InsertFenceSyncCHROMIUM() override { 193 GLuint64 InsertFenceSyncCHROMIUM() override {
118 static GLuint64 syncPointGenerator = 0; 194 static GLuint64 syncPointGenerator = 0;
119 return ++syncPointGenerator; 195 return ++syncPointGenerator;
120 } 196 }
121 197
122 void WaitSyncTokenCHROMIUM(const GLbyte* syncToken) override { 198 void WaitSyncTokenCHROMIUM(const GLbyte* syncToken) override {
123 memcpy(&m_mostRecentlyWaitedSyncToken, syncToken, 199 memcpy(&m_mostRecentlyWaitedSyncToken, syncToken,
124 sizeof(m_mostRecentlyWaitedSyncToken)); 200 sizeof(m_mostRecentlyWaitedSyncToken));
(...skipping 27 matching lines...) Expand all
152 void TexImage2D(GLenum target, 228 void TexImage2D(GLenum target,
153 GLint level, 229 GLint level,
154 GLint internalformat, 230 GLint internalformat,
155 GLsizei width, 231 GLsizei width,
156 GLsizei height, 232 GLsizei height,
157 GLint border, 233 GLint border,
158 GLenum format, 234 GLenum format,
159 GLenum type, 235 GLenum type,
160 const void* pixels) override { 236 const void* pixels) override {
161 if (target == GL_TEXTURE_2D && !level) { 237 if (target == GL_TEXTURE_2D && !level) {
162 m_textureSizes.set(m_boundTexture, IntSize(width, height)); 238 m_textureSizes.set(m_boundTextures[target], IntSize(width, height));
163 } 239 }
164 } 240 }
165 241
166 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width, 242 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width,
167 GLsizei height, 243 GLsizei height,
168 GLenum internalformat, 244 GLenum internalformat,
169 GLenum usage) override { 245 GLenum usage) override {
170 if (m_createImageChromiumFail) 246 if (m_createImageChromiumFail)
171 return 0; 247 return 0;
172 m_imageSizes.set(m_currentImageId, IntSize(width, height)); 248 m_imageSizes.set(m_currentImageId, IntSize(width, height));
173 return m_currentImageId++; 249 return m_currentImageId++;
174 } 250 }
175 251
176 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); 252 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId));
177 void DestroyImageCHROMIUM(GLuint imageId) { 253 void DestroyImageCHROMIUM(GLuint imageId) {
178 m_imageSizes.remove(imageId); 254 m_imageSizes.remove(imageId);
179 // No textures should be bound to this. 255 // No textures should be bound to this.
180 CHECK(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end()); 256 CHECK(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end());
181 m_imageSizes.remove(imageId); 257 m_imageSizes.remove(imageId);
182 DestroyImageMock(imageId); 258 DestroyImageMock(imageId);
183 } 259 }
184 260
185 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); 261 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId));
186 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { 262 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) {
187 if (target == imageCHROMIUMTextureTarget()) { 263 if (target == imageCHROMIUMTextureTarget()) {
188 m_textureSizes.set(m_boundTexture, m_imageSizes.find(imageId)->value); 264 m_textureSizes.set(m_boundTextures[target],
189 m_imageToTextureMap.set(imageId, m_boundTexture); 265 m_imageSizes.find(imageId)->value);
266 m_imageToTextureMap.set(imageId, m_boundTextures[target]);
190 BindTexImage2DMock(imageId); 267 BindTexImage2DMock(imageId);
191 } 268 }
192 } 269 }
193 270
194 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); 271 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId));
195 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { 272 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) {
196 if (target == imageCHROMIUMTextureTarget()) { 273 if (target == imageCHROMIUMTextureTarget()) {
197 m_imageSizes.set(m_currentImageId, IntSize()); 274 m_imageSizes.set(m_currentImageId, IntSize());
198 m_imageToTextureMap.remove(imageId); 275 m_imageToTextureMap.remove(imageId);
199 ReleaseTexImage2DMock(imageId); 276 ReleaseTexImage2DMock(imageId);
200 } 277 }
201 } 278 }
202 279
203 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override { 280 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override {
204 static uint64_t uniqueId = 1; 281 static uint64_t uniqueId = 1;
205 gpu::SyncToken source(gpu::GPU_IO, 1, 282 gpu::SyncToken source(gpu::GPU_IO, 1,
206 gpu::CommandBufferId::FromUnsafeValue(uniqueId++), 2); 283 gpu::CommandBufferId::FromUnsafeValue(uniqueId++), 2);
207 memcpy(syncToken, &source, sizeof(source)); 284 memcpy(syncToken, &source, sizeof(source));
208 } 285 }
209 286
210 void GenTextures(GLsizei n, GLuint* textures) override { 287 void GenTextures(GLsizei n, GLuint* textures) override {
211 static GLuint id = 1; 288 static GLuint id = 1;
212 for (GLsizei i = 0; i < n; ++i) 289 for (GLsizei i = 0; i < n; ++i)
213 textures[i] = id++; 290 textures[i] = id++;
214 } 291 }
215 292
216 GLuint boundTexture() const { return m_boundTexture; } 293 // DrawingBuffer::Client implementation.
217 GLuint boundTextureTarget() const { return m_boundTextureTarget; } 294 bool DrawingBufferClientIsBoundForDraw() override {
295 return !m_state.drawFramebufferBinding;
296 }
297 void DrawingBufferClientRestoreScissorTest() override {
298 m_state.scissorEnabled = m_savedState.scissorEnabled;
299 }
300 void DrawingBufferClientRestoreMaskAndClearValues() override {
301 memcpy(m_state.colorMask, m_savedState.colorMask,
302 sizeof(m_state.colorMask));
303 m_state.clearDepth = m_savedState.clearDepth;
304 m_state.clearStencil = m_savedState.clearStencil;
305
306 memcpy(m_state.clearColor, m_savedState.clearColor,
307 sizeof(m_state.clearColor));
308 m_state.depthMask = m_savedState.depthMask;
309 m_state.stencilMask = m_savedState.stencilMask;
310 }
311 void DrawingBufferClientRestorePixelPackAlignment() override {
312 m_state.packAlignment = m_savedState.packAlignment;
313 }
314 void DrawingBufferClientRestoreTexture2DBinding() override {
315 m_state.activeTexture2DBinding = m_savedState.activeTexture2DBinding;
316 }
317 void DrawingBufferClientRestoreRenderbufferBinding() override {
318 m_state.renderbufferBinding = m_savedState.renderbufferBinding;
319 }
320 void DrawingBufferClientRestoreFramebufferBinding() override {
321 m_state.drawFramebufferBinding = m_savedState.drawFramebufferBinding;
322 m_state.readFramebufferBinding = m_savedState.readFramebufferBinding;
323 }
324 void DrawingBufferClientRestorePixelUnpackBufferBinding() override {
325 m_state.pixelUnpackBufferBinding = m_savedState.pixelUnpackBufferBinding;
326 }
327
328 // Testing methods.
218 gpu::SyncToken mostRecentlyWaitedSyncToken() const { 329 gpu::SyncToken mostRecentlyWaitedSyncToken() const {
219 return m_mostRecentlyWaitedSyncToken; 330 return m_mostRecentlyWaitedSyncToken;
220 } 331 }
221 GLuint nextImageIdToBeCreated() const { return m_currentImageId; } 332 GLuint nextImageIdToBeCreated() const { return m_currentImageId; }
222 IntSize mostRecentlyProducedSize() const { 333 IntSize mostRecentlyProducedSize() const {
223 return m_mostRecentlyProducedSize; 334 return m_mostRecentlyProducedSize;
224 } 335 }
225 336
226 void setCreateImageChromiumFail(bool fail) { 337 void setCreateImageChromiumFail(bool fail) {
227 m_createImageChromiumFail = fail; 338 m_createImageChromiumFail = fail;
228 } 339 }
229 340
341 // Saves current GL state for later verification.
342 void SaveState() { m_savedState = m_state; }
343 void VerifyStateHasNotChangedSinceSave() const {
344 for (size_t i = 0; i < 4; ++i) {
345 EXPECT_EQ(m_state.clearColor[0], m_savedState.clearColor[0]);
346 EXPECT_EQ(m_state.colorMask[0], m_savedState.colorMask[0]);
347 }
348 EXPECT_EQ(m_state.clearDepth, m_savedState.clearDepth);
349 EXPECT_EQ(m_state.clearStencil, m_savedState.clearStencil);
350 EXPECT_EQ(m_state.depthMask, m_savedState.depthMask);
351 EXPECT_EQ(m_state.stencilMask, m_savedState.stencilMask);
352 EXPECT_EQ(m_state.packAlignment, m_savedState.packAlignment);
353 EXPECT_EQ(m_state.activeTexture2DBinding,
354 m_savedState.activeTexture2DBinding);
355 EXPECT_EQ(m_state.renderbufferBinding, m_savedState.renderbufferBinding);
356 EXPECT_EQ(m_state.drawFramebufferBinding,
357 m_savedState.drawFramebufferBinding);
358 EXPECT_EQ(m_state.readFramebufferBinding,
359 m_savedState.readFramebufferBinding);
360 EXPECT_EQ(m_state.pixelUnpackBufferBinding,
361 m_savedState.pixelUnpackBufferBinding);
362 }
363
230 private: 364 private:
231 GLuint m_boundTexture = 0; 365 std::map<GLenum, GLuint> m_boundTextures;
232 GLuint m_boundTextureTarget = 0; 366
367 // State tracked to verify that it is restored correctly.
368 struct State {
369 bool scissorEnabled = false;
370
371 GLfloat clearColor[4] = {0, 0, 0, 0};
372 GLfloat clearDepth = 0;
373 GLint clearStencil = 0;
374
375 GLboolean colorMask[4] = {0, 0, 0, 0};
376 GLboolean depthMask = 0;
377 GLuint stencilMask = 0;
378
379 GLint packAlignment = 4;
380
381 // The bound 2D texture for the active texture unit.
382 GLuint activeTexture2DBinding = 0;
383 GLuint renderbufferBinding = 0;
384 GLuint drawFramebufferBinding = 0;
385 GLuint readFramebufferBinding = 0;
386 GLuint pixelUnpackBufferBinding = 0;
387 };
388 State m_state;
389 State m_savedState;
390
233 gpu::SyncToken m_mostRecentlyWaitedSyncToken; 391 gpu::SyncToken m_mostRecentlyWaitedSyncToken;
234 GLbyte m_currentMailboxByte = 0; 392 GLbyte m_currentMailboxByte = 0;
235 IntSize m_mostRecentlyProducedSize; 393 IntSize m_mostRecentlyProducedSize;
236 bool m_createImageChromiumFail = false; 394 bool m_createImageChromiumFail = false;
237 GLuint m_currentImageId = 1; 395 GLuint m_currentImageId = 1;
238 HashMap<GLuint, IntSize> m_textureSizes; 396 HashMap<GLuint, IntSize> m_textureSizes;
239 HashMap<GLuint, IntSize> m_imageSizes; 397 HashMap<GLuint, IntSize> m_imageSizes;
240 HashMap<GLuint, GLuint> m_imageToTextureMap; 398 HashMap<GLuint, GLuint> m_imageToTextureMap;
241 }; 399 };
242 400
243 } // blink 401 } // blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/DrawingBufferTest.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698