| 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 | 11 |
| 12 namespace blink { | 12 namespace blink { |
| 13 | 13 |
| 14 enum { | 14 enum { |
| 15 InitialWidth = 100, | 15 InitialWidth = 100, |
| 16 InitialHeight = 100, | 16 InitialHeight = 100, |
| 17 AlternateHeight = 50, | 17 AlternateHeight = 50, |
| 18 }; | 18 }; |
| 19 | 19 |
| 20 class DrawingBufferForTests : public DrawingBuffer { | 20 class DrawingBufferForTests : public DrawingBuffer { |
| 21 public: | 21 public: |
| 22 static PassRefPtr<DrawingBufferForTests> create( | 22 static PassRefPtr<DrawingBufferForTests> create( |
| 23 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 23 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, |
| 24 DrawingBufferStateTracker* stateTracker, |
| 24 const IntSize& size, | 25 const IntSize& size, |
| 25 PreserveDrawingBuffer preserve) { | 26 PreserveDrawingBuffer preserve) { |
| 26 std::unique_ptr<Extensions3DUtil> extensionsUtil = | 27 std::unique_ptr<Extensions3DUtil> extensionsUtil = |
| 27 Extensions3DUtil::create(contextProvider->contextGL()); | 28 Extensions3DUtil::create(contextProvider->contextGL()); |
| 28 RefPtr<DrawingBufferForTests> drawingBuffer = | 29 RefPtr<DrawingBufferForTests> drawingBuffer = |
| 29 adoptRef(new DrawingBufferForTests( | 30 adoptRef(new DrawingBufferForTests(std::move(contextProvider), |
| 30 std::move(contextProvider), std::move(extensionsUtil), preserve)); | 31 std::move(extensionsUtil), |
| 32 stateTracker, 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 DrawingBufferStateTracker* stateTracker, |
| 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 stateTracker, |
| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 { |
| 105 public: | 109 public: |
| 106 void BindTexture(GLenum target, GLuint texture) override { | 110 void BindTexture(GLenum target, GLuint texture) override { |
| 107 if (target != m_boundTextureTarget && texture == 0) | 111 if (target == GL_TEXTURE_2D) |
| 108 return; | 112 m_state.activeTexture2DBinding = texture; |
| 113 m_boundTextures[target] = texture; |
| 114 } |
| 109 | 115 |
| 110 // For simplicity, only allow one target to ever be bound. | 116 void BindFramebuffer(GLenum target, GLuint framebuffer) override { |
| 111 ASSERT_TRUE(m_boundTextureTarget == 0 || target == m_boundTextureTarget); | 117 switch (target) { |
| 112 m_boundTextureTarget = target; | 118 case GL_FRAMEBUFFER: |
| 113 m_boundTexture = texture; | 119 m_state.drawFramebufferBinding = framebuffer; |
| 120 m_state.readFramebufferBinding = framebuffer; |
| 121 break; |
| 122 case GL_DRAW_FRAMEBUFFER: |
| 123 m_state.drawFramebufferBinding = framebuffer; |
| 124 break; |
| 125 case GL_READ_FRAMEBUFFER: |
| 126 m_state.readFramebufferBinding = framebuffer; |
| 127 break; |
| 128 default: |
| 129 break; |
| 130 } |
| 131 } |
| 132 |
| 133 void BindRenderbuffer(GLenum target, GLuint renderbuffer) override { |
| 134 m_state.renderbufferBinding = renderbuffer; |
| 135 } |
| 136 |
| 137 void Enable(GLenum cap) { |
| 138 if (cap == GL_SCISSOR_TEST) |
| 139 m_state.scissorEnabled = true; |
| 140 } |
| 141 |
| 142 void Disable(GLenum cap) { |
| 143 if (cap == GL_SCISSOR_TEST) |
| 144 m_state.scissorEnabled = false; |
| 145 } |
| 146 |
| 147 void ClearColor(GLfloat red, |
| 148 GLfloat green, |
| 149 GLfloat blue, |
| 150 GLfloat alpha) override { |
| 151 m_state.clearColor[0] = red; |
| 152 m_state.clearColor[1] = green; |
| 153 m_state.clearColor[2] = blue; |
| 154 m_state.clearColor[3] = alpha; |
| 155 } |
| 156 |
| 157 void ClearDepthf(GLfloat depth) override { m_state.clearDepth = depth; } |
| 158 |
| 159 void ClearStencil(GLint s) override { m_state.clearStencil = s; } |
| 160 |
| 161 void ColorMask(GLboolean red, |
| 162 GLboolean green, |
| 163 GLboolean blue, |
| 164 GLboolean alpha) override { |
| 165 m_state.colorMask[0] = red; |
| 166 m_state.colorMask[1] = green; |
| 167 m_state.colorMask[2] = blue; |
| 168 m_state.colorMask[3] = alpha; |
| 169 } |
| 170 |
| 171 void DepthMask(GLboolean flag) override { m_state.depthMask = flag; } |
| 172 |
| 173 void StencilMask(GLuint mask) override { m_state.stencilMask = mask; } |
| 174 |
| 175 void StencilMaskSeparate(GLenum face, GLuint mask) override { |
| 176 if (face == GL_FRONT) |
| 177 m_state.stencilMask = mask; |
| 178 } |
| 179 |
| 180 void PixelStorei(GLenum pname, GLint param) override { |
| 181 if (pname == GL_PACK_ALIGNMENT) |
| 182 m_state.packAlignment = param; |
| 183 } |
| 184 |
| 185 void BindBuffer(GLenum target, GLuint buffer) override { |
| 186 if (target == GL_PIXEL_UNPACK_BUFFER) |
| 187 m_state.pixelUnpackBufferBinding = buffer; |
| 114 } | 188 } |
| 115 | 189 |
| 116 GLuint64 InsertFenceSyncCHROMIUM() override { | 190 GLuint64 InsertFenceSyncCHROMIUM() override { |
| 117 static GLuint64 syncPointGenerator = 0; | 191 static GLuint64 syncPointGenerator = 0; |
| 118 return ++syncPointGenerator; | 192 return ++syncPointGenerator; |
| 119 } | 193 } |
| 120 | 194 |
| 121 void WaitSyncTokenCHROMIUM(const GLbyte* syncToken) override { | 195 void WaitSyncTokenCHROMIUM(const GLbyte* syncToken) override { |
| 122 memcpy(&m_mostRecentlyWaitedSyncToken, syncToken, | 196 memcpy(&m_mostRecentlyWaitedSyncToken, syncToken, |
| 123 sizeof(m_mostRecentlyWaitedSyncToken)); | 197 sizeof(m_mostRecentlyWaitedSyncToken)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 151 void TexImage2D(GLenum target, | 225 void TexImage2D(GLenum target, |
| 152 GLint level, | 226 GLint level, |
| 153 GLint internalformat, | 227 GLint internalformat, |
| 154 GLsizei width, | 228 GLsizei width, |
| 155 GLsizei height, | 229 GLsizei height, |
| 156 GLint border, | 230 GLint border, |
| 157 GLenum format, | 231 GLenum format, |
| 158 GLenum type, | 232 GLenum type, |
| 159 const void* pixels) override { | 233 const void* pixels) override { |
| 160 if (target == GL_TEXTURE_2D && !level) { | 234 if (target == GL_TEXTURE_2D && !level) { |
| 161 m_textureSizes.set(m_boundTexture, IntSize(width, height)); | 235 m_textureSizes.set(m_boundTextures[target], IntSize(width, height)); |
| 162 } | 236 } |
| 163 } | 237 } |
| 164 | 238 |
| 165 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width, | 239 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width, |
| 166 GLsizei height, | 240 GLsizei height, |
| 167 GLenum internalformat, | 241 GLenum internalformat, |
| 168 GLenum usage) override { | 242 GLenum usage) override { |
| 169 if (m_createImageChromiumFail) | 243 if (m_createImageChromiumFail) |
| 170 return 0; | 244 return 0; |
| 171 m_imageSizes.set(m_currentImageId, IntSize(width, height)); | 245 m_imageSizes.set(m_currentImageId, IntSize(width, height)); |
| 172 return m_currentImageId++; | 246 return m_currentImageId++; |
| 173 } | 247 } |
| 174 | 248 |
| 175 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); | 249 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); |
| 176 void DestroyImageCHROMIUM(GLuint imageId) { | 250 void DestroyImageCHROMIUM(GLuint imageId) { |
| 177 m_imageSizes.remove(imageId); | 251 m_imageSizes.remove(imageId); |
| 178 // No textures should be bound to this. | 252 // No textures should be bound to this. |
| 179 CHECK(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end()); | 253 CHECK(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end()); |
| 180 m_imageSizes.remove(imageId); | 254 m_imageSizes.remove(imageId); |
| 181 DestroyImageMock(imageId); | 255 DestroyImageMock(imageId); |
| 182 } | 256 } |
| 183 | 257 |
| 184 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); | 258 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); |
| 185 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { | 259 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) { |
| 186 if (target == imageCHROMIUMTextureTarget()) { | 260 if (target == imageCHROMIUMTextureTarget()) { |
| 187 m_textureSizes.set(m_boundTexture, m_imageSizes.find(imageId)->value); | 261 m_textureSizes.set(m_boundTextures[target], |
| 188 m_imageToTextureMap.set(imageId, m_boundTexture); | 262 m_imageSizes.find(imageId)->value); |
| 263 m_imageToTextureMap.set(imageId, m_boundTextures[target]); |
| 189 BindTexImage2DMock(imageId); | 264 BindTexImage2DMock(imageId); |
| 190 } | 265 } |
| 191 } | 266 } |
| 192 | 267 |
| 193 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); | 268 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); |
| 194 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { | 269 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) { |
| 195 if (target == imageCHROMIUMTextureTarget()) { | 270 if (target == imageCHROMIUMTextureTarget()) { |
| 196 m_imageSizes.set(m_currentImageId, IntSize()); | 271 m_imageSizes.set(m_currentImageId, IntSize()); |
| 197 m_imageToTextureMap.remove(imageId); | 272 m_imageToTextureMap.remove(imageId); |
| 198 ReleaseTexImage2DMock(imageId); | 273 ReleaseTexImage2DMock(imageId); |
| 199 } | 274 } |
| 200 } | 275 } |
| 201 | 276 |
| 202 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override { | 277 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override { |
| 203 static uint64_t uniqueId = 1; | 278 static uint64_t uniqueId = 1; |
| 204 gpu::SyncToken source(gpu::GPU_IO, 1, | 279 gpu::SyncToken source(gpu::GPU_IO, 1, |
| 205 gpu::CommandBufferId::FromUnsafeValue(uniqueId++), 2); | 280 gpu::CommandBufferId::FromUnsafeValue(uniqueId++), 2); |
| 206 memcpy(syncToken, &source, sizeof(source)); | 281 memcpy(syncToken, &source, sizeof(source)); |
| 207 } | 282 } |
| 208 | 283 |
| 209 void GenTextures(GLsizei n, GLuint* textures) override { | 284 void GenTextures(GLsizei n, GLuint* textures) override { |
| 210 static GLuint id = 1; | 285 static GLuint id = 1; |
| 211 for (GLsizei i = 0; i < n; ++i) | 286 for (GLsizei i = 0; i < n; ++i) |
| 212 textures[i] = id++; | 287 textures[i] = id++; |
| 213 } | 288 } |
| 214 | 289 |
| 215 GLuint boundTexture() const { return m_boundTexture; } | |
| 216 GLuint boundTextureTarget() const { return m_boundTextureTarget; } | |
| 217 gpu::SyncToken mostRecentlyWaitedSyncToken() const { | 290 gpu::SyncToken mostRecentlyWaitedSyncToken() const { |
| 218 return m_mostRecentlyWaitedSyncToken; | 291 return m_mostRecentlyWaitedSyncToken; |
| 219 } | 292 } |
| 220 GLuint nextImageIdToBeCreated() const { return m_currentImageId; } | 293 GLuint nextImageIdToBeCreated() const { return m_currentImageId; } |
| 221 IntSize mostRecentlyProducedSize() const { | 294 IntSize mostRecentlyProducedSize() const { |
| 222 return m_mostRecentlyProducedSize; | 295 return m_mostRecentlyProducedSize; |
| 223 } | 296 } |
| 224 | 297 |
| 225 void setCreateImageChromiumFail(bool fail) { | 298 void setCreateImageChromiumFail(bool fail) { |
| 226 m_createImageChromiumFail = fail; | 299 m_createImageChromiumFail = fail; |
| 227 } | 300 } |
| 228 | 301 |
| 302 const DrawingBufferRestoreState& getActualRestoreState() const { |
| 303 return m_state; |
| 304 } |
| 305 |
| 229 private: | 306 private: |
| 230 GLuint m_boundTexture = 0; | 307 std::map<GLenum, GLuint> m_boundTextures; |
| 231 GLuint m_boundTextureTarget = 0; | 308 |
| 309 // The actual state set by GL commands. This is compared against an |
| 310 // expected value. |
| 311 DrawingBufferRestoreState m_state; |
| 312 |
| 232 gpu::SyncToken m_mostRecentlyWaitedSyncToken; | 313 gpu::SyncToken m_mostRecentlyWaitedSyncToken; |
| 233 GLbyte m_currentMailboxByte = 0; | 314 GLbyte m_currentMailboxByte = 0; |
| 234 IntSize m_mostRecentlyProducedSize; | 315 IntSize m_mostRecentlyProducedSize; |
| 235 bool m_createImageChromiumFail = false; | 316 bool m_createImageChromiumFail = false; |
| 236 GLuint m_currentImageId = 1; | 317 GLuint m_currentImageId = 1; |
| 237 HashMap<GLuint, IntSize> m_textureSizes; | 318 HashMap<GLuint, IntSize> m_textureSizes; |
| 238 HashMap<GLuint, IntSize> m_imageSizes; | 319 HashMap<GLuint, IntSize> m_imageSizes; |
| 239 HashMap<GLuint, GLuint> m_imageToTextureMap; | 320 HashMap<GLuint, GLuint> m_imageToTextureMap; |
| 240 }; | 321 }; |
| 241 | 322 |
| 242 } // blink | 323 } // blink |
| OLD | NEW |