OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "gpu/command_buffer/common/capabilities.h" |
| 6 #include "platform/RuntimeEnabledFeatures.h" |
| 7 #include "platform/graphics/gpu/DrawingBuffer.h" |
| 8 #include "platform/graphics/gpu/Extensions3DUtil.h" |
| 9 #include "public/platform/WebGraphicsContext3DProvider.h" |
| 10 #include "testing/gmock/include/gmock/gmock.h" |
| 11 |
| 12 namespace blink { |
| 13 |
| 14 enum { |
| 15 InitialWidth = 100, |
| 16 InitialHeight = 100, |
| 17 AlternateHeight = 50, |
| 18 }; |
| 19 |
| 20 class DrawingBufferForTests : public DrawingBuffer { |
| 21 public: |
| 22 static PassRefPtr<DrawingBufferForTests> create(std::unique_ptr<WebGraphicsC
ontext3DProvider> contextProvider, const IntSize& size, PreserveDrawingBuffer pr
eserve) |
| 23 { |
| 24 std::unique_ptr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::cre
ate(contextProvider->contextGL()); |
| 25 RefPtr<DrawingBufferForTests> drawingBuffer = adoptRef(new DrawingBuffer
ForTests(std::move(contextProvider), std::move(extensionsUtil), preserve)); |
| 26 bool multisampleExtensionSupported = false; |
| 27 if (!drawingBuffer->initialize(size, multisampleExtensionSupported)) { |
| 28 drawingBuffer->beginDestruction(); |
| 29 return nullptr; |
| 30 } |
| 31 return drawingBuffer.release(); |
| 32 } |
| 33 |
| 34 DrawingBufferForTests(std::unique_ptr<WebGraphicsContext3DProvider> contextP
rovider, std::unique_ptr<Extensions3DUtil> extensionsUtil, PreserveDrawingBuffer
preserve) |
| 35 : DrawingBuffer(std::move(contextProvider), std::move(extensionsUtil), f
alse /* discardFramebufferSupported */, |
| 36 true /* wantAlphaChannel */, false /* premultipliedAlpha */, preserv
e, WebGL1, |
| 37 false /* wantDepth */, false /* wantStencil */) |
| 38 , m_live(0) |
| 39 { } |
| 40 |
| 41 ~DrawingBufferForTests() override |
| 42 { |
| 43 if (m_live) |
| 44 *m_live = false; |
| 45 } |
| 46 |
| 47 bool* m_live; |
| 48 |
| 49 int recycledBitmapCount() { return m_recycledBitmaps.size(); } |
| 50 }; |
| 51 |
| 52 class WebGraphicsContext3DProviderForTests : public WebGraphicsContext3DProvider
{ |
| 53 public: |
| 54 WebGraphicsContext3DProviderForTests(std::unique_ptr<gpu::gles2::GLES2Interf
ace> gl) |
| 55 : m_gl(std::move(gl)) |
| 56 { |
| 57 } |
| 58 |
| 59 gpu::gles2::GLES2Interface* contextGL() override { return m_gl.get(); } |
| 60 bool isSoftwareRendering() const override { return false; } |
| 61 |
| 62 // Not used by WebGL code. |
| 63 GrContext* grContext() override { return nullptr; } |
| 64 bool bindToCurrentThread() override { return false; } |
| 65 gpu::Capabilities getCapabilities() override { return gpu::Capabilities(); } |
| 66 void setLostContextCallback(WebClosure) {} |
| 67 void setErrorMessageCallback(WebFunction<void(const char*, int32_t id)>) {} |
| 68 |
| 69 private: |
| 70 std::unique_ptr<gpu::gles2::GLES2Interface> m_gl; |
| 71 }; |
| 72 |
| 73 // The target to use when binding a texture to a Chromium image. |
| 74 GLenum imageCHROMIUMTextureTarget() |
| 75 { |
| 76 #if OS(MACOSX) |
| 77 return GC3D_TEXTURE_RECTANGLE_ARB; |
| 78 #else |
| 79 return GL_TEXTURE_2D; |
| 80 #endif |
| 81 } |
| 82 |
| 83 // The target to use when preparing a mailbox texture. |
| 84 GLenum drawingBufferTextureTarget() |
| 85 { |
| 86 if (RuntimeEnabledFeatures::webGLImageChromiumEnabled()) |
| 87 return imageCHROMIUMTextureTarget(); |
| 88 return GL_TEXTURE_2D; |
| 89 } |
| 90 |
| 91 class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub { |
| 92 public: |
| 93 void BindTexture(GLenum target, GLuint texture) override |
| 94 { |
| 95 if (target != m_boundTextureTarget && texture == 0) |
| 96 return; |
| 97 |
| 98 // For simplicity, only allow one target to ever be bound. |
| 99 ASSERT_TRUE(m_boundTextureTarget == 0 || target == m_boundTextureTarget)
; |
| 100 m_boundTextureTarget = target; |
| 101 m_boundTexture = texture; |
| 102 } |
| 103 |
| 104 GLuint64 InsertFenceSyncCHROMIUM() override |
| 105 { |
| 106 static GLuint64 syncPointGenerator = 0; |
| 107 return ++syncPointGenerator; |
| 108 } |
| 109 |
| 110 void WaitSyncTokenCHROMIUM(const GLbyte* syncToken) override |
| 111 { |
| 112 memcpy(&m_mostRecentlyWaitedSyncToken, syncToken, sizeof(m_mostRecentlyW
aitedSyncToken)); |
| 113 } |
| 114 |
| 115 GLenum CheckFramebufferStatus(GLenum target) override |
| 116 { |
| 117 return GL_FRAMEBUFFER_COMPLETE; |
| 118 } |
| 119 |
| 120 void GetIntegerv(GLenum pname, GLint* value) override |
| 121 { |
| 122 if (pname == GL_MAX_TEXTURE_SIZE) |
| 123 *value = 1024; |
| 124 } |
| 125 |
| 126 void GenMailboxCHROMIUM(GLbyte* mailbox) override |
| 127 { |
| 128 ++m_currentMailboxByte; |
| 129 memset(mailbox, m_currentMailboxByte, GL_MAILBOX_SIZE_CHROMIUM); |
| 130 } |
| 131 |
| 132 void ProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, const GLbyt
e* mailbox) override |
| 133 { |
| 134 ASSERT_EQ(target, drawingBufferTextureTarget()); |
| 135 |
| 136 if (!m_createImageChromiumFail) { |
| 137 ASSERT_TRUE(m_textureSizes.contains(texture)); |
| 138 m_mostRecentlyProducedSize = m_textureSizes.get(texture); |
| 139 } |
| 140 } |
| 141 |
| 142 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei wi
dth, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixel
s) override |
| 143 { |
| 144 if (target == GL_TEXTURE_2D && !level) { |
| 145 m_textureSizes.set(m_boundTexture, IntSize(width, height)); |
| 146 } |
| 147 } |
| 148 |
| 149 GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width, GLsizei height, GLe
num internalformat, GLenum usage) override |
| 150 { |
| 151 if (m_createImageChromiumFail) |
| 152 return 0; |
| 153 m_imageSizes.set(m_currentImageId, IntSize(width, height)); |
| 154 return m_currentImageId++; |
| 155 } |
| 156 |
| 157 MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); |
| 158 void DestroyImageCHROMIUM(GLuint imageId) |
| 159 { |
| 160 m_imageSizes.remove(imageId); |
| 161 // No textures should be bound to this. |
| 162 CHECK(m_imageToTextureMap.find(imageId) == m_imageToTextureMap.end()); |
| 163 m_imageSizes.remove(imageId); |
| 164 DestroyImageMock(imageId); |
| 165 } |
| 166 |
| 167 MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); |
| 168 void BindTexImage2DCHROMIUM(GLenum target, GLint imageId) |
| 169 { |
| 170 if (target == imageCHROMIUMTextureTarget()) { |
| 171 m_textureSizes.set(m_boundTexture, m_imageSizes.find(imageId)->value
); |
| 172 m_imageToTextureMap.set(imageId, m_boundTexture); |
| 173 BindTexImage2DMock(imageId); |
| 174 } |
| 175 } |
| 176 |
| 177 MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); |
| 178 void ReleaseTexImage2DCHROMIUM(GLenum target, GLint imageId) |
| 179 { |
| 180 if (target == imageCHROMIUMTextureTarget()) { |
| 181 m_imageSizes.set(m_currentImageId, IntSize()); |
| 182 m_imageToTextureMap.remove(imageId); |
| 183 ReleaseTexImage2DMock(imageId); |
| 184 } |
| 185 } |
| 186 |
| 187 void GenSyncTokenCHROMIUM(GLuint64 fenceSync, GLbyte* syncToken) override |
| 188 { |
| 189 static uint64_t uniqueId = 1; |
| 190 gpu::SyncToken source(gpu::GPU_IO, 1, gpu::CommandBufferId::FromUnsafeVa
lue(uniqueId++), 2); |
| 191 memcpy(syncToken, &source, sizeof(source)); |
| 192 } |
| 193 |
| 194 void GenTextures(GLsizei n, GLuint* textures) override |
| 195 { |
| 196 static GLuint id = 1; |
| 197 for (GLsizei i = 0; i < n; ++i) |
| 198 textures[i] = id++; |
| 199 } |
| 200 |
| 201 GLuint boundTexture() const { return m_boundTexture; } |
| 202 GLuint boundTextureTarget() const { return m_boundTextureTarget; } |
| 203 gpu::SyncToken mostRecentlyWaitedSyncToken() const { return m_mostRecentlyWa
itedSyncToken; } |
| 204 GLuint nextImageIdToBeCreated() const { return m_currentImageId; } |
| 205 IntSize mostRecentlyProducedSize() const { return m_mostRecentlyProducedSize
; } |
| 206 |
| 207 void setCreateImageChromiumFail(bool fail) { m_createImageChromiumFail = fai
l; } |
| 208 |
| 209 private: |
| 210 GLuint m_boundTexture = 0; |
| 211 GLuint m_boundTextureTarget = 0; |
| 212 gpu::SyncToken m_mostRecentlyWaitedSyncToken; |
| 213 GLbyte m_currentMailboxByte = 0; |
| 214 IntSize m_mostRecentlyProducedSize; |
| 215 bool m_createImageChromiumFail = false; |
| 216 GLuint m_currentImageId = 1; |
| 217 HashMap<GLuint, IntSize> m_textureSizes; |
| 218 HashMap<GLuint, IntSize> m_imageSizes; |
| 219 HashMap<GLuint, GLuint> m_imageToTextureMap; |
| 220 }; |
| 221 |
| 222 } // blink |
OLD | NEW |