| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright (c) 2010, Google Inc. All rights reserved. | 2  * Copyright (c) 2010, Google Inc. All rights reserved. | 
| 3  * | 3  * | 
| 4  * Redistribution and use in source and binary forms, with or without | 4  * Redistribution and use in source and binary forms, with or without | 
| 5  * modification, are permitted provided that the following conditions are | 5  * modification, are permitted provided that the following conditions are | 
| 6  * met: | 6  * met: | 
| 7  * | 7  * | 
| 8  *     * Redistributions of source code must retain the above copyright | 8  *     * Redistributions of source code must retain the above copyright | 
| 9  * notice, this list of conditions and the following disclaimer. | 9  * notice, this list of conditions and the following disclaimer. | 
| 10  *     * Redistributions in binary form must reproduce the above | 10  *     * Redistributions in binary form must reproduce the above | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 53 #include "wtf/typed_arrays/ArrayBufferContents.h" | 53 #include "wtf/typed_arrays/ArrayBufferContents.h" | 
| 54 #include <algorithm> | 54 #include <algorithm> | 
| 55 #include <memory> | 55 #include <memory> | 
| 56 | 56 | 
| 57 namespace blink { | 57 namespace blink { | 
| 58 | 58 | 
| 59 namespace { | 59 namespace { | 
| 60 | 60 | 
| 61 const float s_resourceAdjustedRatio = 0.5; | 61 const float s_resourceAdjustedRatio = 0.5; | 
| 62 | 62 | 
| 63 class ScopedTextureUnit0BindingRestorer { |  | 
| 64   STACK_ALLOCATED(); |  | 
| 65   WTF_MAKE_NONCOPYABLE(ScopedTextureUnit0BindingRestorer); |  | 
| 66 |  | 
| 67  public: |  | 
| 68   ScopedTextureUnit0BindingRestorer(gpu::gles2::GLES2Interface* gl, |  | 
| 69                                     GLenum activeTextureUnit, |  | 
| 70                                     GLuint textureUnitZeroId) |  | 
| 71       : m_gl(gl), |  | 
| 72         m_oldActiveTextureUnit(activeTextureUnit), |  | 
| 73         m_oldTextureUnitZeroId(textureUnitZeroId) { |  | 
| 74     m_gl->ActiveTexture(GL_TEXTURE0); |  | 
| 75   } |  | 
| 76   ~ScopedTextureUnit0BindingRestorer() { |  | 
| 77     m_gl->BindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); |  | 
| 78     m_gl->ActiveTexture(m_oldActiveTextureUnit); |  | 
| 79   } |  | 
| 80 |  | 
| 81  private: |  | 
| 82   gpu::gles2::GLES2Interface* m_gl; |  | 
| 83   GLenum m_oldActiveTextureUnit; |  | 
| 84   GLuint m_oldTextureUnitZeroId; |  | 
| 85 }; |  | 
| 86 |  | 
| 87 static bool shouldFailDrawingBufferCreationForTesting = false; | 63 static bool shouldFailDrawingBufferCreationForTesting = false; | 
| 88 | 64 | 
| 89 }  // namespace | 65 }  // namespace | 
| 90 | 66 | 
| 91 PassRefPtr<DrawingBuffer> DrawingBuffer::create( | 67 PassRefPtr<DrawingBuffer> DrawingBuffer::create( | 
| 92     std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 68     std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 
|  | 69     DrawingBufferStateTracker* drawingBufferRestoreSource, | 
| 93     const IntSize& size, | 70     const IntSize& size, | 
| 94     bool premultipliedAlpha, | 71     bool premultipliedAlpha, | 
| 95     bool wantAlphaChannel, | 72     bool wantAlphaChannel, | 
| 96     bool wantDepthBuffer, | 73     bool wantDepthBuffer, | 
| 97     bool wantStencilBuffer, | 74     bool wantStencilBuffer, | 
| 98     bool wantAntialiasing, | 75     bool wantAntialiasing, | 
| 99     PreserveDrawingBuffer preserve, | 76     PreserveDrawingBuffer preserve, | 
| 100     WebGLVersion webGLVersion, | 77     WebGLVersion webGLVersion, | 
| 101     ChromiumImageUsage chromiumImageUsage) { | 78     ChromiumImageUsage chromiumImageUsage) { | 
| 102   ASSERT(contextProvider); | 79   ASSERT(contextProvider); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 130       extensionsUtil->ensureExtensionEnabled( | 107       extensionsUtil->ensureExtensionEnabled( | 
| 131           "GL_EXT_multisampled_render_to_texture"); | 108           "GL_EXT_multisampled_render_to_texture"); | 
| 132   } | 109   } | 
| 133   bool discardFramebufferSupported = | 110   bool discardFramebufferSupported = | 
| 134       extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer"); | 111       extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer"); | 
| 135   if (discardFramebufferSupported) | 112   if (discardFramebufferSupported) | 
| 136     extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); | 113     extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); | 
| 137 | 114 | 
| 138   RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer( | 115   RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer( | 
| 139       std::move(contextProvider), std::move(extensionsUtil), | 116       std::move(contextProvider), std::move(extensionsUtil), | 
| 140       discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha, | 117       drawingBufferRestoreSource, discardFramebufferSupported, wantAlphaChannel, | 
| 141       preserve, webGLVersion, wantDepthBuffer, wantStencilBuffer, | 118       premultipliedAlpha, preserve, webGLVersion, wantDepthBuffer, | 
| 142       chromiumImageUsage)); | 119       wantStencilBuffer, chromiumImageUsage)); | 
| 143   if (!drawingBuffer->initialize(size, multisampleSupported)) { | 120   if (!drawingBuffer->initialize(size, multisampleSupported)) { | 
| 144     drawingBuffer->beginDestruction(); | 121     drawingBuffer->beginDestruction(); | 
| 145     return PassRefPtr<DrawingBuffer>(); | 122     return PassRefPtr<DrawingBuffer>(); | 
| 146   } | 123   } | 
| 147   return drawingBuffer.release(); | 124   return drawingBuffer.release(); | 
| 148 } | 125 } | 
| 149 | 126 | 
| 150 void DrawingBuffer::forceNextDrawingBufferCreationToFail() { | 127 void DrawingBuffer::forceNextDrawingBufferCreationToFail() { | 
| 151   shouldFailDrawingBufferCreationForTesting = true; | 128   shouldFailDrawingBufferCreationForTesting = true; | 
| 152 } | 129 } | 
| 153 | 130 | 
| 154 DrawingBuffer::DrawingBuffer( | 131 DrawingBuffer::DrawingBuffer( | 
| 155     std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 132     std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 
| 156     std::unique_ptr<Extensions3DUtil> extensionsUtil, | 133     std::unique_ptr<Extensions3DUtil> extensionsUtil, | 
|  | 134     DrawingBufferStateTracker* stateTracker, | 
| 157     bool discardFramebufferSupported, | 135     bool discardFramebufferSupported, | 
| 158     bool wantAlphaChannel, | 136     bool wantAlphaChannel, | 
| 159     bool premultipliedAlpha, | 137     bool premultipliedAlpha, | 
| 160     PreserveDrawingBuffer preserve, | 138     PreserveDrawingBuffer preserve, | 
| 161     WebGLVersion webGLVersion, | 139     WebGLVersion webGLVersion, | 
| 162     bool wantDepth, | 140     bool wantDepth, | 
| 163     bool wantStencil, | 141     bool wantStencil, | 
| 164     ChromiumImageUsage chromiumImageUsage) | 142     ChromiumImageUsage chromiumImageUsage) | 
| 165     : m_preserveDrawingBuffer(preserve), | 143     : m_stateTracker(stateTracker), | 
|  | 144       m_preserveDrawingBuffer(preserve), | 
| 166       m_webGLVersion(webGLVersion), | 145       m_webGLVersion(webGLVersion), | 
| 167       m_contextProvider(std::move(contextProvider)), | 146       m_contextProvider(std::move(contextProvider)), | 
| 168       m_gl(m_contextProvider->contextGL()), | 147       m_gl(m_contextProvider->contextGL()), | 
| 169       m_extensionsUtil(std::move(extensionsUtil)), | 148       m_extensionsUtil(std::move(extensionsUtil)), | 
| 170       m_discardFramebufferSupported(discardFramebufferSupported), | 149       m_discardFramebufferSupported(discardFramebufferSupported), | 
| 171       m_wantAlphaChannel(wantAlphaChannel), | 150       m_wantAlphaChannel(wantAlphaChannel), | 
| 172       m_premultipliedAlpha(premultipliedAlpha), | 151       m_premultipliedAlpha(premultipliedAlpha), | 
| 173       m_softwareRendering(m_contextProvider->isSoftwareRendering()), | 152       m_softwareRendering(m_contextProvider->isSoftwareRendering()), | 
| 174       m_wantDepth(wantDepth), | 153       m_wantDepth(wantDepth), | 
| 175       m_wantStencil(wantStencil), | 154       m_wantStencil(wantStencil), | 
| 176       m_chromiumImageUsage(chromiumImageUsage) { | 155       m_chromiumImageUsage(chromiumImageUsage) { | 
| 177   memset(m_colorMask, 0, 4 * sizeof(GLboolean)); |  | 
| 178   memset(m_clearColor, 0, 4 * sizeof(GLfloat)); |  | 
| 179   // Used by browser tests to detect the use of a DrawingBuffer. | 156   // Used by browser tests to detect the use of a DrawingBuffer. | 
| 180   TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", | 157   TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", | 
| 181                        TRACE_EVENT_SCOPE_GLOBAL); | 158                        TRACE_EVENT_SCOPE_GLOBAL); | 
| 182 } | 159 } | 
| 183 | 160 | 
| 184 DrawingBuffer::~DrawingBuffer() { | 161 DrawingBuffer::~DrawingBuffer() { | 
| 185   DCHECK(m_destructionInProgress); | 162   DCHECK(m_destructionInProgress); | 
| 186   m_layer.reset(); | 163   m_layer.reset(); | 
| 187   m_contextProvider.reset(); | 164   m_contextProvider.reset(); | 
| 188 } | 165 } | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 210 | 187 | 
| 211 WebGraphicsContext3DProvider* DrawingBuffer::contextProvider() { | 188 WebGraphicsContext3DProvider* DrawingBuffer::contextProvider() { | 
| 212   return m_contextProvider.get(); | 189   return m_contextProvider.get(); | 
| 213 } | 190 } | 
| 214 | 191 | 
| 215 void DrawingBuffer::setIsHidden(bool hidden) { | 192 void DrawingBuffer::setIsHidden(bool hidden) { | 
| 216   if (m_isHidden == hidden) | 193   if (m_isHidden == hidden) | 
| 217     return; | 194     return; | 
| 218   m_isHidden = hidden; | 195   m_isHidden = hidden; | 
| 219   if (m_isHidden) | 196   if (m_isHidden) | 
| 220     m_recycledMailboxQueue.clear(); | 197     m_recycledColorBufferQueue.clear(); | 
| 221 } | 198 } | 
| 222 | 199 | 
| 223 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { | 200 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { | 
| 224   if (m_filterQuality != filterQuality) { | 201   if (m_filterQuality != filterQuality) { | 
| 225     m_filterQuality = filterQuality; | 202     m_filterQuality = filterQuality; | 
| 226     if (m_layer) | 203     if (m_layer) | 
| 227       m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); | 204       m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); | 
| 228   } | 205   } | 
| 229 } | 206 } | 
| 230 | 207 | 
| 231 bool DrawingBuffer::requiresAlphaChannelToBePreserved() { | 208 bool DrawingBuffer::requiresAlphaChannelToBePreserved() { | 
| 232   return !m_drawFramebufferBinding && | 209   DrawingBufferRestoreState restoreState; | 
|  | 210   m_stateTracker->GetDrawingBufferRestoreState(&restoreState); | 
|  | 211   return !restoreState.drawFramebufferBinding && | 
| 233          defaultBufferRequiresAlphaChannelToBePreserved(); | 212          defaultBufferRequiresAlphaChannelToBePreserved(); | 
| 234 } | 213 } | 
| 235 | 214 | 
| 236 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() { | 215 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() { | 
| 237   if (wantExplicitResolve()) { | 216   if (wantExplicitResolve()) { | 
| 238     return !m_wantAlphaChannel && | 217     return !m_wantAlphaChannel && | 
| 239            getMultisampledRenderbufferFormat() == GL_RGBA8_OES; | 218            getMultisampledRenderbufferFormat() == GL_RGBA8_OES; | 
| 240   } | 219   } | 
| 241 | 220 | 
| 242   bool rgbEmulation = | 221   bool rgbEmulation = | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 258     DCHECK(recycled.size == m_size); | 237     DCHECK(recycled.size == m_size); | 
| 259     return std::move(recycled.bitmap); | 238     return std::move(recycled.bitmap); | 
| 260   } | 239   } | 
| 261 | 240 | 
| 262   return Platform::current()->allocateSharedBitmap(m_size); | 241   return Platform::current()->allocateSharedBitmap(m_size); | 
| 263 } | 242 } | 
| 264 | 243 | 
| 265 bool DrawingBuffer::PrepareTextureMailbox( | 244 bool DrawingBuffer::PrepareTextureMailbox( | 
| 266     cc::TextureMailbox* outMailbox, | 245     cc::TextureMailbox* outMailbox, | 
| 267     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 246     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 
|  | 247   ScopedStateRestorer scopedStateRestorer(this); | 
| 268   bool forceGpuResult = false; | 248   bool forceGpuResult = false; | 
| 269   return prepareTextureMailboxInternal(outMailbox, outReleaseCallback, | 249   return prepareTextureMailboxInternal(outMailbox, outReleaseCallback, | 
| 270                                        forceGpuResult); | 250                                        forceGpuResult); | 
| 271 } | 251 } | 
| 272 | 252 | 
| 273 bool DrawingBuffer::prepareTextureMailboxInternal( | 253 bool DrawingBuffer::prepareTextureMailboxInternal( | 
| 274     cc::TextureMailbox* outMailbox, | 254     cc::TextureMailbox* outMailbox, | 
| 275     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, | 255     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, | 
| 276     bool forceGpuResult) { | 256     bool forceGpuResult) { | 
| 277   if (m_destructionInProgress) { | 257   if (m_destructionInProgress) { | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 292   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) | 272   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) | 
| 293     return false; | 273     return false; | 
| 294 | 274 | 
| 295   TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); | 275   TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); | 
| 296 | 276 | 
| 297   if (m_newMailboxCallback) | 277   if (m_newMailboxCallback) | 
| 298     (*m_newMailboxCallback)(); | 278     (*m_newMailboxCallback)(); | 
| 299 | 279 | 
| 300   // Resolve the multisampled buffer into m_backColorBuffer texture. | 280   // Resolve the multisampled buffer into m_backColorBuffer texture. | 
| 301   if (m_antiAliasingMode != None) | 281   if (m_antiAliasingMode != None) | 
| 302     commit(); | 282     resolveMultisampleFramebufferInternal(); | 
| 303 | 283 | 
| 304   if (m_softwareRendering && !forceGpuResult) { | 284   if (m_softwareRendering && !forceGpuResult) { | 
| 305     std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap(); | 285     return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback); | 
| 306     if (!bitmap) | 286   } else { | 
| 307       return false; | 287     return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback); | 
|  | 288   } | 
|  | 289 } | 
|  | 290 | 
|  | 291 bool DrawingBuffer::finishPrepareTextureMailboxSoftware( | 
|  | 292     cc::TextureMailbox* outMailbox, | 
|  | 293     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 
|  | 294   std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap(); | 
|  | 295   if (!bitmap) | 
|  | 296     return false; | 
|  | 297 | 
|  | 298   // Read the framebuffer into |bitmap|. | 
|  | 299   { | 
| 308     unsigned char* pixels = bitmap->pixels(); | 300     unsigned char* pixels = bitmap->pixels(); | 
| 309     DCHECK(pixels); | 301     DCHECK(pixels); | 
| 310 |  | 
| 311     bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha; | 302     bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha; | 
| 312     WebGLImageConversion::AlphaOp op = | 303     WebGLImageConversion::AlphaOp op = | 
| 313         needPremultiply ? WebGLImageConversion::AlphaDoPremultiply | 304         needPremultiply ? WebGLImageConversion::AlphaDoPremultiply | 
| 314                         : WebGLImageConversion::AlphaDoNothing; | 305                         : WebGLImageConversion::AlphaDoNothing; | 
| 315     readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSkia, | 306     readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSkia, | 
| 316                         op); | 307                         op); | 
| 317 |  | 
| 318     *outMailbox = cc::TextureMailbox(bitmap.get(), m_size); |  | 
| 319 |  | 
| 320     // This holds a ref on the DrawingBuffer that will keep it alive until the |  | 
| 321     // mailbox is released (and while the release callback is running). It also |  | 
| 322     // owns the SharedBitmap. |  | 
| 323     auto func = WTF::bind(&DrawingBuffer::softwareMailboxReleased, |  | 
| 324                           RefPtr<DrawingBuffer>(this), |  | 
| 325                           WTF::passed(std::move(bitmap)), m_size); |  | 
| 326     *outReleaseCallback = cc::SingleReleaseCallback::Create( |  | 
| 327         convertToBaseCallback(std::move(func))); |  | 
| 328     return true; |  | 
| 329   } | 308   } | 
| 330 | 309 | 
|  | 310   *outMailbox = cc::TextureMailbox(bitmap.get(), m_size); | 
|  | 311 | 
|  | 312   // This holds a ref on the DrawingBuffer that will keep it alive until the | 
|  | 313   // mailbox is released (and while the release callback is running). It also | 
|  | 314   // owns the SharedBitmap. | 
|  | 315   auto func = WTF::bind(&DrawingBuffer::mailboxReleasedSoftware, | 
|  | 316                         RefPtr<DrawingBuffer>(this), | 
|  | 317                         WTF::passed(std::move(bitmap)), m_size); | 
|  | 318   *outReleaseCallback = | 
|  | 319       cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); | 
|  | 320   return true; | 
|  | 321 } | 
|  | 322 | 
|  | 323 bool DrawingBuffer::finishPrepareTextureMailboxGpu( | 
|  | 324     cc::TextureMailbox* outMailbox, | 
|  | 325     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 
| 331   if (m_webGLVersion > WebGL1) { | 326   if (m_webGLVersion > WebGL1) { | 
|  | 327     m_stateRestorer->setPixelUnpackBufferBindingDirty(); | 
| 332     m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 328     m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 
| 333   } | 329   } | 
| 334 | 330 | 
| 335   // We must restore the texture binding since creating new textures, | 331   // Specify the buffer that we will put in the mailbox. | 
| 336   // consuming and producing mailboxes changes it. | 332   RefPtr<ColorBuffer> colorBufferForMailbox; | 
| 337   ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, |  | 
| 338                                              m_texture2DBinding); |  | 
| 339 |  | 
| 340   // First try to recycle an old buffer. |  | 
| 341   RefPtr<ColorBuffer> colorBufferForMailbox = takeRecycledMailbox(); |  | 
| 342 |  | 
| 343   // No buffer available to recycle, create a new one. |  | 
| 344   if (!colorBufferForMailbox) |  | 
| 345     colorBufferForMailbox = createTextureAndAllocateMemory(m_size); |  | 
| 346 |  | 
| 347   if (m_preserveDrawingBuffer == Discard) { | 333   if (m_preserveDrawingBuffer == Discard) { | 
| 348     std::swap(colorBufferForMailbox, m_backColorBuffer); | 334     // If we can discard the backbuffer, send the old backbuffer directly | 
|  | 335     // into the mailbox, and allocate (or recycle) a new backbuffer. | 
|  | 336     colorBufferForMailbox = m_backColorBuffer; | 
|  | 337     m_backColorBuffer = createOrRecycleColorBuffer(); | 
| 349     attachColorBufferToReadFramebuffer(); | 338     attachColorBufferToReadFramebuffer(); | 
| 350 | 339 | 
|  | 340     // Explicitly specify that m_fbo (which is now bound to the just-allocated | 
|  | 341     // m_backColorBuffer) is not initialized, to save GPU memory bandwidth for | 
|  | 342     // tile-based GPU architectures. | 
| 351     if (m_discardFramebufferSupported) { | 343     if (m_discardFramebufferSupported) { | 
| 352       // Explicitly discard the framebuffer to save GPU memory bandwidth for |  | 
| 353       // tile-based GPU arch. |  | 
| 354       const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, | 344       const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, | 
| 355                                      GL_STENCIL_ATTACHMENT}; | 345                                      GL_STENCIL_ATTACHMENT}; | 
|  | 346       m_stateRestorer->setFramebufferBindingDirty(); | 
| 356       m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 347       m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 357       m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); | 348       m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); | 
| 358     } | 349     } | 
| 359   } else { | 350   } else { | 
|  | 351     // If we can't discard the backbuffer, create (or recycle) a buffer to put | 
|  | 352     // in the mailbox, and copy backbuffer's contents there. | 
|  | 353     colorBufferForMailbox = createOrRecycleColorBuffer(); | 
| 360     m_gl->CopySubTextureCHROMIUM( | 354     m_gl->CopySubTextureCHROMIUM( | 
| 361         m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, | 355         m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, | 
| 362         0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); | 356         0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); | 
| 363   } | 357   } | 
| 364 | 358 | 
| 365   restoreFramebufferBindings(); | 359   // Put colorBufferForMailbox into its mailbox, and populate its | 
| 366   restorePixelUnpackBufferBindings(); | 360   // produceSyncToken with that point. | 
|  | 361   { | 
|  | 362     m_gl->ProduceTextureDirectCHROMIUM(colorBufferForMailbox->textureId, | 
|  | 363                                        colorBufferForMailbox->parameters.target, | 
|  | 364                                        colorBufferForMailbox->mailbox.name); | 
|  | 365     const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); | 
|  | 366 #if OS(MACOSX) | 
|  | 367     m_gl->DescheduleUntilFinishedCHROMIUM(); | 
|  | 368 #endif | 
|  | 369     m_gl->Flush(); | 
|  | 370     m_gl->GenSyncTokenCHROMIUM( | 
|  | 371         fenceSync, colorBufferForMailbox->produceSyncToken.GetData()); | 
|  | 372   } | 
|  | 373 | 
|  | 374   // Populate the output mailbox and callback. | 
|  | 375   { | 
|  | 376     bool isOverlayCandidate = colorBufferForMailbox->imageId != 0; | 
|  | 377     bool secureOutputOnly = false; | 
|  | 378     *outMailbox = cc::TextureMailbox( | 
|  | 379         colorBufferForMailbox->mailbox, colorBufferForMailbox->produceSyncToken, | 
|  | 380         colorBufferForMailbox->parameters.target, gfx::Size(m_size), | 
|  | 381         isOverlayCandidate, secureOutputOnly); | 
|  | 382 | 
|  | 383     // This holds a ref on the DrawingBuffer that will keep it alive until the | 
|  | 384     // mailbox is released (and while the release callback is running). | 
|  | 385     auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu, | 
|  | 386                           RefPtr<DrawingBuffer>(this), colorBufferForMailbox); | 
|  | 387     *outReleaseCallback = cc::SingleReleaseCallback::Create( | 
|  | 388         convertToBaseCallback(std::move(func))); | 
|  | 389   } | 
|  | 390 | 
|  | 391   // Point |m_frontColorBuffer| to the buffer that we are now presenting. | 
|  | 392   m_frontColorBuffer = colorBufferForMailbox; | 
|  | 393 | 
| 367   m_contentsChanged = false; | 394   m_contentsChanged = false; | 
| 368 |  | 
| 369   m_gl->ProduceTextureDirectCHROMIUM(colorBufferForMailbox->textureId, |  | 
| 370                                      colorBufferForMailbox->parameters.target, |  | 
| 371                                      colorBufferForMailbox->mailbox.name); |  | 
| 372   const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); |  | 
| 373 #if OS(MACOSX) |  | 
| 374   m_gl->DescheduleUntilFinishedCHROMIUM(); |  | 
| 375 #endif |  | 
| 376   m_gl->Flush(); |  | 
| 377   gpu::SyncToken syncToken; |  | 
| 378   m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); |  | 
| 379 |  | 
| 380   bool isOverlayCandidate = colorBufferForMailbox->imageId != 0; |  | 
| 381   bool secureOutputOnly = false; |  | 
| 382   *outMailbox = cc::TextureMailbox(colorBufferForMailbox->mailbox, syncToken, |  | 
| 383                                    colorBufferForMailbox->parameters.target, |  | 
| 384                                    gfx::Size(m_size.width(), m_size.height()), |  | 
| 385                                    isOverlayCandidate, secureOutputOnly); |  | 
| 386 |  | 
| 387   // This holds a ref on the DrawingBuffer that will keep it alive until the |  | 
| 388   // mailbox is released (and while the release callback is running). |  | 
| 389   auto func = WTF::bind(&DrawingBuffer::gpuMailboxReleased, |  | 
| 390                         RefPtr<DrawingBuffer>(this), colorBufferForMailbox); |  | 
| 391   *outReleaseCallback = |  | 
| 392       cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); |  | 
| 393 |  | 
| 394   // Point |m_frontColorBuffer| to the buffer that we are presenting, and |  | 
| 395   // update its sync token. |  | 
| 396   colorBufferForMailbox->produceSyncToken = syncToken; |  | 
| 397   m_frontColorBuffer = colorBufferForMailbox; |  | 
| 398   setBufferClearNeeded(true); | 395   setBufferClearNeeded(true); | 
| 399   return true; | 396   return true; | 
| 400 } | 397 } | 
| 401 | 398 | 
| 402 void DrawingBuffer::gpuMailboxReleased(RefPtr<ColorBuffer> colorBuffer, | 399 void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer, | 
| 403                                        const gpu::SyncToken& syncToken, | 400                                        const gpu::SyncToken& syncToken, | 
| 404                                        bool lostResource) { | 401                                        bool lostResource) { | 
| 405   // If the mailbox has been returned by the compositor then it is no | 402   // If the mailbox has been returned by the compositor then it is no | 
| 406   // longer being presented, and so is no longer the front buffer. | 403   // longer being presented, and so is no longer the front buffer. | 
| 407   if (colorBuffer == m_frontColorBuffer) | 404   if (colorBuffer == m_frontColorBuffer) | 
| 408     m_frontColorBuffer = nullptr; | 405     m_frontColorBuffer = nullptr; | 
| 409 | 406 | 
| 410   // Update the SyncToken to ensure that we will wait for it even if we | 407   // Update the SyncToken to ensure that we will wait for it even if we | 
| 411   // immediately destroy this buffer. | 408   // immediately destroy this buffer. | 
| 412   colorBuffer->receiveSyncToken = syncToken; | 409   colorBuffer->receiveSyncToken = syncToken; | 
| 413 | 410 | 
| 414   if (m_destructionInProgress || colorBuffer->size != m_size || | 411   if (m_destructionInProgress || colorBuffer->size != m_size || | 
| 415       m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource || | 412       m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource || | 
| 416       m_isHidden) { | 413       m_isHidden) { | 
| 417     return; | 414     return; | 
| 418   } | 415   } | 
| 419 | 416 | 
| 420   // Creation of image backed mailboxes is very expensive, so be less | 417   // Creation of image backed mailboxes is very expensive, so be less | 
| 421   // aggressive about pruning them. Pruning is done in FIFO order. | 418   // aggressive about pruning them. Pruning is done in FIFO order. | 
| 422   size_t cacheLimit = 1; | 419   size_t cacheLimit = 1; | 
| 423   if (shouldUseChromiumImage()) | 420   if (shouldUseChromiumImage()) | 
| 424     cacheLimit = 4; | 421     cacheLimit = 4; | 
| 425   while (m_recycledMailboxQueue.size() >= cacheLimit) | 422   while (m_recycledColorBufferQueue.size() >= cacheLimit) | 
| 426     m_recycledMailboxQueue.takeLast(); | 423     m_recycledColorBufferQueue.takeLast(); | 
| 427 | 424 | 
| 428   m_recycledMailboxQueue.prepend(colorBuffer); | 425   m_recycledColorBufferQueue.prepend(colorBuffer); | 
| 429 } | 426 } | 
| 430 | 427 | 
| 431 void DrawingBuffer::softwareMailboxReleased( | 428 void DrawingBuffer::mailboxReleasedSoftware( | 
| 432     std::unique_ptr<cc::SharedBitmap> bitmap, | 429     std::unique_ptr<cc::SharedBitmap> bitmap, | 
| 433     const IntSize& size, | 430     const IntSize& size, | 
| 434     const gpu::SyncToken& syncToken, | 431     const gpu::SyncToken& syncToken, | 
| 435     bool lostResource) { | 432     bool lostResource) { | 
| 436   DCHECK(!syncToken.HasData());  // No sync tokens for software resources. | 433   DCHECK(!syncToken.HasData());  // No sync tokens for software resources. | 
| 437   if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) | 434   if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) | 
| 438     return;  // Just delete the bitmap. | 435     return;  // Just delete the bitmap. | 
| 439 | 436 | 
| 440   RecycledBitmap recycled = {std::move(bitmap), m_size}; | 437   RecycledBitmap recycled = {std::move(bitmap), m_size}; | 
| 441   m_recycledBitmaps.append(std::move(recycled)); | 438   m_recycledBitmaps.append(std::move(recycled)); | 
| 442 } | 439 } | 
| 443 | 440 | 
| 444 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() { | 441 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() { | 
|  | 442   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 443 | 
| 445   // This can be null if the context is lost before the first call to | 444   // This can be null if the context is lost before the first call to | 
| 446   // grContext(). | 445   // grContext(). | 
| 447   GrContext* grContext = m_contextProvider->grContext(); | 446   GrContext* grContext = m_contextProvider->grContext(); | 
| 448 | 447 | 
| 449   cc::TextureMailbox textureMailbox; | 448   cc::TextureMailbox textureMailbox; | 
| 450   std::unique_ptr<cc::SingleReleaseCallback> releaseCallback; | 449   std::unique_ptr<cc::SingleReleaseCallback> releaseCallback; | 
| 451   bool success = false; | 450   bool success = false; | 
| 452   if (grContext) { | 451   if (grContext) { | 
| 453     bool forceGpuResult = true; | 452     bool forceGpuResult = true; | 
| 454     success = prepareTextureMailboxInternal(&textureMailbox, &releaseCallback, | 453     success = prepareTextureMailboxInternal(&textureMailbox, &releaseCallback, | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 507   // DrawingBuffer's context anyways. | 506   // DrawingBuffer's context anyways. | 
| 508   const auto& skImageSyncToken = textureMailbox.sync_token(); | 507   const auto& skImageSyncToken = textureMailbox.sync_token(); | 
| 509 | 508 | 
| 510   // TODO(xidachen): Create a small pool of recycled textures from | 509   // TODO(xidachen): Create a small pool of recycled textures from | 
| 511   // ImageBitmapRenderingContext's transferFromImageBitmap, and try to use them | 510   // ImageBitmapRenderingContext's transferFromImageBitmap, and try to use them | 
| 512   // in DrawingBuffer. | 511   // in DrawingBuffer. | 
| 513   return AcceleratedStaticBitmapImage::createFromWebGLContextImage( | 512   return AcceleratedStaticBitmapImage::createFromWebGLContextImage( | 
| 514       std::move(skImage), skImageMailbox, skImageSyncToken); | 513       std::move(skImage), skImageMailbox, skImageSyncToken); | 
| 515 } | 514 } | 
| 516 | 515 | 
| 517 DrawingBuffer::TextureParameters | 516 DrawingBuffer::ColorBufferParameters | 
| 518 DrawingBuffer::chromiumImageTextureParameters() { | 517 DrawingBuffer::gpuMemoryBufferColorBufferParameters() { | 
| 519 #if OS(MACOSX) | 518 #if OS(MACOSX) | 
| 520   // A CHROMIUM_image backed texture requires a specialized set of parameters | 519   // A CHROMIUM_image backed texture requires a specialized set of parameters | 
| 521   // on OSX. | 520   // on OSX. | 
| 522   TextureParameters parameters; | 521   ColorBufferParameters parameters; | 
| 523   parameters.target = GC3D_TEXTURE_RECTANGLE_ARB; | 522   parameters.target = GC3D_TEXTURE_RECTANGLE_ARB; | 
| 524 | 523 | 
| 525   if (m_wantAlphaChannel) { | 524   if (m_wantAlphaChannel) { | 
| 526     parameters.creationInternalColorFormat = GL_RGBA; | 525     parameters.creationInternalColorFormat = GL_RGBA; | 
| 527     parameters.internalColorFormat = GL_RGBA; | 526     parameters.internalColorFormat = GL_RGBA; | 
| 528   } else if (contextProvider() | 527   } else if (contextProvider() | 
| 529                  ->getCapabilities() | 528                  ->getCapabilities() | 
| 530                  .chromium_image_rgb_emulation) { | 529                  .chromium_image_rgb_emulation) { | 
| 531     parameters.creationInternalColorFormat = GL_RGB; | 530     parameters.creationInternalColorFormat = GL_RGB; | 
| 532     parameters.internalColorFormat = GL_RGBA; | 531     parameters.internalColorFormat = GL_RGBA; | 
| 533   } else { | 532   } else { | 
| 534     GLenum format = | 533     GLenum format = | 
| 535         defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB; | 534         defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB; | 
| 536     parameters.creationInternalColorFormat = format; | 535     parameters.creationInternalColorFormat = format; | 
| 537     parameters.internalColorFormat = format; | 536     parameters.internalColorFormat = format; | 
| 538   } | 537   } | 
| 539 | 538 | 
| 540   // Unused when CHROMIUM_image is being used. | 539   // Unused when CHROMIUM_image is being used. | 
| 541   parameters.colorFormat = 0; | 540   parameters.colorFormat = 0; | 
| 542   return parameters; | 541   return parameters; | 
| 543 #else | 542 #else | 
| 544   return defaultTextureParameters(); | 543   return textureColorBufferParameters(); | 
| 545 #endif | 544 #endif | 
| 546 } | 545 } | 
| 547 | 546 | 
| 548 DrawingBuffer::TextureParameters DrawingBuffer::defaultTextureParameters() { | 547 DrawingBuffer::ColorBufferParameters | 
| 549   TextureParameters parameters; | 548 DrawingBuffer::textureColorBufferParameters() { | 
|  | 549   ColorBufferParameters parameters; | 
| 550   parameters.target = GL_TEXTURE_2D; | 550   parameters.target = GL_TEXTURE_2D; | 
| 551   if (m_wantAlphaChannel) { | 551   if (m_wantAlphaChannel) { | 
| 552     parameters.internalColorFormat = GL_RGBA; | 552     parameters.internalColorFormat = GL_RGBA; | 
| 553     parameters.creationInternalColorFormat = GL_RGBA; | 553     parameters.creationInternalColorFormat = GL_RGBA; | 
| 554     parameters.colorFormat = GL_RGBA; | 554     parameters.colorFormat = GL_RGBA; | 
| 555   } else if (contextProvider() | 555   } else if (contextProvider() | 
| 556                  ->getCapabilities() | 556                  ->getCapabilities() | 
| 557                  .emulate_rgb_buffer_with_rgba) { | 557                  .emulate_rgb_buffer_with_rgba) { | 
| 558     parameters.internalColorFormat = GL_RGBA; | 558     parameters.internalColorFormat = GL_RGBA; | 
| 559     parameters.creationInternalColorFormat = GL_RGBA; | 559     parameters.creationInternalColorFormat = GL_RGBA; | 
| 560     parameters.colorFormat = GL_RGBA; | 560     parameters.colorFormat = GL_RGBA; | 
| 561   } else { | 561   } else { | 
| 562     GLenum format = | 562     GLenum format = | 
| 563         defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB; | 563         defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB; | 
| 564     parameters.creationInternalColorFormat = format; | 564     parameters.creationInternalColorFormat = format; | 
| 565     parameters.internalColorFormat = format; | 565     parameters.internalColorFormat = format; | 
| 566     parameters.colorFormat = format; | 566     parameters.colorFormat = format; | 
| 567   } | 567   } | 
| 568   return parameters; | 568   return parameters; | 
| 569 } | 569 } | 
| 570 | 570 | 
| 571 PassRefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::takeRecycledMailbox() { | 571 PassRefPtr<DrawingBuffer::ColorBuffer> | 
| 572   if (m_recycledMailboxQueue.isEmpty()) | 572 DrawingBuffer::createOrRecycleColorBuffer() { | 
| 573     return nullptr; | 573   if (!m_recycledColorBufferQueue.isEmpty()) { | 
| 574 | 574     RefPtr<ColorBuffer> recycled = m_recycledColorBufferQueue.takeLast(); | 
| 575   RefPtr<ColorBuffer> recycled = m_recycledMailboxQueue.takeLast(); | 575     if (recycled->receiveSyncToken.HasData()) | 
| 576   DCHECK(recycled->size == m_size); | 576       m_gl->WaitSyncTokenCHROMIUM(recycled->receiveSyncToken.GetData()); | 
| 577   if (recycled->receiveSyncToken.HasData()) | 577     DCHECK(recycled->size == m_size); | 
| 578     m_gl->WaitSyncTokenCHROMIUM(recycled->receiveSyncToken.GetData()); | 578     return recycled; | 
| 579   return recycled; | 579   } | 
|  | 580   return createColorBuffer(m_size); | 
| 580 } | 581 } | 
| 581 | 582 | 
| 582 DrawingBuffer::ColorBuffer::ColorBuffer(DrawingBuffer* drawingBuffer, | 583 DrawingBuffer::ColorBuffer::ColorBuffer(DrawingBuffer* drawingBuffer, | 
| 583                                         const TextureParameters& parameters, | 584                                         const ColorBufferParameters& parameters, | 
| 584                                         const IntSize& size) | 585                                         const IntSize& size, | 
| 585     : drawingBuffer(drawingBuffer), parameters(parameters), size(size) { | 586                                         GLuint textureId, | 
|  | 587                                         GLuint imageId) | 
|  | 588     : drawingBuffer(drawingBuffer), | 
|  | 589       parameters(parameters), | 
|  | 590       size(size), | 
|  | 591       textureId(textureId), | 
|  | 592       imageId(imageId) { | 
| 586   drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); | 593   drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); | 
| 587 } | 594 } | 
| 588 | 595 | 
| 589 DrawingBuffer::ColorBuffer::~ColorBuffer() { | 596 DrawingBuffer::ColorBuffer::~ColorBuffer() { | 
| 590   gpu::gles2::GLES2Interface* gl = drawingBuffer->contextGL(); | 597   gpu::gles2::GLES2Interface* gl = drawingBuffer->m_gl; | 
| 591   if (receiveSyncToken.HasData()) | 598   if (receiveSyncToken.HasData()) | 
| 592     gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData()); | 599     gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData()); | 
| 593   if (imageId) { | 600   if (imageId) { | 
| 594     gl->BindTexture(parameters.target, textureId); | 601     gl->BindTexture(parameters.target, textureId); | 
| 595     gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId); | 602     gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId); | 
| 596     gl->DestroyImageCHROMIUM(imageId); | 603     gl->DestroyImageCHROMIUM(imageId); | 
|  | 604     switch (parameters.target) { | 
|  | 605       case GL_TEXTURE_2D: | 
|  | 606         // Restore the texture binding for GL_TEXTURE_2D, since the client will | 
|  | 607         // expect the previous state. | 
|  | 608         if (drawingBuffer->m_stateTracker) { | 
|  | 609           DrawingBufferRestoreState restoreState; | 
|  | 610           drawingBuffer->m_stateTracker->GetDrawingBufferRestoreState( | 
|  | 611               &restoreState); | 
|  | 612           gl->BindTexture(GL_TEXTURE_2D, restoreState.activeTexture2DBinding); | 
|  | 613         } | 
|  | 614         break; | 
|  | 615       case GC3D_TEXTURE_RECTANGLE_ARB: | 
|  | 616         // Rectangle textures aren't exposed to WebGL, so don't bother | 
|  | 617         // restoring this state (there is no meaningful way to restore it). | 
|  | 618         break; | 
|  | 619       default: | 
|  | 620         NOTREACHED(); | 
|  | 621         break; | 
|  | 622     } | 
| 597   } | 623   } | 
| 598   gl->DeleteTextures(1, &textureId); | 624   gl->DeleteTextures(1, &textureId); | 
| 599 } | 625 } | 
| 600 | 626 | 
| 601 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) { | 627 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) { | 
|  | 628   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 629 | 
| 602   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 630   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 
| 603     // Need to try to restore the context again later. | 631     // Need to try to restore the context again later. | 
| 604     return false; | 632     return false; | 
| 605   } | 633   } | 
| 606 | 634 | 
| 607   m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); | 635   m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); | 
| 608 | 636 | 
| 609   int maxSampleCount = 0; | 637   int maxSampleCount = 0; | 
| 610   m_antiAliasingMode = None; | 638   m_antiAliasingMode = None; | 
| 611   if (useMultisampling) { | 639   if (useMultisampling) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 623   // The Linux ATI bot fails | 651   // The Linux ATI bot fails | 
| 624   // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage | 652   // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage | 
| 625   // textures only if ScreenSpaceAntialiasing is enabled, because | 653   // textures only if ScreenSpaceAntialiasing is enabled, because | 
| 626   // ScreenSpaceAntialiasing is much faster with storage textures. | 654   // ScreenSpaceAntialiasing is much faster with storage textures. | 
| 627   m_storageTextureSupported = | 655   m_storageTextureSupported = | 
| 628       (m_webGLVersion > WebGL1 || | 656       (m_webGLVersion > WebGL1 || | 
| 629        m_extensionsUtil->supportsExtension("GL_EXT_texture_storage")) && | 657        m_extensionsUtil->supportsExtension("GL_EXT_texture_storage")) && | 
| 630       m_antiAliasingMode == ScreenSpaceAntialiasing; | 658       m_antiAliasingMode == ScreenSpaceAntialiasing; | 
| 631   m_sampleCount = std::min(4, maxSampleCount); | 659   m_sampleCount = std::min(4, maxSampleCount); | 
| 632 | 660 | 
|  | 661   m_stateRestorer->setFramebufferBindingDirty(); | 
| 633   m_gl->GenFramebuffers(1, &m_fbo); | 662   m_gl->GenFramebuffers(1, &m_fbo); | 
| 634   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 663   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 635   if (wantExplicitResolve()) { | 664   if (wantExplicitResolve()) { | 
| 636     m_gl->GenFramebuffers(1, &m_multisampleFBO); | 665     m_gl->GenFramebuffers(1, &m_multisampleFBO); | 
| 637     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 666     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 
| 638     m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer); | 667     m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer); | 
| 639   } | 668   } | 
| 640   if (!reset(size)) | 669   if (!resizeFramebufferInternal(size)) | 
| 641     return false; | 670     return false; | 
| 642 | 671 | 
| 643   if (m_depthStencilBuffer) { | 672   if (m_depthStencilBuffer) { | 
| 644     DCHECK(wantDepthOrStencil()); | 673     DCHECK(wantDepthOrStencil()); | 
| 645     m_hasImplicitStencilBuffer = !m_wantStencil; | 674     m_hasImplicitStencilBuffer = !m_wantStencil; | 
| 646   } | 675   } | 
| 647 | 676 | 
| 648   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 677   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 
| 649     // It's possible that the drawing buffer allocation provokes a context loss, | 678     // It's possible that the drawing buffer allocation provokes a context loss, | 
| 650     // so check again just in case. http://crbug.com/512302 | 679     // so check again just in case. http://crbug.com/512302 | 
| 651     return false; | 680     return false; | 
| 652   } | 681   } | 
| 653 | 682 | 
| 654   return true; | 683   return true; | 
| 655 } | 684 } | 
| 656 | 685 | 
| 657 bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl, | 686 bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl, | 
| 658                                           GLuint texture, | 687                                           GLuint texture, | 
| 659                                           GLenum internalFormat, | 688                                           GLenum internalFormat, | 
| 660                                           GLenum destType, | 689                                           GLenum destType, | 
| 661                                           GLint level, | 690                                           GLint level, | 
| 662                                           bool premultiplyAlpha, | 691                                           bool premultiplyAlpha, | 
| 663                                           bool flipY, | 692                                           bool flipY, | 
| 664                                           SourceDrawingBuffer sourceBuffer) { | 693                                           SourceDrawingBuffer sourceBuffer) { | 
|  | 694   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 695 | 
| 665   if (m_contentsChanged) { | 696   if (m_contentsChanged) { | 
| 666     if (m_antiAliasingMode != None) { | 697     if (m_antiAliasingMode != None) | 
| 667       commit(); | 698       resolveMultisampleFramebufferInternal(); | 
| 668       restoreFramebufferBindings(); |  | 
| 669     } |  | 
| 670     m_gl->Flush(); | 699     m_gl->Flush(); | 
| 671   } | 700   } | 
| 672 | 701 | 
| 673   // Assume that the destination target is GL_TEXTURE_2D. | 702   // Assume that the destination target is GL_TEXTURE_2D. | 
| 674   if (!Extensions3DUtil::canUseCopyTextureCHROMIUM( | 703   if (!Extensions3DUtil::canUseCopyTextureCHROMIUM( | 
| 675           GL_TEXTURE_2D, internalFormat, destType, level)) | 704           GL_TEXTURE_2D, internalFormat, destType, level)) | 
| 676     return false; | 705     return false; | 
| 677 | 706 | 
| 678   // Contexts may be in a different share group. We must transfer the texture | 707   // Contexts may be in a different share group. We must transfer the texture | 
| 679   // through a mailbox first. | 708   // through a mailbox first. | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 715   const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 744   const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 
| 716 | 745 | 
| 717   gl->Flush(); | 746   gl->Flush(); | 
| 718   gpu::SyncToken syncToken; | 747   gpu::SyncToken syncToken; | 
| 719   gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); | 748   gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); | 
| 720   m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData()); | 749   m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData()); | 
| 721 | 750 | 
| 722   return true; | 751   return true; | 
| 723 } | 752 } | 
| 724 | 753 | 
| 725 GLuint DrawingBuffer::framebuffer() const { |  | 
| 726   return m_fbo; |  | 
| 727 } |  | 
| 728 |  | 
| 729 WebLayer* DrawingBuffer::platformLayer() { | 754 WebLayer* DrawingBuffer::platformLayer() { | 
| 730   if (!m_layer) { | 755   if (!m_layer) { | 
| 731     m_layer = wrapUnique( | 756     m_layer = wrapUnique( | 
| 732         Platform::current()->compositorSupport()->createExternalTextureLayer( | 757         Platform::current()->compositorSupport()->createExternalTextureLayer( | 
| 733             this)); | 758             this)); | 
| 734 | 759 | 
| 735     m_layer->setOpaque(!m_wantAlphaChannel); | 760     m_layer->setOpaque(!m_wantAlphaChannel); | 
| 736     m_layer->setBlendBackgroundColor(m_wantAlphaChannel); | 761     m_layer->setBlendBackgroundColor(m_wantAlphaChannel); | 
| 737     m_layer->setPremultipliedAlpha(m_premultipliedAlpha); | 762     m_layer->setPremultipliedAlpha(m_premultipliedAlpha); | 
| 738     m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); | 763     m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); | 
| 739     GraphicsLayer::registerContentsLayer(m_layer->layer()); | 764     GraphicsLayer::registerContentsLayer(m_layer->layer()); | 
| 740   } | 765   } | 
| 741 | 766 | 
| 742   return m_layer->layer(); | 767   return m_layer->layer(); | 
| 743 } | 768 } | 
| 744 | 769 | 
| 745 void DrawingBuffer::clearPlatformLayer() { | 770 void DrawingBuffer::clearPlatformLayer() { | 
| 746   if (m_layer) | 771   if (m_layer) | 
| 747     m_layer->clearTexture(); | 772     m_layer->clearTexture(); | 
| 748 | 773 | 
| 749   m_gl->Flush(); | 774   m_gl->Flush(); | 
| 750 } | 775 } | 
| 751 | 776 | 
| 752 void DrawingBuffer::beginDestruction() { | 777 void DrawingBuffer::beginDestruction() { | 
| 753   ASSERT(!m_destructionInProgress); | 778   ASSERT(!m_destructionInProgress); | 
| 754   m_destructionInProgress = true; | 779   m_destructionInProgress = true; | 
| 755 | 780 | 
| 756   clearPlatformLayer(); | 781   clearPlatformLayer(); | 
| 757   m_recycledMailboxQueue.clear(); | 782   m_recycledColorBufferQueue.clear(); | 
| 758 | 783 | 
| 759   if (m_multisampleFBO) | 784   if (m_multisampleFBO) | 
| 760     m_gl->DeleteFramebuffers(1, &m_multisampleFBO); | 785     m_gl->DeleteFramebuffers(1, &m_multisampleFBO); | 
| 761 | 786 | 
| 762   if (m_fbo) | 787   if (m_fbo) | 
| 763     m_gl->DeleteFramebuffers(1, &m_fbo); | 788     m_gl->DeleteFramebuffers(1, &m_fbo); | 
| 764 | 789 | 
| 765   if (m_multisampleRenderbuffer) | 790   if (m_multisampleRenderbuffer) | 
| 766     m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer); | 791     m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer); | 
| 767 | 792 | 
| 768   if (m_depthStencilBuffer) | 793   if (m_depthStencilBuffer) | 
| 769     m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer); | 794     m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer); | 
| 770 | 795 | 
| 771   m_size = IntSize(); | 796   m_size = IntSize(); | 
| 772 | 797 | 
| 773   m_backColorBuffer = nullptr; | 798   m_backColorBuffer = nullptr; | 
| 774   m_frontColorBuffer = nullptr; | 799   m_frontColorBuffer = nullptr; | 
| 775   m_multisampleRenderbuffer = 0; | 800   m_multisampleRenderbuffer = 0; | 
| 776   m_depthStencilBuffer = 0; | 801   m_depthStencilBuffer = 0; | 
| 777   m_multisampleFBO = 0; | 802   m_multisampleFBO = 0; | 
| 778   m_fbo = 0; | 803   m_fbo = 0; | 
| 779 | 804 | 
| 780   if (m_layer) | 805   if (m_layer) | 
| 781     GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 806     GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 
| 782 } |  | 
| 783 | 807 | 
| 784 GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters) { | 808   m_stateTracker = nullptr; | 
| 785   GLuint offscreenColorTexture; |  | 
| 786   m_gl->GenTextures(1, &offscreenColorTexture); |  | 
| 787   m_gl->BindTexture(parameters.target, offscreenColorTexture); |  | 
| 788   m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |  | 
| 789   m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |  | 
| 790   m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |  | 
| 791   m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |  | 
| 792   return offscreenColorTexture; |  | 
| 793 } | 809 } | 
| 794 | 810 | 
| 795 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { | 811 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { | 
| 796   // Recreate m_backColorBuffer. | 812   // Recreate m_backColorBuffer. | 
| 797   m_backColorBuffer = createTextureAndAllocateMemory(size); | 813   m_backColorBuffer = createColorBuffer(size); | 
| 798 | 814 | 
| 799   attachColorBufferToReadFramebuffer(); | 815   attachColorBufferToReadFramebuffer(); | 
| 800 | 816 | 
| 801   if (wantExplicitResolve()) { | 817   if (wantExplicitResolve()) { | 
|  | 818     m_stateRestorer->setFramebufferBindingDirty(); | 
|  | 819     m_stateRestorer->setRenderbufferBindingDirty(); | 
| 802     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 820     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 
| 803     m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); | 821     m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); | 
| 804     m_gl->RenderbufferStorageMultisampleCHROMIUM( | 822     m_gl->RenderbufferStorageMultisampleCHROMIUM( | 
| 805         GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), | 823         GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), | 
| 806         size.width(), size.height()); | 824         size.width(), size.height()); | 
| 807 | 825 | 
| 808     if (m_gl->GetError() == GL_OUT_OF_MEMORY) | 826     if (m_gl->GetError() == GL_OUT_OF_MEMORY) | 
| 809       return false; | 827       return false; | 
| 810 | 828 | 
| 811     m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 829     m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 812                                   GL_RENDERBUFFER, m_multisampleRenderbuffer); | 830                                   GL_RENDERBUFFER, m_multisampleRenderbuffer); | 
| 813   } | 831   } | 
| 814 | 832 | 
| 815   if (wantDepthOrStencil()) { | 833   if (wantDepthOrStencil()) { | 
|  | 834     m_stateRestorer->setFramebufferBindingDirty(); | 
|  | 835     m_stateRestorer->setRenderbufferBindingDirty(); | 
| 816     m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 836     m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 
| 817                           m_multisampleFBO ? m_multisampleFBO : m_fbo); | 837                           m_multisampleFBO ? m_multisampleFBO : m_fbo); | 
| 818     if (!m_depthStencilBuffer) | 838     if (!m_depthStencilBuffer) | 
| 819       m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); | 839       m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); | 
| 820     m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 840     m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 
| 821     if (m_antiAliasingMode == MSAAImplicitResolve) { | 841     if (m_antiAliasingMode == MSAAImplicitResolve) { | 
| 822       m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, | 842       m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, | 
| 823                                               GL_DEPTH24_STENCIL8_OES, | 843                                               GL_DEPTH24_STENCIL8_OES, | 
| 824                                               size.width(), size.height()); | 844                                               size.width(), size.height()); | 
| 825     } else if (m_antiAliasingMode == MSAAExplicitResolve) { | 845     } else if (m_antiAliasingMode == MSAAExplicitResolve) { | 
| 826       m_gl->RenderbufferStorageMultisampleCHROMIUM( | 846       m_gl->RenderbufferStorageMultisampleCHROMIUM( | 
| 827           GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), | 847           GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), | 
| 828           size.height()); | 848           size.height()); | 
| 829     } else { | 849     } else { | 
| 830       m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, | 850       m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, | 
| 831                                 size.width(), size.height()); | 851                                 size.width(), size.height()); | 
| 832     } | 852     } | 
| 833     // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we | 853     // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we | 
| 834     // emulate | 854     // emulate | 
| 835     // it at the command buffer level for WebGL contexts. | 855     // it at the command buffer level for WebGL contexts. | 
| 836     m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, | 856     m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, | 
| 837                                   GL_RENDERBUFFER, m_depthStencilBuffer); | 857                                   GL_RENDERBUFFER, m_depthStencilBuffer); | 
| 838     m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); | 858     m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); | 
| 839   } | 859   } | 
| 840 | 860 | 
| 841   if (wantExplicitResolve()) { | 861   if (wantExplicitResolve()) { | 
|  | 862     m_stateRestorer->setFramebufferBindingDirty(); | 
| 842     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 863     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 
| 843     if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | 864     if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | 
| 844       return false; | 865       return false; | 
| 845   } | 866   } | 
| 846 | 867 | 
|  | 868   m_stateRestorer->setFramebufferBindingDirty(); | 
| 847   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 869   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 848   return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == | 870   return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == | 
| 849          GL_FRAMEBUFFER_COMPLETE; | 871          GL_FRAMEBUFFER_COMPLETE; | 
| 850 } | 872 } | 
| 851 | 873 | 
| 852 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) { | 874 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) { | 
|  | 875   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 876   clearFramebuffersInternal(clearMask); | 
|  | 877 } | 
|  | 878 | 
|  | 879 void DrawingBuffer::clearFramebuffersInternal(GLbitfield clearMask) { | 
|  | 880   m_stateRestorer->setFramebufferBindingDirty(); | 
| 853   // We will clear the multisample FBO, but we also need to clear the | 881   // We will clear the multisample FBO, but we also need to clear the | 
| 854   // non-multisampled buffer. | 882   // non-multisampled buffer. | 
| 855   if (m_multisampleFBO) { | 883   if (m_multisampleFBO) { | 
| 856     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 884     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 857     m_gl->Clear(GL_COLOR_BUFFER_BIT); | 885     m_gl->Clear(GL_COLOR_BUFFER_BIT); | 
| 858   } | 886   } | 
| 859 | 887 | 
| 860   m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 888   m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 
| 861                         m_multisampleFBO ? m_multisampleFBO : m_fbo); | 889                         m_multisampleFBO ? m_multisampleFBO : m_fbo); | 
| 862   m_gl->Clear(clearMask); | 890   m_gl->Clear(clearMask); | 
| 863 } | 891 } | 
| 864 | 892 | 
| 865 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, | 893 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, | 
| 866                                   const IntSize& curSize, | 894                                   const IntSize& curSize, | 
| 867                                   int maxTextureSize) { | 895                                   int maxTextureSize) { | 
| 868   IntSize adjustedSize = desiredSize; | 896   IntSize adjustedSize = desiredSize; | 
| 869 | 897 | 
| 870   // Clamp if the desired size is greater than the maximum texture size for the | 898   // Clamp if the desired size is greater than the maximum texture size for the | 
| 871   // device. | 899   // device. | 
| 872   if (adjustedSize.height() > maxTextureSize) | 900   if (adjustedSize.height() > maxTextureSize) | 
| 873     adjustedSize.setHeight(maxTextureSize); | 901     adjustedSize.setHeight(maxTextureSize); | 
| 874 | 902 | 
| 875   if (adjustedSize.width() > maxTextureSize) | 903   if (adjustedSize.width() > maxTextureSize) | 
| 876     adjustedSize.setWidth(maxTextureSize); | 904     adjustedSize.setWidth(maxTextureSize); | 
| 877 | 905 | 
| 878   return adjustedSize; | 906   return adjustedSize; | 
| 879 } | 907 } | 
| 880 | 908 | 
| 881 bool DrawingBuffer::reset(const IntSize& newSize) { | 909 bool DrawingBuffer::resize(const IntSize& newSize) { | 
|  | 910   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 911   return resizeFramebufferInternal(newSize); | 
|  | 912 } | 
|  | 913 | 
|  | 914 bool DrawingBuffer::resizeFramebufferInternal(const IntSize& newSize) { | 
| 882   CHECK(!newSize.isEmpty()); | 915   CHECK(!newSize.isEmpty()); | 
| 883   IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); | 916   IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); | 
| 884   if (adjustedSize.isEmpty()) | 917   if (adjustedSize.isEmpty()) | 
| 885     return false; | 918     return false; | 
| 886 | 919 | 
| 887   if (adjustedSize != m_size) { | 920   if (adjustedSize != m_size) { | 
| 888     do { | 921     do { | 
| 889       if (!resizeDefaultFramebuffer(adjustedSize)) { | 922       if (!resizeDefaultFramebuffer(adjustedSize)) { | 
| 890         adjustedSize.scale(s_resourceAdjustedRatio); | 923         adjustedSize.scale(s_resourceAdjustedRatio); | 
| 891         continue; | 924         continue; | 
| 892       } | 925       } | 
| 893       break; | 926       break; | 
| 894     } while (!adjustedSize.isEmpty()); | 927     } while (!adjustedSize.isEmpty()); | 
| 895 | 928 | 
| 896     m_size = adjustedSize; | 929     m_size = adjustedSize; | 
| 897     // Free all mailboxes, because they are now of the wrong size. Only the | 930     // Free all mailboxes, because they are now of the wrong size. Only the | 
| 898     // first call in this loop has any effect. | 931     // first call in this loop has any effect. | 
| 899     m_recycledMailboxQueue.clear(); | 932     m_recycledColorBufferQueue.clear(); | 
| 900     m_recycledBitmaps.clear(); | 933     m_recycledBitmaps.clear(); | 
| 901 | 934 | 
| 902     if (adjustedSize.isEmpty()) | 935     if (adjustedSize.isEmpty()) | 
| 903       return false; | 936       return false; | 
| 904   } | 937   } | 
| 905 | 938 | 
|  | 939   m_stateRestorer->setClearStateDirty(); | 
| 906   m_gl->Disable(GL_SCISSOR_TEST); | 940   m_gl->Disable(GL_SCISSOR_TEST); | 
| 907   m_gl->ClearColor(0, 0, 0, | 941   m_gl->ClearColor(0, 0, 0, | 
| 908                    defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); | 942                    defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); | 
| 909   m_gl->ColorMask(true, true, true, true); | 943   m_gl->ColorMask(true, true, true, true); | 
| 910 | 944 | 
| 911   GLbitfield clearMask = GL_COLOR_BUFFER_BIT; | 945   GLbitfield clearMask = GL_COLOR_BUFFER_BIT; | 
| 912   if (!!m_depthStencilBuffer) { | 946   if (!!m_depthStencilBuffer) { | 
| 913     m_gl->ClearDepthf(1.0f); | 947     m_gl->ClearDepthf(1.0f); | 
| 914     clearMask |= GL_DEPTH_BUFFER_BIT; | 948     clearMask |= GL_DEPTH_BUFFER_BIT; | 
| 915     m_gl->DepthMask(true); | 949     m_gl->DepthMask(true); | 
| 916   } | 950   } | 
| 917   if (!!m_depthStencilBuffer) { | 951   if (!!m_depthStencilBuffer) { | 
| 918     m_gl->ClearStencil(0); | 952     m_gl->ClearStencil(0); | 
| 919     clearMask |= GL_STENCIL_BUFFER_BIT; | 953     clearMask |= GL_STENCIL_BUFFER_BIT; | 
| 920     m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); | 954     m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); | 
| 921   } | 955   } | 
| 922 | 956 | 
| 923   clearFramebuffers(clearMask); | 957   clearFramebuffersInternal(clearMask); | 
| 924   return true; | 958   return true; | 
| 925 } | 959 } | 
| 926 | 960 | 
| 927 void DrawingBuffer::commit() { | 961 void DrawingBuffer::resolveAndBindForReadAndDraw() { | 
|  | 962   { | 
|  | 963     ScopedStateRestorer scopedStateRestorer(this); | 
|  | 964     resolveMultisampleFramebufferInternal(); | 
|  | 965   } | 
|  | 966   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
|  | 967 } | 
|  | 968 | 
|  | 969 void DrawingBuffer::resolveMultisampleFramebufferInternal() { | 
|  | 970   m_stateRestorer->setFramebufferBindingDirty(); | 
| 928   if (wantExplicitResolve() && !m_contentsChangeCommitted) { | 971   if (wantExplicitResolve() && !m_contentsChangeCommitted) { | 
|  | 972     m_stateRestorer->setClearStateDirty(); | 
| 929     m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); | 973     m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); | 
| 930     m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); | 974     m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); | 
| 931 | 975     m_gl->Disable(GL_SCISSOR_TEST); | 
| 932     if (m_scissorEnabled) |  | 
| 933       m_gl->Disable(GL_SCISSOR_TEST); |  | 
| 934 | 976 | 
| 935     int width = m_size.width(); | 977     int width = m_size.width(); | 
| 936     int height = m_size.height(); | 978     int height = m_size.height(); | 
| 937     // Use NEAREST, because there is no scale performed during the blit. | 979     // Use NEAREST, because there is no scale performed during the blit. | 
| 938     GLuint filter = GL_NEAREST; | 980     GLuint filter = GL_NEAREST; | 
| 939 | 981 | 
| 940     m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height, | 982     m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height, | 
| 941                                   GL_COLOR_BUFFER_BIT, filter); | 983                                   GL_COLOR_BUFFER_BIT, filter); | 
| 942 | 984 | 
| 943     // On old AMD GPUs on OS X, glColorMask doesn't work correctly for | 985     // On old AMD GPUs on OS X, glColorMask doesn't work correctly for | 
| 944     // multisampled renderbuffers and the alpha channel can be overwritten. | 986     // multisampled renderbuffers and the alpha channel can be overwritten. | 
| 945     // Clear the alpha channel of |m_fbo|. | 987     // Clear the alpha channel of |m_fbo|. | 
| 946     if (defaultBufferRequiresAlphaChannelToBePreserved() && | 988     if (defaultBufferRequiresAlphaChannelToBePreserved() && | 
| 947         contextProvider() | 989         contextProvider() | 
| 948             ->getCapabilities() | 990             ->getCapabilities() | 
| 949             .disable_multisampling_color_mask_usage) { | 991             .disable_multisampling_color_mask_usage) { | 
| 950       m_gl->ClearColor(0, 0, 0, 1); | 992       m_gl->ClearColor(0, 0, 0, 1); | 
| 951       m_gl->ColorMask(false, false, false, true); | 993       m_gl->ColorMask(false, false, false, true); | 
| 952       m_gl->Clear(GL_COLOR_BUFFER_BIT); |  | 
| 953 |  | 
| 954       m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], |  | 
| 955                        m_clearColor[3]); |  | 
| 956       m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], |  | 
| 957                       m_colorMask[3]); |  | 
| 958     } | 994     } | 
| 959 |  | 
| 960     if (m_scissorEnabled) |  | 
| 961       m_gl->Enable(GL_SCISSOR_TEST); |  | 
| 962   } | 995   } | 
| 963 | 996 | 
| 964   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 997   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 965   if (m_antiAliasingMode == ScreenSpaceAntialiasing) { | 998   if (m_antiAliasingMode == ScreenSpaceAntialiasing) | 
| 966     m_gl->ApplyScreenSpaceAntialiasingCHROMIUM(); | 999     m_gl->ApplyScreenSpaceAntialiasingCHROMIUM(); | 
| 967   } |  | 
| 968   m_contentsChangeCommitted = true; | 1000   m_contentsChangeCommitted = true; | 
| 969 } | 1001 } | 
| 970 | 1002 | 
| 971 void DrawingBuffer::restorePixelUnpackBufferBindings() { |  | 
| 972   if (m_webGLVersion > WebGL1) { |  | 
| 973     m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixelUnpackBufferBinding); |  | 
| 974   } |  | 
| 975 } |  | 
| 976 |  | 
| 977 void DrawingBuffer::restoreFramebufferBindings() { | 1003 void DrawingBuffer::restoreFramebufferBindings() { | 
| 978   if (m_drawFramebufferBinding && m_readFramebufferBinding) { | 1004   DrawingBufferRestoreState restoreState; | 
| 979     if (m_drawFramebufferBinding == m_readFramebufferBinding) { | 1005   m_stateRestorer->setFramebufferBindingDirty(); | 
| 980       m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_readFramebufferBinding); |  | 
| 981     } else { |  | 
| 982       m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding); |  | 
| 983       m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding); |  | 
| 984     } |  | 
| 985     return; |  | 
| 986   } |  | 
| 987   if (!m_drawFramebufferBinding && !m_readFramebufferBinding) { |  | 
| 988     bind(GL_FRAMEBUFFER); |  | 
| 989     return; |  | 
| 990   } |  | 
| 991   if (!m_drawFramebufferBinding) { |  | 
| 992     bind(GL_DRAW_FRAMEBUFFER); |  | 
| 993     m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding); |  | 
| 994   } else { |  | 
| 995     bind(GL_READ_FRAMEBUFFER); |  | 
| 996     m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding); |  | 
| 997   } |  | 
| 998 } | 1006 } | 
| 999 | 1007 | 
| 1000 bool DrawingBuffer::multisample() const { | 1008 bool DrawingBuffer::multisample() const { | 
| 1001   return m_antiAliasingMode != None; | 1009   return m_antiAliasingMode != None; | 
| 1002 } | 1010 } | 
| 1003 | 1011 | 
| 1004 void DrawingBuffer::bind(GLenum target) { | 1012 void DrawingBuffer::bind(GLenum target) { | 
| 1005   m_gl->BindFramebuffer(target, | 1013   m_gl->BindFramebuffer(target, | 
| 1006                         wantExplicitResolve() ? m_multisampleFBO : m_fbo); | 1014                         wantExplicitResolve() ? m_multisampleFBO : m_fbo); | 
| 1007 } | 1015 } | 
| 1008 | 1016 | 
| 1009 void DrawingBuffer::setPackAlignment(GLint param) { |  | 
| 1010   m_packAlignment = param; |  | 
| 1011 } |  | 
| 1012 |  | 
| 1013 bool DrawingBuffer::paintRenderingResultsToImageData( | 1017 bool DrawingBuffer::paintRenderingResultsToImageData( | 
| 1014     int& width, | 1018     int& width, | 
| 1015     int& height, | 1019     int& height, | 
| 1016     SourceDrawingBuffer sourceBuffer, | 1020     SourceDrawingBuffer sourceBuffer, | 
| 1017     WTF::ArrayBufferContents& contents) { | 1021     WTF::ArrayBufferContents& contents) { | 
|  | 1022   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 1023 | 
| 1018   ASSERT(!m_premultipliedAlpha); | 1024   ASSERT(!m_premultipliedAlpha); | 
| 1019   width = size().width(); | 1025   width = size().width(); | 
| 1020   height = size().height(); | 1026   height = size().height(); | 
| 1021 | 1027 | 
| 1022   CheckedNumeric<int> dataSize = 4; | 1028   CheckedNumeric<int> dataSize = 4; | 
| 1023   dataSize *= width; | 1029   dataSize *= width; | 
| 1024   dataSize *= height; | 1030   dataSize *= height; | 
| 1025   if (!dataSize.IsValid()) | 1031   if (!dataSize.IsValid()) | 
| 1026     return false; | 1032     return false; | 
| 1027 | 1033 | 
| 1028   WTF::ArrayBufferContents pixels(width * height, 4, | 1034   WTF::ArrayBufferContents pixels(width * height, 4, | 
| 1029                                   WTF::ArrayBufferContents::NotShared, | 1035                                   WTF::ArrayBufferContents::NotShared, | 
| 1030                                   WTF::ArrayBufferContents::DontInitialize); | 1036                                   WTF::ArrayBufferContents::DontInitialize); | 
| 1031 | 1037 | 
| 1032   GLuint fbo = 0; | 1038   GLuint fbo = 0; | 
|  | 1039   m_stateRestorer->setFramebufferBindingDirty(); | 
| 1033   if (sourceBuffer == FrontBuffer && m_frontColorBuffer) { | 1040   if (sourceBuffer == FrontBuffer && m_frontColorBuffer) { | 
| 1034     m_gl->GenFramebuffers(1, &fbo); | 1041     m_gl->GenFramebuffers(1, &fbo); | 
| 1035     m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 1042     m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 
| 1036     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1043     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 1037                                m_frontColorBuffer->parameters.target, | 1044                                m_frontColorBuffer->parameters.target, | 
| 1038                                m_frontColorBuffer->textureId, 0); | 1045                                m_frontColorBuffer->textureId, 0); | 
| 1039   } else { | 1046   } else { | 
| 1040     m_gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer()); | 1047     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 1041   } | 1048   } | 
| 1042 | 1049 | 
| 1043   readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, | 1050   readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, | 
| 1044                       ReadbackRGBA, WebGLImageConversion::AlphaDoNothing); | 1051                       ReadbackRGBA, WebGLImageConversion::AlphaDoNothing); | 
| 1045   flipVertically(static_cast<uint8_t*>(pixels.data()), width, height); | 1052   flipVertically(static_cast<uint8_t*>(pixels.data()), width, height); | 
| 1046 | 1053 | 
| 1047   if (fbo) { | 1054   if (fbo) { | 
| 1048     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1055     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 1049                                m_frontColorBuffer->parameters.target, 0, 0); | 1056                                m_frontColorBuffer->parameters.target, 0, 0); | 
| 1050     m_gl->DeleteFramebuffers(1, &fbo); | 1057     m_gl->DeleteFramebuffers(1, &fbo); | 
| 1051   } | 1058   } | 
| 1052 | 1059 | 
| 1053   restoreFramebufferBindings(); |  | 
| 1054 |  | 
| 1055   pixels.transfer(contents); | 1060   pixels.transfer(contents); | 
| 1056   return true; | 1061   return true; | 
| 1057 } | 1062 } | 
| 1058 | 1063 | 
| 1059 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, | 1064 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, | 
| 1060                                         int width, | 1065                                         int width, | 
| 1061                                         int height, | 1066                                         int height, | 
| 1062                                         ReadbackOrder readbackOrder, | 1067                                         ReadbackOrder readbackOrder, | 
| 1063                                         WebGLImageConversion::AlphaOp op) { | 1068                                         WebGLImageConversion::AlphaOp op) { | 
| 1064   if (m_packAlignment > 4) | 1069   m_stateRestorer->setPixelPackAlignmentDirty(); | 
| 1065     m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1); | 1070   m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1); | 
| 1066   m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 1071   m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 
| 1067   if (m_packAlignment > 4) |  | 
| 1068     m_gl->PixelStorei(GL_PACK_ALIGNMENT, m_packAlignment); |  | 
| 1069 | 1072 | 
| 1070   size_t bufferSize = 4 * width * height; | 1073   size_t bufferSize = 4 * width * height; | 
| 1071 | 1074 | 
| 1072   if (readbackOrder == ReadbackSkia) { | 1075   if (readbackOrder == ReadbackSkia) { | 
| 1073 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 1076 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 
| 1074     // Swizzle red and blue channels to match SkBitmap's byte ordering. | 1077     // Swizzle red and blue channels to match SkBitmap's byte ordering. | 
| 1075     // TODO(kbr): expose GL_BGRA as extension. | 1078     // TODO(kbr): expose GL_BGRA as extension. | 
| 1076     for (size_t i = 0; i < bufferSize; i += 4) { | 1079     for (size_t i = 0; i < bufferSize; i += 4) { | 
| 1077       std::swap(pixels[i], pixels[i + 2]); | 1080       std::swap(pixels[i], pixels[i + 2]); | 
| 1078     } | 1081     } | 
| 1079 #endif | 1082 #endif | 
| 1080   } | 1083   } | 
| 1081 | 1084 | 
| 1082   if (op == WebGLImageConversion::AlphaDoPremultiply) { | 1085   if (op == WebGLImageConversion::AlphaDoPremultiply) { | 
| 1083     for (size_t i = 0; i < bufferSize; i += 4) { | 1086     for (size_t i = 0; i < bufferSize; i += 4) { | 
| 1084       pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); | 1087       pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); | 
| 1085       pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); | 1088       pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); | 
| 1086       pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); | 1089       pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); | 
| 1087     } | 1090     } | 
| 1088   } else if (op != WebGLImageConversion::AlphaDoNothing) { | 1091   } else if (op != WebGLImageConversion::AlphaDoNothing) { | 
| 1089     ASSERT_NOT_REACHED(); | 1092     ASSERT_NOT_REACHED(); | 
| 1090   } | 1093   } | 
| 1091 } | 1094 } | 
| 1092 | 1095 | 
| 1093 void DrawingBuffer::flipVertically(uint8_t* framebuffer, | 1096 void DrawingBuffer::flipVertically(uint8_t* framebuffer, | 
| 1094                                    int width, | 1097                                    int width, | 
| 1095                                    int height) { | 1098                                    int height) { | 
| 1096   m_scanline.resize(width * 4); | 1099   std::vector<uint8_t> scanline(width * 4); | 
| 1097   uint8_t* scanline = &m_scanline[0]; |  | 
| 1098   unsigned rowBytes = width * 4; | 1100   unsigned rowBytes = width * 4; | 
| 1099   unsigned count = height / 2; | 1101   unsigned count = height / 2; | 
| 1100   for (unsigned i = 0; i < count; i++) { | 1102   for (unsigned i = 0; i < count; i++) { | 
| 1101     uint8_t* rowA = framebuffer + i * rowBytes; | 1103     uint8_t* rowA = framebuffer + i * rowBytes; | 
| 1102     uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; | 1104     uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; | 
| 1103     memcpy(scanline, rowB, rowBytes); | 1105     memcpy(scanline.data(), rowB, rowBytes); | 
| 1104     memcpy(rowB, rowA, rowBytes); | 1106     memcpy(rowB, rowA, rowBytes); | 
| 1105     memcpy(rowA, scanline, rowBytes); | 1107     memcpy(rowA, scanline.data(), rowBytes); | 
| 1106   } | 1108   } | 
| 1107 } | 1109 } | 
| 1108 | 1110 | 
| 1109 void DrawingBuffer::allocateConditionallyImmutableTexture(GLenum target, | 1111 RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer( | 
| 1110                                                           GLenum internalformat, | 1112     const IntSize& size) { | 
| 1111                                                           GLsizei width, | 1113   m_stateRestorer->setFramebufferBindingDirty(); | 
| 1112                                                           GLsizei height, | 1114   m_stateRestorer->setTextureBindingDirty(); | 
| 1113                                                           GLint border, | 1115 | 
| 1114                                                           GLenum format, | 1116   // Select the Parameters for the texture object. Allocate the backing | 
| 1115                                                           GLenum type) { | 1117   // GpuMemoryBuffer and GLImage, if one is going to be used. | 
| 1116   if (m_storageTextureSupported) { | 1118   ColorBufferParameters parameters; | 
| 1117     GLenum internalStorageFormat = GL_NONE; | 1119   GLuint imageId = 0; | 
| 1118     if (internalformat == GL_RGB) { | 1120   if (shouldUseChromiumImage()) { | 
| 1119       internalStorageFormat = GL_RGB8; | 1121     parameters = gpuMemoryBufferColorBufferParameters(); | 
| 1120     } else if (internalformat == GL_RGBA) { | 1122     imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( | 
| 1121       internalStorageFormat = GL_RGBA8; | 1123         size.width(), size.height(), parameters.creationInternalColorFormat, | 
| 1122     } else { | 1124         GC3D_SCANOUT_CHROMIUM); | 
| 1123       NOTREACHED(); | 1125   } else { | 
| 1124     } | 1126     parameters = textureColorBufferParameters(); | 
| 1125     m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat, width, |  | 
| 1126                           height); |  | 
| 1127     return; |  | 
| 1128   } | 1127   } | 
| 1129   m_gl->TexImage2D(target, 0, internalformat, width, height, border, format, |  | 
| 1130                    type, 0); |  | 
| 1131 } |  | 
| 1132 | 1128 | 
| 1133 void DrawingBuffer::clearChromiumImageAlpha(const ColorBuffer& info) { | 1129   // Allocate the texture for this object. | 
| 1134   if (m_wantAlphaChannel) | 1130   GLuint textureId = 0; | 
| 1135     return; | 1131   { | 
| 1136   if (!contextProvider()->getCapabilities().chromium_image_rgb_emulation) | 1132     m_gl->GenTextures(1, &textureId); | 
| 1137     return; | 1133     m_gl->BindTexture(parameters.target, textureId); | 
|  | 1134     m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 
|  | 1135     m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 
|  | 1136     m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 
|  | 1137     m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 
|  | 1138   } | 
| 1138 | 1139 | 
| 1139   GLuint fbo = 0; | 1140   // If this is GpuMemoryBuffer-backed, then bind the texture to the | 
| 1140   m_gl->GenFramebuffers(1, &fbo); | 1141   // GpuMemoryBuffer's GLImage. Otherwise, allocate ordinary texture storage. | 
| 1141   m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); |  | 
| 1142   m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |  | 
| 1143                              info.parameters.target, info.textureId, 0); |  | 
| 1144   m_gl->ClearColor(0, 0, 0, 1); |  | 
| 1145   m_gl->ColorMask(false, false, false, true); |  | 
| 1146   m_gl->Clear(GL_COLOR_BUFFER_BIT); |  | 
| 1147   m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |  | 
| 1148                              info.parameters.target, 0, 0); |  | 
| 1149   m_gl->DeleteFramebuffers(1, &fbo); |  | 
| 1150   restoreFramebufferBindings(); |  | 
| 1151   m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], |  | 
| 1152                    m_clearColor[3]); |  | 
| 1153   m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], |  | 
| 1154                   m_colorMask[3]); |  | 
| 1155 } |  | 
| 1156 |  | 
| 1157 RefPtr<DrawingBuffer::ColorBuffer> |  | 
| 1158 DrawingBuffer::createTextureAndAllocateMemory(const IntSize& size) { |  | 
| 1159   if (!shouldUseChromiumImage()) |  | 
| 1160     return createDefaultTextureAndAllocateMemory(size); |  | 
| 1161 |  | 
| 1162   TextureParameters parameters = chromiumImageTextureParameters(); |  | 
| 1163   GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( |  | 
| 1164       size.width(), size.height(), parameters.creationInternalColorFormat, |  | 
| 1165       GC3D_SCANOUT_CHROMIUM); |  | 
| 1166   GLuint textureId = createColorTexture(parameters); |  | 
| 1167   if (imageId) { | 1142   if (imageId) { | 
| 1168     m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId); | 1143     m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId); | 
|  | 1144   } else { | 
|  | 1145     if (m_storageTextureSupported) { | 
|  | 1146       GLenum internalStorageFormat = GL_NONE; | 
|  | 1147       if (parameters.creationInternalColorFormat == GL_RGB) { | 
|  | 1148         internalStorageFormat = GL_RGB8; | 
|  | 1149       } else if (parameters.creationInternalColorFormat == GL_RGBA) { | 
|  | 1150         internalStorageFormat = GL_RGBA8; | 
|  | 1151       } else { | 
|  | 1152         NOTREACHED(); | 
|  | 1153       } | 
|  | 1154       m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat, | 
|  | 1155                             size.width(), size.height()); | 
|  | 1156     } else { | 
|  | 1157       m_gl->TexImage2D(parameters.target, 0, | 
|  | 1158                        parameters.creationInternalColorFormat, size.width(), | 
|  | 1159                        size.height(), 0, parameters.colorFormat, | 
|  | 1160                        GL_UNSIGNED_BYTE, 0); | 
|  | 1161     } | 
| 1169   } | 1162   } | 
| 1170 | 1163 | 
| 1171   RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size))); | 1164   // Clear the alpha channel if this is RGB emulated. | 
| 1172   info->textureId = textureId; | 1165   if (imageId && !m_wantAlphaChannel && | 
| 1173   info->imageId = imageId; | 1166       contextProvider()->getCapabilities().chromium_image_rgb_emulation) { | 
| 1174   clearChromiumImageAlpha(*info); | 1167     GLuint fbo = 0; | 
| 1175   return info; |  | 
| 1176 } |  | 
| 1177 | 1168 | 
| 1178 RefPtr<DrawingBuffer::ColorBuffer> | 1169     m_stateRestorer->setClearStateDirty(); | 
| 1179 DrawingBuffer::createDefaultTextureAndAllocateMemory(const IntSize& size) { | 1170     m_gl->GenFramebuffers(1, &fbo); | 
| 1180   TextureParameters parameters = defaultTextureParameters(); | 1171     m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 
| 1181   RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size))); | 1172     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 1182   info->textureId = createColorTexture(parameters); | 1173                                parameters.target, textureId, 0); | 
| 1183   allocateConditionallyImmutableTexture( | 1174     m_gl->ClearColor(0, 0, 0, 1); | 
| 1184       parameters.target, parameters.creationInternalColorFormat, size.width(), | 1175     m_gl->ColorMask(false, false, false, true); | 
| 1185       size.height(), 0, parameters.colorFormat, GL_UNSIGNED_BYTE); | 1176     m_gl->Clear(GL_COLOR_BUFFER_BIT); | 
| 1186   return info; | 1177     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
|  | 1178                                parameters.target, 0, 0); | 
|  | 1179     m_gl->DeleteFramebuffers(1, &fbo); | 
|  | 1180   } | 
|  | 1181 | 
|  | 1182   return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId)); | 
| 1187 } | 1183 } | 
| 1188 | 1184 | 
| 1189 void DrawingBuffer::attachColorBufferToReadFramebuffer() { | 1185 void DrawingBuffer::attachColorBufferToReadFramebuffer() { | 
|  | 1186   m_stateRestorer->setFramebufferBindingDirty(); | 
|  | 1187   m_stateRestorer->setTextureBindingDirty(); | 
|  | 1188 | 
| 1190   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 1189   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 1191 | 1190 | 
| 1192   GLenum target = m_backColorBuffer->parameters.target; | 1191   GLenum target = m_backColorBuffer->parameters.target; | 
| 1193   GLenum id = m_backColorBuffer->textureId; | 1192   GLenum id = m_backColorBuffer->textureId; | 
| 1194 | 1193 | 
| 1195   m_gl->BindTexture(target, id); | 1194   m_gl->BindTexture(target, id); | 
| 1196 | 1195 | 
| 1197   if (m_antiAliasingMode == MSAAImplicitResolve) | 1196   if (m_antiAliasingMode == MSAAImplicitResolve) | 
| 1198     m_gl->FramebufferTexture2DMultisampleEXT( | 1197     m_gl->FramebufferTexture2DMultisampleEXT( | 
| 1199         GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount); | 1198         GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount); | 
| 1200   else | 1199   else | 
| 1201     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, | 1200     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, | 
| 1202                                0); | 1201                                0); | 
| 1203 |  | 
| 1204   restoreTextureBindings(); |  | 
| 1205   restoreFramebufferBindings(); |  | 
| 1206 } | 1202 } | 
| 1207 | 1203 | 
| 1208 bool DrawingBuffer::wantExplicitResolve() { | 1204 bool DrawingBuffer::wantExplicitResolve() { | 
| 1209   return m_antiAliasingMode == MSAAExplicitResolve; | 1205   return m_antiAliasingMode == MSAAExplicitResolve; | 
| 1210 } | 1206 } | 
| 1211 | 1207 | 
| 1212 bool DrawingBuffer::wantDepthOrStencil() { | 1208 bool DrawingBuffer::wantDepthOrStencil() { | 
| 1213   return m_wantDepth || m_wantStencil; | 1209   return m_wantDepth || m_wantStencil; | 
| 1214 } | 1210 } | 
| 1215 | 1211 | 
| 1216 GLenum DrawingBuffer::getMultisampledRenderbufferFormat() { | 1212 GLenum DrawingBuffer::getMultisampledRenderbufferFormat() { | 
| 1217   DCHECK(wantExplicitResolve()); | 1213   DCHECK(wantExplicitResolve()); | 
| 1218   if (m_wantAlphaChannel) | 1214   if (m_wantAlphaChannel) | 
| 1219     return GL_RGBA8_OES; | 1215     return GL_RGBA8_OES; | 
| 1220   if (shouldUseChromiumImage() && | 1216   if (shouldUseChromiumImage() && | 
| 1221       contextProvider()->getCapabilities().chromium_image_rgb_emulation) | 1217       contextProvider()->getCapabilities().chromium_image_rgb_emulation) | 
| 1222     return GL_RGBA8_OES; | 1218     return GL_RGBA8_OES; | 
| 1223   if (contextProvider() | 1219   if (contextProvider() | 
| 1224           ->getCapabilities() | 1220           ->getCapabilities() | 
| 1225           .disable_webgl_rgb_multisampling_usage) | 1221           .disable_webgl_rgb_multisampling_usage) | 
| 1226     return GL_RGBA8_OES; | 1222     return GL_RGBA8_OES; | 
| 1227   return GL_RGB8_OES; | 1223   return GL_RGB8_OES; | 
| 1228 } | 1224 } | 
| 1229 | 1225 | 
| 1230 void DrawingBuffer::restoreTextureBindings() { | 1226 DrawingBuffer::ScopedStateRestorer::ScopedStateRestorer( | 
| 1231   // This class potentially modifies the bindings for GL_TEXTURE_2D and | 1227     DrawingBuffer* drawingBuffer) | 
| 1232   // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since | 1228     : m_drawingBuffer(drawingBuffer) { | 
| 1233   // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. | 1229   DCHECK(!m_drawingBuffer->m_stateRestorer); | 
| 1234   m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); | 1230   m_drawingBuffer->m_stateRestorer = this; | 
|  | 1231 } | 
|  | 1232 | 
|  | 1233 DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() { | 
|  | 1234   m_drawingBuffer->m_stateRestorer = nullptr; | 
|  | 1235   if (!m_drawingBuffer->m_stateTracker) | 
|  | 1236     return; | 
|  | 1237 | 
|  | 1238   gpu::gles2::GLES2Interface* gl = m_drawingBuffer->m_gl; | 
|  | 1239   DrawingBufferRestoreState restoreState; | 
|  | 1240   m_drawingBuffer->m_stateTracker->GetDrawingBufferRestoreState(&restoreState); | 
|  | 1241 | 
|  | 1242   if (m_clearStateDirty) { | 
|  | 1243     if (restoreState.scissorEnabled) | 
|  | 1244       gl->Enable(GL_SCISSOR_TEST); | 
|  | 1245     else | 
|  | 1246       gl->Disable(GL_SCISSOR_TEST); | 
|  | 1247     gl->ClearColor(restoreState.clearColor[0], restoreState.clearColor[1], | 
|  | 1248                    restoreState.clearColor[2], restoreState.clearColor[3]); | 
|  | 1249     gl->ClearDepthf(restoreState.clearDepth); | 
|  | 1250     gl->ClearStencil(restoreState.clearStencil); | 
|  | 1251 | 
|  | 1252     gl->ColorMask(restoreState.colorMask[0], restoreState.colorMask[1], | 
|  | 1253                   restoreState.colorMask[2], restoreState.colorMask[3]); | 
|  | 1254     gl->DepthMask(restoreState.depthMask); | 
|  | 1255     gl->StencilMaskSeparate(GL_FRONT, restoreState.stencilMask); | 
|  | 1256   } | 
|  | 1257   if (m_pixelPackAlignmentDirty) | 
|  | 1258     gl->PixelStorei(GL_PACK_ALIGNMENT, restoreState.packAlignment); | 
|  | 1259   if (m_textureBindingDirty) | 
|  | 1260     gl->BindTexture(GL_TEXTURE_2D, restoreState.activeTexture2DBinding); | 
|  | 1261   if (m_renderbufferBindingDirty) | 
|  | 1262     gl->BindRenderbuffer(GL_RENDERBUFFER, restoreState.renderbufferBinding); | 
|  | 1263   if (m_framebufferBindingDirty) { | 
|  | 1264     if (restoreState.drawFramebufferBinding == | 
|  | 1265         restoreState.readFramebufferBinding) { | 
|  | 1266       gl->BindFramebuffer(GL_FRAMEBUFFER, restoreState.drawFramebufferBinding); | 
|  | 1267     } else { | 
|  | 1268       gl->BindFramebuffer(GL_READ_FRAMEBUFFER, | 
|  | 1269                           restoreState.readFramebufferBinding); | 
|  | 1270       gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, | 
|  | 1271                           restoreState.drawFramebufferBinding); | 
|  | 1272     } | 
|  | 1273   } | 
|  | 1274   if (m_pixelUnpackBufferBindingDirty) { | 
|  | 1275     gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, | 
|  | 1276                    restoreState.pixelUnpackBufferBinding); | 
|  | 1277   } | 
| 1235 } | 1278 } | 
| 1236 | 1279 | 
| 1237 bool DrawingBuffer::shouldUseChromiumImage() { | 1280 bool DrawingBuffer::shouldUseChromiumImage() { | 
| 1238   return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && | 1281   return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && | 
| 1239          m_chromiumImageUsage == AllowChromiumImage; | 1282          m_chromiumImageUsage == AllowChromiumImage; | 
| 1240 } | 1283 } | 
| 1241 | 1284 | 
| 1242 }  // namespace blink | 1285 }  // namespace blink | 
| OLD | NEW | 
|---|