| 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 #endif | 98 #endif |
| 95 } | 99 } |
| 96 | 100 |
| 97 // The target to use when preparing a mailbox texture. | 101 // The target to use when preparing a mailbox texture. |
| 98 GLenum drawingBufferTextureTarget() { | 102 GLenum drawingBufferTextureTarget() { |
| 99 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) | 103 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) |
| 100 return imageCHROMIUMTextureTarget(); | 104 return imageCHROMIUMTextureTarget(); |
| 101 return GL_TEXTURE_2D; | 105 return GL_TEXTURE_2D; |
| 102 } | 106 } |
| 103 | 107 |
| 104 class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { | 108 class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub, |
| 109 public DrawingBuffer::Client { |
| 105 public: | 110 public: |
| 111 // GLES2InterfaceStub implementation: |
| 106 void BindTexture(GLenum target, GLuint texture) override { | 112 void BindTexture(GLenum target, GLuint texture) override { |
| 107 if (target != m_boundTextureTarget && texture == 0) | 113 if (target == GL_TEXTURE_2D) |
| 108 return; | 114 m_state.activeTexture2DBinding = texture; |
| 115 m_boundTextures[target] = texture; |
| 116 } |
| 109 | 117 |
| 110 // For simplicity, only allow one target to ever be bound. | 118 void BindFramebuffer(GLenum target, GLuint framebuffer) override { |
| 111 ASSERT_TRUE(m_boundTextureTarget == 0 || target == m_boundTextureTarget); | 119 switch (target) { |
| 112 m_boundTextureTarget = target; | 120 case GL_FRAMEBUFFER: |
| 113 m_boundTexture = texture; | 121 m_state.drawFramebufferBinding = framebuffer; |
| 122 m_state.readFramebufferBinding = framebuffer; |
| 123 break; |
| 124 case GL_DRAW_FRAMEBUFFER: |
| 125 m_state.drawFramebufferBinding = framebuffer; |
| 126 break; |
| 127 case GL_READ_FRAMEBUFFER: |
| 128 m_state.readFramebufferBinding = framebuffer; |
| 129 break; |
| 130 default: |
| 131 break; |
| 132 } |
| 133 } |
| 134 |
| 135 void BindRenderbuffer(GLenum target, GLuint renderbuffer) override { |
| 136 m_state.renderbufferBinding = renderbuffer; |
| 137 } |
| 138 |
| 139 void Enable(GLenum cap) { |
| 140 if (cap == GL_SCISSOR_TEST) |
| 141 m_state.scissorEnabled = true; |
| 142 } |
| 143 |
| 144 void Disable(GLenum cap) { |
| 145 if (cap == GL_SCISSOR_TEST) |
| 146 m_state.scissorEnabled = false; |
| 147 } |
| 148 |
| 149 void ClearColor(GLfloat red, |
| 150 GLfloat green, |
| 151 GLfloat blue, |
| 152 GLfloat alpha) override { |
| 153 m_state.clearColor[0] = red; |
| 154 m_state.clearColor[1] = green; |
| 155 m_state.clearColor[2] = blue; |
| 156 m_state.clearColor[3] = alpha; |
| 157 } |
| 158 |
| 159 void ClearDepthf(GLfloat depth) override { m_state.clearDepth = depth; } |
| 160 |
| 161 void ClearStencil(GLint s) override { m_state.clearStencil = s; } |
| 162 |
| 163 void ColorMask(GLboolean red, |
| 164 GLboolean green, |
| 165 GLboolean blue, |
| 166 GLboolean alpha) override { |
| 167 m_state.colorMask[0] = red; |
| 168 m_state.colorMask[1] = green; |
| 169 m_state.colorMask[2] = blue; |
| 170 m_state.colorMask[3] = alpha; |
| 171 } |
| 172 |
| 173 void DepthMask(GLboolean flag) override { m_state.depthMask = flag; } |
| 174 |
| 175 void StencilMask(GLuint mask) override { m_state.stencilMask = mask; } |
| 176 |
| 177 void StencilMaskSeparate(GLenum face, GLuint mask) override { |
| 178 if (face == GL_FRONT) |
| 179 m_state.stencilMask = mask; |
| 180 } |
| 181 |
| 182 void PixelStorei(GLenum pname, GLint param) override { |
| 183 if (pname == GL_PACK_ALIGNMENT) |
| 184 m_state.packAlignment = param; |
| 185 } |
| 186 |
| 187 void BindBuffer(GLenum target, GLuint buffer) override { |
| 188 if (target == GL_PIXEL_UNPACK_BUFFER) |
| 189 m_state.pixelUnpackBufferBinding = buffer; |
| 114 } | 190 } |
| 115 | 191 |
| 116 GLuint64 InsertFenceSyncCHROMIUM() override { | 192 GLuint64 InsertFenceSyncCHROMIUM() override { |
| 117 static GLuint64 syncPointGenerator = 0; | 193 static GLuint64 syncPointGenerator = 0; |
| 118 return ++syncPointGenerator; | 194 return ++syncPointGenerator; |
| 119 } | 195 } |
| 120 | 196 |
| 121 void WaitSyncTokenCHROMIUM(const GLbyte* syncToken) override { | 197 void WaitSyncTokenCHROMIUM(const GLbyte* syncToken) override { |
| 122 memcpy(&m_mostRecentlyWaitedSyncToken, syncToken, | 198 memcpy(&m_mostRecentlyWaitedSyncToken, syncToken, |
| 123 sizeof(m_mostRecentlyWaitedSyncToken)); | 199 sizeof(m_mostRecentlyWaitedSyncToken)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 151 void TexImage2D(GLenum target, | 227 void TexImage2D(GLenum target, |
| 152 GLint level, | 228 GLint level, |
| 153 GLint internalformat, | 229 GLint internalformat, |
| 154 GLsizei width, | 230 GLsizei width, |
| 155 GLsizei height, | 231 GLsizei height, |
| 156 GLint border, | 232 GLint border, |
| 157 GLenum format, | 233 GLenum format, |
| 158 GLenum type, | 234 GLenum type, |
| 159 const void* pixels) override { | 235 const void* pixels) override { |
| 160 if (target == GL_TEXTURE_2D && !level) { | 236 if (target == GL_TEXTURE_2D && !level) { |
| 161 m_textureSizes.set(m_boundTexture, IntSize(width, height)); | 237 m_textureSizes.set(m_boundTextures[target], IntSize(width, height)); |
| 162 } | 238 } |
| 163 } | 239 } |
| 164 | 240 |
| 165 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width, | 241 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width, |
| 166 GLsizei height, | 242 GLsizei height, |
| 167 GLenum internalformat, | 243 GLenum internalformat, |
| 168 GLenum usage) override { | 244 GLenum usage) override { |
| 169 if (m_createImageChromiumFail) | 245 if (m_createImageChromiumFail) |
| 170 return 0; | 246 return 0; |
| 171 m_imageSizes.set(m_currentImageId, IntSize(width, height)); | 247 m_imageSizes.set(m_currentImageId, IntSize(width, height)); |
| 172 return m_currentImageId++; | 248 return m_currentImageId++; |
| 173 } | 249 } |
| 174 | 250 |
| 175 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); | 251 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); |
| 176 void DestroyImageCHROMIUM(GLuint imageId) { | 252 void DestroyImageCHROMIUM(GLuint imageId) { |
| 177 m_imageSizes.remove(imageId); | 253 m_imageSizes.remove(imageId); |
| 178 // No textures should be bound to this. | 254 // No textures should be bound to this. |
| 179 CHECK(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end()); | 255 CHECK(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end()); |
| 180 m_imageSizes.remove(imageId); | 256 m_imageSizes.remove(imageId); |
| 181 DestroyImageMock(imageId); | 257 DestroyImageMock(imageId); |
| 182 } | 258 } |
| 183 | 259 |
| 184 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); | 260 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); |
| 185 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { | 261 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { |
| 186 if (target == imageCHROMIUMTextureTarget()) { | 262 if (target == imageCHROMIUMTextureTarget()) { |
| 187 m_textureSizes.set(m_boundTexture, m_imageSizes.find(imageId)->value); | 263 m_textureSizes.set(m_boundTextures[target], |
| 188 m_imageToTextureMap.set(imageId, m_boundTexture); | 264 m_imageSizes.find(imageId)->value); |
| 265 m_imageToTextureMap.set(imageId, m_boundTextures[target]); |
| 189 BindTexImage2DMock(imageId); | 266 BindTexImage2DMock(imageId); |
| 190 } | 267 } |
| 191 } | 268 } |
| 192 | 269 |
| 193 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); | 270 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); |
| 194 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { | 271 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { |
| 195 if (target == imageCHROMIUMTextureTarget()) { | 272 if (target == imageCHROMIUMTextureTarget()) { |
| 196 m_imageSizes.set(m_currentImageId, IntSize()); | 273 m_imageSizes.set(m_currentImageId, IntSize()); |
| 197 m_imageToTextureMap.remove(imageId); | 274 m_imageToTextureMap.remove(imageId); |
| 198 ReleaseTexImage2DMock(imageId); | 275 ReleaseTexImage2DMock(imageId); |
| 199 } | 276 } |
| 200 } | 277 } |
| 201 | 278 |
| 202 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override { | 279 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override { |
| 203 static uint64_t uniqueId = 1; | 280 static uint64_t uniqueId = 1; |
| 204 gpu::SyncToken source(gpu::GPU_IO, 1, | 281 gpu::SyncToken source(gpu::GPU_IO, 1, |
| 205 gpu::CommandBufferId::FromUnsafeValue(uniqueId++), 2); | 282 gpu::CommandBufferId::FromUnsafeValue(uniqueId++), 2); |
| 206 memcpy(syncToken, &source, sizeof(source)); | 283 memcpy(syncToken, &source, sizeof(source)); |
| 207 } | 284 } |
| 208 | 285 |
| 209 void GenTextures(GLsizei n, GLuint* textures) override { | 286 void GenTextures(GLsizei n, GLuint* textures) override { |
| 210 static GLuint id = 1; | 287 static GLuint id = 1; |
| 211 for (GLsizei i = 0; i < n; ++i) | 288 for (GLsizei i = 0; i < n; ++i) |
| 212 textures[i] = id++; | 289 textures[i] = id++; |
| 213 } | 290 } |
| 214 | 291 |
| 215 GLuint boundTexture() const { return m_boundTexture; } | 292 // DrawingBuffer::Client implementation. |
| 216 GLuint boundTextureTarget() const { return m_boundTextureTarget; } | 293 bool DrawingBufferClientIsBoundForDraw() override { |
| 294 return !m_state.drawFramebufferBinding; |
| 295 } |
| 296 void DrawingBufferClientRestoreScissorTest() override { |
| 297 m_state.scissorEnabled = m_savedState.scissorEnabled; |
| 298 } |
| 299 void DrawingBufferClientRestoreMaskAndClearValues() override { |
| 300 memcpy(m_state.colorMask, m_savedState.colorMask, |
| 301 sizeof(m_state.colorMask)); |
| 302 m_state.clearDepth = m_savedState.clearDepth; |
| 303 m_state.clearStencil = m_savedState.clearStencil; |
| 304 |
| 305 memcpy(m_state.clearColor, m_savedState.clearColor, |
| 306 sizeof(m_state.clearColor)); |
| 307 m_state.depthMask = m_savedState.depthMask; |
| 308 m_state.stencilMask = m_savedState.stencilMask; |
| 309 } |
| 310 void DrawingBufferClientRestorePixelPackAlignment() override { |
| 311 m_state.packAlignment = m_savedState.packAlignment; |
| 312 } |
| 313 void DrawingBufferClientRestoreTexture2DBinding() override { |
| 314 m_state.activeTexture2DBinding = m_savedState.activeTexture2DBinding; |
| 315 } |
| 316 void DrawingBufferClientRestoreRenderbufferBinding() override { |
| 317 m_state.renderbufferBinding = m_savedState.renderbufferBinding; |
| 318 } |
| 319 void DrawingBufferClientRestoreFramebufferBinding() override { |
| 320 m_state.drawFramebufferBinding = m_savedState.drawFramebufferBinding; |
| 321 m_state.readFramebufferBinding = m_savedState.readFramebufferBinding; |
| 322 } |
| 323 void DrawingBufferClientRestorePixelUnpackBufferBinding() override { |
| 324 m_state.pixelUnpackBufferBinding = m_savedState.pixelUnpackBufferBinding; |
| 325 } |
| 326 |
| 327 // Testing methods. |
| 217 gpu::SyncToken mostRecentlyWaitedSyncToken() const { | 328 gpu::SyncToken mostRecentlyWaitedSyncToken() const { |
| 218 return m_mostRecentlyWaitedSyncToken; | 329 return m_mostRecentlyWaitedSyncToken; |
| 219 } | 330 } |
| 220 GLuint nextImageIdToBeCreated() const { return m_currentImageId; } | 331 GLuint nextImageIdToBeCreated() const { return m_currentImageId; } |
| 221 IntSize mostRecentlyProducedSize() const { | 332 IntSize mostRecentlyProducedSize() const { |
| 222 return m_mostRecentlyProducedSize; | 333 return m_mostRecentlyProducedSize; |
| 223 } | 334 } |
| 224 | 335 |
| 225 void setCreateImageChromiumFail(bool fail) { | 336 void setCreateImageChromiumFail(bool fail) { |
| 226 m_createImageChromiumFail = fail; | 337 m_createImageChromiumFail = fail; |
| 227 } | 338 } |
| 228 | 339 |
| 340 // Saves current GL state for later verification. |
| 341 void SaveState() { m_savedState = m_state; } |
| 342 void VeriyStateHasNotChangedSinceSave() const { |
| 343 for (size_t i = 0; i < 4; ++i) { |
| 344 EXPECT_EQ(m_state.clearColor[0], m_savedState.clearColor[0]); |
| 345 EXPECT_EQ(m_state.colorMask[0], m_savedState.colorMask[0]); |
| 346 } |
| 347 EXPECT_EQ(m_state.clearDepth, m_savedState.clearDepth); |
| 348 EXPECT_EQ(m_state.clearStencil, m_savedState.clearStencil); |
| 349 EXPECT_EQ(m_state.depthMask, m_savedState.depthMask); |
| 350 EXPECT_EQ(m_state.stencilMask, m_savedState.stencilMask); |
| 351 EXPECT_EQ(m_state.packAlignment, m_savedState.packAlignment); |
| 352 EXPECT_EQ(m_state.activeTexture2DBinding, |
| 353 m_savedState.activeTexture2DBinding); |
| 354 EXPECT_EQ(m_state.renderbufferBinding, m_savedState.renderbufferBinding); |
| 355 EXPECT_EQ(m_state.drawFramebufferBinding, |
| 356 m_savedState.drawFramebufferBinding); |
| 357 EXPECT_EQ(m_state.readFramebufferBinding, |
| 358 m_savedState.readFramebufferBinding); |
| 359 EXPECT_EQ(m_state.pixelUnpackBufferBinding, |
| 360 m_savedState.pixelUnpackBufferBinding); |
| 361 } |
| 362 |
| 229 private: | 363 private: |
| 230 GLuint m_boundTexture = 0; | 364 std::map<GLenum, GLuint> m_boundTextures; |
| 231 GLuint m_boundTextureTarget = 0; | 365 |
| 366 // State tracked to verify that it is restored correctly. |
| 367 struct State { |
| 368 bool scissorEnabled = false; |
| 369 |
| 370 GLfloat clearColor[4] = {0, 0, 0, 0}; |
| 371 GLfloat clearDepth = 0; |
| 372 GLint clearStencil = 0; |
| 373 |
| 374 GLboolean colorMask[4] = {0, 0, 0, 0}; |
| 375 GLboolean depthMask = 0; |
| 376 GLuint stencilMask = 0; |
| 377 |
| 378 GLint packAlignment = 4; |
| 379 |
| 380 // The bound 2D texture for the active texture unit. |
| 381 GLuint activeTexture2DBinding = 0; |
| 382 GLuint renderbufferBinding = 0; |
| 383 GLuint drawFramebufferBinding = 0; |
| 384 GLuint readFramebufferBinding = 0; |
| 385 GLuint pixelUnpackBufferBinding = 0; |
| 386 }; |
| 387 State m_state; |
| 388 State m_savedState; |
| 389 |
| 232 gpu::SyncToken m_mostRecentlyWaitedSyncToken; | 390 gpu::SyncToken m_mostRecentlyWaitedSyncToken; |
| 233 GLbyte m_currentMailboxByte = 0; | 391 GLbyte m_currentMailboxByte = 0; |
| 234 IntSize m_mostRecentlyProducedSize; | 392 IntSize m_mostRecentlyProducedSize; |
| 235 bool m_createImageChromiumFail = false; | 393 bool m_createImageChromiumFail = false; |
| 236 GLuint m_currentImageId = 1; | 394 GLuint m_currentImageId = 1; |
| 237 HashMap<GLuint, IntSize> m_textureSizes; | 395 HashMap<GLuint, IntSize> m_textureSizes; |
| 238 HashMap<GLuint, IntSize> m_imageSizes; | 396 HashMap<GLuint, IntSize> m_imageSizes; |
| 239 HashMap<GLuint, GLuint> m_imageToTextureMap; | 397 HashMap<GLuint, GLuint> m_imageToTextureMap; |
| 240 }; | 398 }; |
| 241 | 399 |
| 242 } // blink | 400 } // blink |
| OLD | NEW |