| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |