| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 52 #include "wtf/typed_arrays/ArrayBufferContents.h" | 52 #include "wtf/typed_arrays/ArrayBufferContents.h" | 
| 53 #include <algorithm> | 53 #include <algorithm> | 
| 54 #include <memory> | 54 #include <memory> | 
| 55 | 55 | 
| 56 namespace blink { | 56 namespace blink { | 
| 57 | 57 | 
| 58 namespace { | 58 namespace { | 
| 59 | 59 | 
| 60 const float s_resourceAdjustedRatio = 0.5; | 60 const float s_resourceAdjustedRatio = 0.5; | 
| 61 | 61 | 
| 62 class ScopedTextureUnit0BindingRestorer { |  | 
| 63   STACK_ALLOCATED(); |  | 
| 64   WTF_MAKE_NONCOPYABLE(ScopedTextureUnit0BindingRestorer); |  | 
| 65 |  | 
| 66  public: |  | 
| 67   ScopedTextureUnit0BindingRestorer(gpu::gles2::GLES2Interface* gl, |  | 
| 68                                     GLenum activeTextureUnit, |  | 
| 69                                     GLuint textureUnitZeroId) |  | 
| 70       : m_gl(gl), |  | 
| 71         m_oldActiveTextureUnit(activeTextureUnit), |  | 
| 72         m_oldTextureUnitZeroId(textureUnitZeroId) { |  | 
| 73     m_gl->ActiveTexture(GL_TEXTURE0); |  | 
| 74   } |  | 
| 75   ~ScopedTextureUnit0BindingRestorer() { |  | 
| 76     m_gl->BindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId); |  | 
| 77     m_gl->ActiveTexture(m_oldActiveTextureUnit); |  | 
| 78   } |  | 
| 79 |  | 
| 80  private: |  | 
| 81   gpu::gles2::GLES2Interface* m_gl; |  | 
| 82   GLenum m_oldActiveTextureUnit; |  | 
| 83   GLuint m_oldTextureUnitZeroId; |  | 
| 84 }; |  | 
| 85 |  | 
| 86 static bool shouldFailDrawingBufferCreationForTesting = false; | 62 static bool shouldFailDrawingBufferCreationForTesting = false; | 
| 87 | 63 | 
| 88 }  // namespace | 64 }  // namespace | 
| 89 | 65 | 
| 90 PassRefPtr<DrawingBuffer> DrawingBuffer::create( | 66 PassRefPtr<DrawingBuffer> DrawingBuffer::create( | 
| 91     std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 67     std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 
|  | 68     Client* client, | 
| 92     const IntSize& size, | 69     const IntSize& size, | 
| 93     bool premultipliedAlpha, | 70     bool premultipliedAlpha, | 
| 94     bool wantAlphaChannel, | 71     bool wantAlphaChannel, | 
| 95     bool wantDepthBuffer, | 72     bool wantDepthBuffer, | 
| 96     bool wantStencilBuffer, | 73     bool wantStencilBuffer, | 
| 97     bool wantAntialiasing, | 74     bool wantAntialiasing, | 
| 98     PreserveDrawingBuffer preserve, | 75     PreserveDrawingBuffer preserve, | 
| 99     WebGLVersion webGLVersion, | 76     WebGLVersion webGLVersion, | 
| 100     ChromiumImageUsage chromiumImageUsage) { | 77     ChromiumImageUsage chromiumImageUsage) { | 
| 101   ASSERT(contextProvider); | 78   ASSERT(contextProvider); | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 128     else | 105     else | 
| 129       extensionsUtil->ensureExtensionEnabled( | 106       extensionsUtil->ensureExtensionEnabled( | 
| 130           "GL_EXT_multisampled_render_to_texture"); | 107           "GL_EXT_multisampled_render_to_texture"); | 
| 131   } | 108   } | 
| 132   bool discardFramebufferSupported = | 109   bool discardFramebufferSupported = | 
| 133       extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer"); | 110       extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer"); | 
| 134   if (discardFramebufferSupported) | 111   if (discardFramebufferSupported) | 
| 135     extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); | 112     extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); | 
| 136 | 113 | 
| 137   RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer( | 114   RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer( | 
| 138       std::move(contextProvider), std::move(extensionsUtil), | 115       std::move(contextProvider), std::move(extensionsUtil), client, | 
| 139       discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha, | 116       discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha, | 
| 140       preserve, webGLVersion, wantDepthBuffer, wantStencilBuffer, | 117       preserve, webGLVersion, wantDepthBuffer, wantStencilBuffer, | 
| 141       chromiumImageUsage)); | 118       chromiumImageUsage)); | 
| 142   if (!drawingBuffer->initialize(size, multisampleSupported)) { | 119   if (!drawingBuffer->initialize(size, multisampleSupported)) { | 
| 143     drawingBuffer->beginDestruction(); | 120     drawingBuffer->beginDestruction(); | 
| 144     return PassRefPtr<DrawingBuffer>(); | 121     return PassRefPtr<DrawingBuffer>(); | 
| 145   } | 122   } | 
| 146   return drawingBuffer.release(); | 123   return drawingBuffer.release(); | 
| 147 } | 124 } | 
| 148 | 125 | 
| 149 void DrawingBuffer::forceNextDrawingBufferCreationToFail() { | 126 void DrawingBuffer::forceNextDrawingBufferCreationToFail() { | 
| 150   shouldFailDrawingBufferCreationForTesting = true; | 127   shouldFailDrawingBufferCreationForTesting = true; | 
| 151 } | 128 } | 
| 152 | 129 | 
| 153 DrawingBuffer::DrawingBuffer( | 130 DrawingBuffer::DrawingBuffer( | 
| 154     std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 131     std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, | 
| 155     std::unique_ptr<Extensions3DUtil> extensionsUtil, | 132     std::unique_ptr<Extensions3DUtil> extensionsUtil, | 
|  | 133     Client* client, | 
| 156     bool discardFramebufferSupported, | 134     bool discardFramebufferSupported, | 
| 157     bool wantAlphaChannel, | 135     bool wantAlphaChannel, | 
| 158     bool premultipliedAlpha, | 136     bool premultipliedAlpha, | 
| 159     PreserveDrawingBuffer preserve, | 137     PreserveDrawingBuffer preserve, | 
| 160     WebGLVersion webGLVersion, | 138     WebGLVersion webGLVersion, | 
| 161     bool wantDepth, | 139     bool wantDepth, | 
| 162     bool wantStencil, | 140     bool wantStencil, | 
| 163     ChromiumImageUsage chromiumImageUsage) | 141     ChromiumImageUsage chromiumImageUsage) | 
| 164     : m_preserveDrawingBuffer(preserve), | 142     : m_client(client), | 
|  | 143       m_preserveDrawingBuffer(preserve), | 
| 165       m_webGLVersion(webGLVersion), | 144       m_webGLVersion(webGLVersion), | 
| 166       m_contextProvider(std::move(contextProvider)), | 145       m_contextProvider(std::move(contextProvider)), | 
| 167       m_gl(m_contextProvider->contextGL()), | 146       m_gl(m_contextProvider->contextGL()), | 
| 168       m_extensionsUtil(std::move(extensionsUtil)), | 147       m_extensionsUtil(std::move(extensionsUtil)), | 
| 169       m_discardFramebufferSupported(discardFramebufferSupported), | 148       m_discardFramebufferSupported(discardFramebufferSupported), | 
| 170       m_wantAlphaChannel(wantAlphaChannel), | 149       m_wantAlphaChannel(wantAlphaChannel), | 
| 171       m_premultipliedAlpha(premultipliedAlpha), | 150       m_premultipliedAlpha(premultipliedAlpha), | 
| 172       m_softwareRendering(m_contextProvider->isSoftwareRendering()), | 151       m_softwareRendering(m_contextProvider->isSoftwareRendering()), | 
| 173       m_wantDepth(wantDepth), | 152       m_wantDepth(wantDepth), | 
| 174       m_wantStencil(wantStencil), | 153       m_wantStencil(wantStencil), | 
| 175       m_chromiumImageUsage(chromiumImageUsage) { | 154       m_chromiumImageUsage(chromiumImageUsage) { | 
| 176   memset(m_colorMask, 0, 4 * sizeof(GLboolean)); |  | 
| 177   memset(m_clearColor, 0, 4 * sizeof(GLfloat)); |  | 
| 178   // Used by browser tests to detect the use of a DrawingBuffer. | 155   // Used by browser tests to detect the use of a DrawingBuffer. | 
| 179   TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", | 156   TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", | 
| 180                        TRACE_EVENT_SCOPE_GLOBAL); | 157                        TRACE_EVENT_SCOPE_GLOBAL); | 
| 181 } | 158 } | 
| 182 | 159 | 
| 183 DrawingBuffer::~DrawingBuffer() { | 160 DrawingBuffer::~DrawingBuffer() { | 
| 184   DCHECK(m_destructionInProgress); | 161   DCHECK(m_destructionInProgress); | 
| 185   m_layer.reset(); | 162   m_layer.reset(); | 
| 186   m_contextProvider.reset(); | 163   m_contextProvider.reset(); | 
| 187 } | 164 } | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 221 | 198 | 
| 222 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { | 199 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { | 
| 223   if (m_filterQuality != filterQuality) { | 200   if (m_filterQuality != filterQuality) { | 
| 224     m_filterQuality = filterQuality; | 201     m_filterQuality = filterQuality; | 
| 225     if (m_layer) | 202     if (m_layer) | 
| 226       m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); | 203       m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); | 
| 227   } | 204   } | 
| 228 } | 205 } | 
| 229 | 206 | 
| 230 bool DrawingBuffer::requiresAlphaChannelToBePreserved() { | 207 bool DrawingBuffer::requiresAlphaChannelToBePreserved() { | 
| 231   return !m_drawFramebufferBinding && | 208   return m_client->DrawingBufferClientIsBoundForDraw() && | 
| 232          defaultBufferRequiresAlphaChannelToBePreserved(); | 209          defaultBufferRequiresAlphaChannelToBePreserved(); | 
| 233 } | 210 } | 
| 234 | 211 | 
| 235 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() { | 212 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() { | 
| 236   if (wantExplicitResolve()) { | 213   if (wantExplicitResolve()) { | 
| 237     return !m_wantAlphaChannel && | 214     return !m_wantAlphaChannel && | 
| 238            getMultisampledRenderbufferFormat() == GL_RGBA8_OES; | 215            getMultisampledRenderbufferFormat() == GL_RGBA8_OES; | 
| 239   } | 216   } | 
| 240 | 217 | 
| 241   bool rgbEmulation = | 218   bool rgbEmulation = | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 257     DCHECK(recycled.size == m_size); | 234     DCHECK(recycled.size == m_size); | 
| 258     return std::move(recycled.bitmap); | 235     return std::move(recycled.bitmap); | 
| 259   } | 236   } | 
| 260 | 237 | 
| 261   return Platform::current()->allocateSharedBitmap(m_size); | 238   return Platform::current()->allocateSharedBitmap(m_size); | 
| 262 } | 239 } | 
| 263 | 240 | 
| 264 bool DrawingBuffer::PrepareTextureMailbox( | 241 bool DrawingBuffer::PrepareTextureMailbox( | 
| 265     cc::TextureMailbox* outMailbox, | 242     cc::TextureMailbox* outMailbox, | 
| 266     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 243     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 
|  | 244   ScopedStateRestorer scopedStateRestorer(this); | 
| 267   bool forceGpuResult = false; | 245   bool forceGpuResult = false; | 
| 268   return prepareTextureMailboxInternal(outMailbox, outReleaseCallback, | 246   return prepareTextureMailboxInternal(outMailbox, outReleaseCallback, | 
| 269                                        forceGpuResult); | 247                                        forceGpuResult); | 
| 270 } | 248 } | 
| 271 | 249 | 
| 272 bool DrawingBuffer::prepareTextureMailboxInternal( | 250 bool DrawingBuffer::prepareTextureMailboxInternal( | 
| 273     cc::TextureMailbox* outMailbox, | 251     cc::TextureMailbox* outMailbox, | 
| 274     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, | 252     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, | 
| 275     bool forceGpuResult) { | 253     bool forceGpuResult) { | 
| 276   if (m_destructionInProgress) { | 254   if (m_destructionInProgress) { | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 291   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) | 269   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) | 
| 292     return false; | 270     return false; | 
| 293 | 271 | 
| 294   TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); | 272   TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); | 
| 295 | 273 | 
| 296   if (m_newMailboxCallback) | 274   if (m_newMailboxCallback) | 
| 297     (*m_newMailboxCallback)(); | 275     (*m_newMailboxCallback)(); | 
| 298 | 276 | 
| 299   // Resolve the multisampled buffer into m_backColorBuffer texture. | 277   // Resolve the multisampled buffer into m_backColorBuffer texture. | 
| 300   if (m_antiAliasingMode != None) | 278   if (m_antiAliasingMode != None) | 
| 301     commit(); | 279     resolveMultisampleFramebufferInternal(); | 
| 302 | 280 | 
| 303   if (m_softwareRendering && !forceGpuResult) { | 281   if (m_softwareRendering && !forceGpuResult) { | 
| 304     return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback); | 282     return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback); | 
| 305   } else { | 283   } else { | 
| 306     return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback); | 284     return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback); | 
| 307   } | 285   } | 
| 308 } | 286 } | 
| 309 | 287 | 
| 310 bool DrawingBuffer::finishPrepareTextureMailboxSoftware( | 288 bool DrawingBuffer::finishPrepareTextureMailboxSoftware( | 
| 311     cc::TextureMailbox* outMailbox, | 289     cc::TextureMailbox* outMailbox, | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 336                         WTF::passed(std::move(bitmap)), m_size); | 314                         WTF::passed(std::move(bitmap)), m_size); | 
| 337   *outReleaseCallback = | 315   *outReleaseCallback = | 
| 338       cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); | 316       cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); | 
| 339   return true; | 317   return true; | 
| 340 } | 318 } | 
| 341 | 319 | 
| 342 bool DrawingBuffer::finishPrepareTextureMailboxGpu( | 320 bool DrawingBuffer::finishPrepareTextureMailboxGpu( | 
| 343     cc::TextureMailbox* outMailbox, | 321     cc::TextureMailbox* outMailbox, | 
| 344     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 322     std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { | 
| 345   if (m_webGLVersion > WebGL1) { | 323   if (m_webGLVersion > WebGL1) { | 
|  | 324     m_stateRestorer->setPixelUnpackBufferBindingDirty(); | 
| 346     m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 325     m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 
| 347   } | 326   } | 
| 348 | 327 | 
| 349   // We must restore the texture binding since creating new textures, |  | 
| 350   // consuming and producing mailboxes changes it. |  | 
| 351   ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, |  | 
| 352                                              m_texture2DBinding); |  | 
| 353 |  | 
| 354   // Specify the buffer that we will put in the mailbox. | 328   // Specify the buffer that we will put in the mailbox. | 
| 355   RefPtr<ColorBuffer> colorBufferForMailbox; | 329   RefPtr<ColorBuffer> colorBufferForMailbox; | 
| 356   if (m_preserveDrawingBuffer == Discard) { | 330   if (m_preserveDrawingBuffer == Discard) { | 
| 357     // If we can discard the backbuffer, send the old backbuffer directly | 331     // If we can discard the backbuffer, send the old backbuffer directly | 
| 358     // into the mailbox, and allocate (or recycle) a new backbuffer. | 332     // into the mailbox, and allocate (or recycle) a new backbuffer. | 
| 359     colorBufferForMailbox = m_backColorBuffer; | 333     colorBufferForMailbox = m_backColorBuffer; | 
| 360     m_backColorBuffer = createOrRecycleColorBuffer(); | 334     m_backColorBuffer = createOrRecycleColorBuffer(); | 
| 361     attachColorBufferToReadFramebuffer(); | 335     attachColorBufferToReadFramebuffer(); | 
| 362 | 336 | 
| 363     // Explicitly specify that m_fbo (which is now bound to the just-allocated | 337     // Explicitly specify that m_fbo (which is now bound to the just-allocated | 
| 364     // m_backColorBuffer) is not initialized, to save GPU memory bandwidth for | 338     // m_backColorBuffer) is not initialized, to save GPU memory bandwidth for | 
| 365     // tile-based GPU architectures. | 339     // tile-based GPU architectures. | 
| 366     if (m_discardFramebufferSupported) { | 340     if (m_discardFramebufferSupported) { | 
| 367       const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, | 341       const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, | 
| 368                                      GL_STENCIL_ATTACHMENT}; | 342                                      GL_STENCIL_ATTACHMENT}; | 
|  | 343       m_stateRestorer->setFramebufferBindingDirty(); | 
| 369       m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 344       m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 370       m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); | 345       m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); | 
| 371     } | 346     } | 
| 372   } else { | 347   } else { | 
| 373     // If we can't discard the backbuffer, create (or recycle) a buffer to put | 348     // If we can't discard the backbuffer, create (or recycle) a buffer to put | 
| 374     // in the mailbox, and copy backbuffer's contents there. | 349     // in the mailbox, and copy backbuffer's contents there. | 
| 375     colorBufferForMailbox = createOrRecycleColorBuffer(); | 350     colorBufferForMailbox = createOrRecycleColorBuffer(); | 
| 376     m_gl->CopySubTextureCHROMIUM( | 351     m_gl->CopySubTextureCHROMIUM( | 
| 377         m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, | 352         m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, | 
| 378         0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); | 353         0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 406     // mailbox is released (and while the release callback is running). | 381     // mailbox is released (and while the release callback is running). | 
| 407     auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu, | 382     auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu, | 
| 408                           RefPtr<DrawingBuffer>(this), colorBufferForMailbox); | 383                           RefPtr<DrawingBuffer>(this), colorBufferForMailbox); | 
| 409     *outReleaseCallback = cc::SingleReleaseCallback::Create( | 384     *outReleaseCallback = cc::SingleReleaseCallback::Create( | 
| 410         convertToBaseCallback(std::move(func))); | 385         convertToBaseCallback(std::move(func))); | 
| 411   } | 386   } | 
| 412 | 387 | 
| 413   // Point |m_frontColorBuffer| to the buffer that we are now presenting. | 388   // Point |m_frontColorBuffer| to the buffer that we are now presenting. | 
| 414   m_frontColorBuffer = colorBufferForMailbox; | 389   m_frontColorBuffer = colorBufferForMailbox; | 
| 415 | 390 | 
| 416   // Restore any state that we may have dirtied, and update dirty bits. |  | 
| 417   restoreFramebufferBindings(); |  | 
| 418   restorePixelUnpackBufferBindings(); |  | 
| 419   m_contentsChanged = false; | 391   m_contentsChanged = false; | 
| 420   setBufferClearNeeded(true); | 392   setBufferClearNeeded(true); | 
| 421   return true; | 393   return true; | 
| 422 } | 394 } | 
| 423 | 395 | 
| 424 void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer, | 396 void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer, | 
| 425                                        const gpu::SyncToken& syncToken, | 397                                        const gpu::SyncToken& syncToken, | 
| 426                                        bool lostResource) { | 398                                        bool lostResource) { | 
| 427   // If the mailbox has been returned by the compositor then it is no | 399   // If the mailbox has been returned by the compositor then it is no | 
| 428   // longer being presented, and so is no longer the front buffer. | 400   // longer being presented, and so is no longer the front buffer. | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 457     bool lostResource) { | 429     bool lostResource) { | 
| 458   DCHECK(!syncToken.HasData());  // No sync tokens for software resources. | 430   DCHECK(!syncToken.HasData());  // No sync tokens for software resources. | 
| 459   if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) | 431   if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) | 
| 460     return;  // Just delete the bitmap. | 432     return;  // Just delete the bitmap. | 
| 461 | 433 | 
| 462   RecycledBitmap recycled = {std::move(bitmap), m_size}; | 434   RecycledBitmap recycled = {std::move(bitmap), m_size}; | 
| 463   m_recycledBitmaps.append(std::move(recycled)); | 435   m_recycledBitmaps.append(std::move(recycled)); | 
| 464 } | 436 } | 
| 465 | 437 | 
| 466 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() { | 438 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() { | 
|  | 439   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 440 | 
| 467   // This can be null if the context is lost before the first call to | 441   // This can be null if the context is lost before the first call to | 
| 468   // grContext(). | 442   // grContext(). | 
| 469   GrContext* grContext = m_contextProvider->grContext(); | 443   GrContext* grContext = m_contextProvider->grContext(); | 
| 470 | 444 | 
| 471   cc::TextureMailbox textureMailbox; | 445   cc::TextureMailbox textureMailbox; | 
| 472   std::unique_ptr<cc::SingleReleaseCallback> releaseCallback; | 446   std::unique_ptr<cc::SingleReleaseCallback> releaseCallback; | 
| 473   bool success = false; | 447   bool success = false; | 
| 474   if (grContext) { | 448   if (grContext) { | 
| 475     bool forceGpuResult = true; | 449     bool forceGpuResult = true; | 
| 476     success = prepareTextureMailboxInternal(&textureMailbox, &releaseCallback, | 450     success = prepareTextureMailboxInternal(&textureMailbox, &releaseCallback, | 
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 610                                         GLuint imageId) | 584                                         GLuint imageId) | 
| 611     : drawingBuffer(drawingBuffer), | 585     : drawingBuffer(drawingBuffer), | 
| 612       parameters(parameters), | 586       parameters(parameters), | 
| 613       size(size), | 587       size(size), | 
| 614       textureId(textureId), | 588       textureId(textureId), | 
| 615       imageId(imageId) { | 589       imageId(imageId) { | 
| 616   drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); | 590   drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); | 
| 617 } | 591 } | 
| 618 | 592 | 
| 619 DrawingBuffer::ColorBuffer::~ColorBuffer() { | 593 DrawingBuffer::ColorBuffer::~ColorBuffer() { | 
| 620   gpu::gles2::GLES2Interface* gl = drawingBuffer->contextGL(); | 594   gpu::gles2::GLES2Interface* gl = drawingBuffer->m_gl; | 
| 621   if (receiveSyncToken.HasData()) | 595   if (receiveSyncToken.HasData()) | 
| 622     gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData()); | 596     gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData()); | 
| 623   if (imageId) { | 597   if (imageId) { | 
| 624     gl->BindTexture(parameters.target, textureId); | 598     gl->BindTexture(parameters.target, textureId); | 
| 625     gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId); | 599     gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId); | 
| 626     gl->DestroyImageCHROMIUM(imageId); | 600     gl->DestroyImageCHROMIUM(imageId); | 
|  | 601     switch (parameters.target) { | 
|  | 602       case GL_TEXTURE_2D: | 
|  | 603         // Restore the texture binding for GL_TEXTURE_2D, since the client will | 
|  | 604         // expect the previous state. | 
|  | 605         if (drawingBuffer->m_client) | 
|  | 606           drawingBuffer->m_client->DrawingBufferClientRestoreTexture2DBinding(); | 
|  | 607         break; | 
|  | 608       case GC3D_TEXTURE_RECTANGLE_ARB: | 
|  | 609         // Rectangle textures aren't exposed to WebGL, so don't bother | 
|  | 610         // restoring this state (there is no meaningful way to restore it). | 
|  | 611         break; | 
|  | 612       default: | 
|  | 613         NOTREACHED(); | 
|  | 614         break; | 
|  | 615     } | 
| 627   } | 616   } | 
| 628   gl->DeleteTextures(1, &textureId); | 617   gl->DeleteTextures(1, &textureId); | 
| 629 } | 618 } | 
| 630 | 619 | 
| 631 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) { | 620 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) { | 
|  | 621   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 622 | 
| 632   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 623   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 
| 633     // Need to try to restore the context again later. | 624     // Need to try to restore the context again later. | 
| 634     return false; | 625     return false; | 
| 635   } | 626   } | 
| 636 | 627 | 
| 637   m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); | 628   m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); | 
| 638 | 629 | 
| 639   int maxSampleCount = 0; | 630   int maxSampleCount = 0; | 
| 640   m_antiAliasingMode = None; | 631   m_antiAliasingMode = None; | 
| 641   if (useMultisampling) { | 632   if (useMultisampling) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 653   // The Linux ATI bot fails | 644   // The Linux ATI bot fails | 
| 654   // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage | 645   // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage | 
| 655   // textures only if ScreenSpaceAntialiasing is enabled, because | 646   // textures only if ScreenSpaceAntialiasing is enabled, because | 
| 656   // ScreenSpaceAntialiasing is much faster with storage textures. | 647   // ScreenSpaceAntialiasing is much faster with storage textures. | 
| 657   m_storageTextureSupported = | 648   m_storageTextureSupported = | 
| 658       (m_webGLVersion > WebGL1 || | 649       (m_webGLVersion > WebGL1 || | 
| 659        m_extensionsUtil->supportsExtension("GL_EXT_texture_storage")) && | 650        m_extensionsUtil->supportsExtension("GL_EXT_texture_storage")) && | 
| 660       m_antiAliasingMode == ScreenSpaceAntialiasing; | 651       m_antiAliasingMode == ScreenSpaceAntialiasing; | 
| 661   m_sampleCount = std::min(4, maxSampleCount); | 652   m_sampleCount = std::min(4, maxSampleCount); | 
| 662 | 653 | 
|  | 654   m_stateRestorer->setFramebufferBindingDirty(); | 
| 663   m_gl->GenFramebuffers(1, &m_fbo); | 655   m_gl->GenFramebuffers(1, &m_fbo); | 
| 664   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 656   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 665   if (wantExplicitResolve()) { | 657   if (wantExplicitResolve()) { | 
| 666     m_gl->GenFramebuffers(1, &m_multisampleFBO); | 658     m_gl->GenFramebuffers(1, &m_multisampleFBO); | 
| 667     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 659     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 
| 668     m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer); | 660     m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer); | 
| 669   } | 661   } | 
| 670   if (!reset(size)) | 662   if (!resizeFramebufferInternal(size)) | 
| 671     return false; | 663     return false; | 
| 672 | 664 | 
| 673   if (m_depthStencilBuffer) { | 665   if (m_depthStencilBuffer) { | 
| 674     DCHECK(wantDepthOrStencil()); | 666     DCHECK(wantDepthOrStencil()); | 
| 675     m_hasImplicitStencilBuffer = !m_wantStencil; | 667     m_hasImplicitStencilBuffer = !m_wantStencil; | 
| 676   } | 668   } | 
| 677 | 669 | 
| 678   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 670   if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { | 
| 679     // It's possible that the drawing buffer allocation provokes a context loss, | 671     // It's possible that the drawing buffer allocation provokes a context loss, | 
| 680     // so check again just in case. http://crbug.com/512302 | 672     // so check again just in case. http://crbug.com/512302 | 
| 681     return false; | 673     return false; | 
| 682   } | 674   } | 
| 683 | 675 | 
| 684   return true; | 676   return true; | 
| 685 } | 677 } | 
| 686 | 678 | 
| 687 bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl, | 679 bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl, | 
| 688                                           GLuint texture, | 680                                           GLuint texture, | 
| 689                                           GLenum internalFormat, | 681                                           GLenum internalFormat, | 
| 690                                           GLenum destType, | 682                                           GLenum destType, | 
| 691                                           GLint level, | 683                                           GLint level, | 
| 692                                           bool premultiplyAlpha, | 684                                           bool premultiplyAlpha, | 
| 693                                           bool flipY, | 685                                           bool flipY, | 
| 694                                           SourceDrawingBuffer sourceBuffer) { | 686                                           SourceDrawingBuffer sourceBuffer) { | 
|  | 687   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 688 | 
| 695   if (m_contentsChanged) { | 689   if (m_contentsChanged) { | 
| 696     if (m_antiAliasingMode != None) { | 690     if (m_antiAliasingMode != None) | 
| 697       commit(); | 691       resolveMultisampleFramebufferInternal(); | 
| 698       restoreFramebufferBindings(); |  | 
| 699     } |  | 
| 700     m_gl->Flush(); | 692     m_gl->Flush(); | 
| 701   } | 693   } | 
| 702 | 694 | 
| 703   // Assume that the destination target is GL_TEXTURE_2D. | 695   // Assume that the destination target is GL_TEXTURE_2D. | 
| 704   if (!Extensions3DUtil::canUseCopyTextureCHROMIUM( | 696   if (!Extensions3DUtil::canUseCopyTextureCHROMIUM( | 
| 705           GL_TEXTURE_2D, internalFormat, destType, level)) | 697           GL_TEXTURE_2D, internalFormat, destType, level)) | 
| 706     return false; | 698     return false; | 
| 707 | 699 | 
| 708   // Contexts may be in a different share group. We must transfer the texture | 700   // Contexts may be in a different share group. We must transfer the texture | 
| 709   // through a mailbox first. | 701   // through a mailbox first. | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 745   const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 737   const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); | 
| 746 | 738 | 
| 747   gl->Flush(); | 739   gl->Flush(); | 
| 748   gpu::SyncToken syncToken; | 740   gpu::SyncToken syncToken; | 
| 749   gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); | 741   gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); | 
| 750   m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData()); | 742   m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData()); | 
| 751 | 743 | 
| 752   return true; | 744   return true; | 
| 753 } | 745 } | 
| 754 | 746 | 
| 755 GLuint DrawingBuffer::framebuffer() const { |  | 
| 756   return m_fbo; |  | 
| 757 } |  | 
| 758 |  | 
| 759 WebLayer* DrawingBuffer::platformLayer() { | 747 WebLayer* DrawingBuffer::platformLayer() { | 
| 760   if (!m_layer) { | 748   if (!m_layer) { | 
| 761     m_layer = | 749     m_layer = | 
| 762         Platform::current()->compositorSupport()->createExternalTextureLayer( | 750         Platform::current()->compositorSupport()->createExternalTextureLayer( | 
| 763             this); | 751             this); | 
| 764 | 752 | 
| 765     m_layer->setOpaque(!m_wantAlphaChannel); | 753     m_layer->setOpaque(!m_wantAlphaChannel); | 
| 766     m_layer->setBlendBackgroundColor(m_wantAlphaChannel); | 754     m_layer->setBlendBackgroundColor(m_wantAlphaChannel); | 
| 767     m_layer->setPremultipliedAlpha(m_premultipliedAlpha); | 755     m_layer->setPremultipliedAlpha(m_premultipliedAlpha); | 
| 768     m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); | 756     m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 802 | 790 | 
| 803   m_backColorBuffer = nullptr; | 791   m_backColorBuffer = nullptr; | 
| 804   m_frontColorBuffer = nullptr; | 792   m_frontColorBuffer = nullptr; | 
| 805   m_multisampleRenderbuffer = 0; | 793   m_multisampleRenderbuffer = 0; | 
| 806   m_depthStencilBuffer = 0; | 794   m_depthStencilBuffer = 0; | 
| 807   m_multisampleFBO = 0; | 795   m_multisampleFBO = 0; | 
| 808   m_fbo = 0; | 796   m_fbo = 0; | 
| 809 | 797 | 
| 810   if (m_layer) | 798   if (m_layer) | 
| 811     GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 799     GraphicsLayer::unregisterContentsLayer(m_layer->layer()); | 
|  | 800 | 
|  | 801   m_client = nullptr; | 
| 812 } | 802 } | 
| 813 | 803 | 
| 814 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { | 804 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { | 
| 815   // Recreate m_backColorBuffer. | 805   // Recreate m_backColorBuffer. | 
| 816   m_backColorBuffer = createColorBuffer(size); | 806   m_backColorBuffer = createColorBuffer(size); | 
| 817 | 807 | 
| 818   attachColorBufferToReadFramebuffer(); | 808   attachColorBufferToReadFramebuffer(); | 
| 819 | 809 | 
| 820   if (wantExplicitResolve()) { | 810   if (wantExplicitResolve()) { | 
|  | 811     m_stateRestorer->setFramebufferBindingDirty(); | 
|  | 812     m_stateRestorer->setRenderbufferBindingDirty(); | 
| 821     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 813     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 
| 822     m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); | 814     m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); | 
| 823     m_gl->RenderbufferStorageMultisampleCHROMIUM( | 815     m_gl->RenderbufferStorageMultisampleCHROMIUM( | 
| 824         GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), | 816         GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), | 
| 825         size.width(), size.height()); | 817         size.width(), size.height()); | 
| 826 | 818 | 
| 827     if (m_gl->GetError() == GL_OUT_OF_MEMORY) | 819     if (m_gl->GetError() == GL_OUT_OF_MEMORY) | 
| 828       return false; | 820       return false; | 
| 829 | 821 | 
| 830     m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 822     m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 831                                   GL_RENDERBUFFER, m_multisampleRenderbuffer); | 823                                   GL_RENDERBUFFER, m_multisampleRenderbuffer); | 
| 832   } | 824   } | 
| 833 | 825 | 
| 834   if (wantDepthOrStencil()) { | 826   if (wantDepthOrStencil()) { | 
|  | 827     m_stateRestorer->setFramebufferBindingDirty(); | 
|  | 828     m_stateRestorer->setRenderbufferBindingDirty(); | 
| 835     m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 829     m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 
| 836                           m_multisampleFBO ? m_multisampleFBO : m_fbo); | 830                           m_multisampleFBO ? m_multisampleFBO : m_fbo); | 
| 837     if (!m_depthStencilBuffer) | 831     if (!m_depthStencilBuffer) | 
| 838       m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); | 832       m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); | 
| 839     m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 833     m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); | 
| 840     if (m_antiAliasingMode == MSAAImplicitResolve) { | 834     if (m_antiAliasingMode == MSAAImplicitResolve) { | 
| 841       m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, | 835       m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, | 
| 842                                               GL_DEPTH24_STENCIL8_OES, | 836                                               GL_DEPTH24_STENCIL8_OES, | 
| 843                                               size.width(), size.height()); | 837                                               size.width(), size.height()); | 
| 844     } else if (m_antiAliasingMode == MSAAExplicitResolve) { | 838     } else if (m_antiAliasingMode == MSAAExplicitResolve) { | 
| 845       m_gl->RenderbufferStorageMultisampleCHROMIUM( | 839       m_gl->RenderbufferStorageMultisampleCHROMIUM( | 
| 846           GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), | 840           GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), | 
| 847           size.height()); | 841           size.height()); | 
| 848     } else { | 842     } else { | 
| 849       m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, | 843       m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, | 
| 850                                 size.width(), size.height()); | 844                                 size.width(), size.height()); | 
| 851     } | 845     } | 
| 852     // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we | 846     // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we | 
| 853     // emulate | 847     // emulate | 
| 854     // it at the command buffer level for WebGL contexts. | 848     // it at the command buffer level for WebGL contexts. | 
| 855     m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, | 849     m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, | 
| 856                                   GL_RENDERBUFFER, m_depthStencilBuffer); | 850                                   GL_RENDERBUFFER, m_depthStencilBuffer); | 
| 857     m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); | 851     m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); | 
| 858   } | 852   } | 
| 859 | 853 | 
| 860   if (wantExplicitResolve()) { | 854   if (wantExplicitResolve()) { | 
|  | 855     m_stateRestorer->setFramebufferBindingDirty(); | 
| 861     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 856     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); | 
| 862     if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | 857     if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) | 
| 863       return false; | 858       return false; | 
| 864   } | 859   } | 
| 865 | 860 | 
|  | 861   m_stateRestorer->setFramebufferBindingDirty(); | 
| 866   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 862   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 867   return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == | 863   return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == | 
| 868          GL_FRAMEBUFFER_COMPLETE; | 864          GL_FRAMEBUFFER_COMPLETE; | 
| 869 } | 865 } | 
| 870 | 866 | 
| 871 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) { | 867 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) { | 
|  | 868   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 869   clearFramebuffersInternal(clearMask); | 
|  | 870 } | 
|  | 871 | 
|  | 872 void DrawingBuffer::clearFramebuffersInternal(GLbitfield clearMask) { | 
|  | 873   m_stateRestorer->setFramebufferBindingDirty(); | 
| 872   // We will clear the multisample FBO, but we also need to clear the | 874   // We will clear the multisample FBO, but we also need to clear the | 
| 873   // non-multisampled buffer. | 875   // non-multisampled buffer. | 
| 874   if (m_multisampleFBO) { | 876   if (m_multisampleFBO) { | 
| 875     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 877     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 876     m_gl->Clear(GL_COLOR_BUFFER_BIT); | 878     m_gl->Clear(GL_COLOR_BUFFER_BIT); | 
| 877   } | 879   } | 
| 878 | 880 | 
| 879   m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 881   m_gl->BindFramebuffer(GL_FRAMEBUFFER, | 
| 880                         m_multisampleFBO ? m_multisampleFBO : m_fbo); | 882                         m_multisampleFBO ? m_multisampleFBO : m_fbo); | 
| 881   m_gl->Clear(clearMask); | 883   m_gl->Clear(clearMask); | 
| 882 } | 884 } | 
| 883 | 885 | 
| 884 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, | 886 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, | 
| 885                                   const IntSize& curSize, | 887                                   const IntSize& curSize, | 
| 886                                   int maxTextureSize) { | 888                                   int maxTextureSize) { | 
| 887   IntSize adjustedSize = desiredSize; | 889   IntSize adjustedSize = desiredSize; | 
| 888 | 890 | 
| 889   // Clamp if the desired size is greater than the maximum texture size for the | 891   // Clamp if the desired size is greater than the maximum texture size for the | 
| 890   // device. | 892   // device. | 
| 891   if (adjustedSize.height() > maxTextureSize) | 893   if (adjustedSize.height() > maxTextureSize) | 
| 892     adjustedSize.setHeight(maxTextureSize); | 894     adjustedSize.setHeight(maxTextureSize); | 
| 893 | 895 | 
| 894   if (adjustedSize.width() > maxTextureSize) | 896   if (adjustedSize.width() > maxTextureSize) | 
| 895     adjustedSize.setWidth(maxTextureSize); | 897     adjustedSize.setWidth(maxTextureSize); | 
| 896 | 898 | 
| 897   return adjustedSize; | 899   return adjustedSize; | 
| 898 } | 900 } | 
| 899 | 901 | 
| 900 bool DrawingBuffer::reset(const IntSize& newSize) { | 902 bool DrawingBuffer::resize(const IntSize& newSize) { | 
|  | 903   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 904   return resizeFramebufferInternal(newSize); | 
|  | 905 } | 
|  | 906 | 
|  | 907 bool DrawingBuffer::resizeFramebufferInternal(const IntSize& newSize) { | 
| 901   CHECK(!newSize.isEmpty()); | 908   CHECK(!newSize.isEmpty()); | 
| 902   IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); | 909   IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); | 
| 903   if (adjustedSize.isEmpty()) | 910   if (adjustedSize.isEmpty()) | 
| 904     return false; | 911     return false; | 
| 905 | 912 | 
| 906   if (adjustedSize != m_size) { | 913   if (adjustedSize != m_size) { | 
| 907     do { | 914     do { | 
| 908       if (!resizeDefaultFramebuffer(adjustedSize)) { | 915       if (!resizeDefaultFramebuffer(adjustedSize)) { | 
| 909         adjustedSize.scale(s_resourceAdjustedRatio); | 916         adjustedSize.scale(s_resourceAdjustedRatio); | 
| 910         continue; | 917         continue; | 
| 911       } | 918       } | 
| 912       break; | 919       break; | 
| 913     } while (!adjustedSize.isEmpty()); | 920     } while (!adjustedSize.isEmpty()); | 
| 914 | 921 | 
| 915     m_size = adjustedSize; | 922     m_size = adjustedSize; | 
| 916     // Free all mailboxes, because they are now of the wrong size. Only the | 923     // Free all mailboxes, because they are now of the wrong size. Only the | 
| 917     // first call in this loop has any effect. | 924     // first call in this loop has any effect. | 
| 918     m_recycledColorBufferQueue.clear(); | 925     m_recycledColorBufferQueue.clear(); | 
| 919     m_recycledBitmaps.clear(); | 926     m_recycledBitmaps.clear(); | 
| 920 | 927 | 
| 921     if (adjustedSize.isEmpty()) | 928     if (adjustedSize.isEmpty()) | 
| 922       return false; | 929       return false; | 
| 923   } | 930   } | 
| 924 | 931 | 
|  | 932   m_stateRestorer->setClearStateDirty(); | 
| 925   m_gl->Disable(GL_SCISSOR_TEST); | 933   m_gl->Disable(GL_SCISSOR_TEST); | 
| 926   m_gl->ClearColor(0, 0, 0, | 934   m_gl->ClearColor(0, 0, 0, | 
| 927                    defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); | 935                    defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); | 
| 928   m_gl->ColorMask(true, true, true, true); | 936   m_gl->ColorMask(true, true, true, true); | 
| 929 | 937 | 
| 930   GLbitfield clearMask = GL_COLOR_BUFFER_BIT; | 938   GLbitfield clearMask = GL_COLOR_BUFFER_BIT; | 
| 931   if (!!m_depthStencilBuffer) { | 939   if (!!m_depthStencilBuffer) { | 
| 932     m_gl->ClearDepthf(1.0f); | 940     m_gl->ClearDepthf(1.0f); | 
| 933     clearMask |= GL_DEPTH_BUFFER_BIT; | 941     clearMask |= GL_DEPTH_BUFFER_BIT; | 
| 934     m_gl->DepthMask(true); | 942     m_gl->DepthMask(true); | 
| 935   } | 943   } | 
| 936   if (!!m_depthStencilBuffer) { | 944   if (!!m_depthStencilBuffer) { | 
| 937     m_gl->ClearStencil(0); | 945     m_gl->ClearStencil(0); | 
| 938     clearMask |= GL_STENCIL_BUFFER_BIT; | 946     clearMask |= GL_STENCIL_BUFFER_BIT; | 
| 939     m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); | 947     m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); | 
| 940   } | 948   } | 
| 941 | 949 | 
| 942   clearFramebuffers(clearMask); | 950   clearFramebuffersInternal(clearMask); | 
| 943   return true; | 951   return true; | 
| 944 } | 952 } | 
| 945 | 953 | 
| 946 void DrawingBuffer::commit() { | 954 void DrawingBuffer::resolveAndBindForReadAndDraw() { | 
|  | 955   { | 
|  | 956     ScopedStateRestorer scopedStateRestorer(this); | 
|  | 957     resolveMultisampleFramebufferInternal(); | 
|  | 958   } | 
|  | 959   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
|  | 960 } | 
|  | 961 | 
|  | 962 void DrawingBuffer::resolveMultisampleFramebufferInternal() { | 
|  | 963   m_stateRestorer->setFramebufferBindingDirty(); | 
| 947   if (wantExplicitResolve() && !m_contentsChangeCommitted) { | 964   if (wantExplicitResolve() && !m_contentsChangeCommitted) { | 
|  | 965     m_stateRestorer->setClearStateDirty(); | 
| 948     m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); | 966     m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); | 
| 949     m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); | 967     m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); | 
| 950 | 968     m_gl->Disable(GL_SCISSOR_TEST); | 
| 951     if (m_scissorEnabled) |  | 
| 952       m_gl->Disable(GL_SCISSOR_TEST); |  | 
| 953 | 969 | 
| 954     int width = m_size.width(); | 970     int width = m_size.width(); | 
| 955     int height = m_size.height(); | 971     int height = m_size.height(); | 
| 956     // Use NEAREST, because there is no scale performed during the blit. | 972     // Use NEAREST, because there is no scale performed during the blit. | 
| 957     GLuint filter = GL_NEAREST; | 973     GLuint filter = GL_NEAREST; | 
| 958 | 974 | 
| 959     m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height, | 975     m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height, | 
| 960                                   GL_COLOR_BUFFER_BIT, filter); | 976                                   GL_COLOR_BUFFER_BIT, filter); | 
| 961 | 977 | 
| 962     // On old AMD GPUs on OS X, glColorMask doesn't work correctly for | 978     // On old AMD GPUs on OS X, glColorMask doesn't work correctly for | 
| 963     // multisampled renderbuffers and the alpha channel can be overwritten. | 979     // multisampled renderbuffers and the alpha channel can be overwritten. | 
| 964     // Clear the alpha channel of |m_fbo|. | 980     // Clear the alpha channel of |m_fbo|. | 
| 965     if (defaultBufferRequiresAlphaChannelToBePreserved() && | 981     if (defaultBufferRequiresAlphaChannelToBePreserved() && | 
| 966         contextProvider() | 982         contextProvider() | 
| 967             ->getCapabilities() | 983             ->getCapabilities() | 
| 968             .disable_multisampling_color_mask_usage) { | 984             .disable_multisampling_color_mask_usage) { | 
| 969       m_gl->ClearColor(0, 0, 0, 1); | 985       m_gl->ClearColor(0, 0, 0, 1); | 
| 970       m_gl->ColorMask(false, false, false, true); | 986       m_gl->ColorMask(false, false, false, true); | 
| 971       m_gl->Clear(GL_COLOR_BUFFER_BIT); |  | 
| 972 |  | 
| 973       m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], |  | 
| 974                        m_clearColor[3]); |  | 
| 975       m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], |  | 
| 976                       m_colorMask[3]); |  | 
| 977     } | 987     } | 
| 978 |  | 
| 979     if (m_scissorEnabled) |  | 
| 980       m_gl->Enable(GL_SCISSOR_TEST); |  | 
| 981   } | 988   } | 
| 982 | 989 | 
| 983   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 990   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 984   if (m_antiAliasingMode == ScreenSpaceAntialiasing) { | 991   if (m_antiAliasingMode == ScreenSpaceAntialiasing) | 
| 985     m_gl->ApplyScreenSpaceAntialiasingCHROMIUM(); | 992     m_gl->ApplyScreenSpaceAntialiasingCHROMIUM(); | 
| 986   } |  | 
| 987   m_contentsChangeCommitted = true; | 993   m_contentsChangeCommitted = true; | 
| 988 } | 994 } | 
| 989 | 995 | 
| 990 void DrawingBuffer::restorePixelUnpackBufferBindings() { | 996 void DrawingBuffer::restoreFramebufferBindings() { | 
| 991   if (m_webGLVersion > WebGL1) { | 997   m_client->DrawingBufferClientRestoreFramebufferBinding(); | 
| 992     m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixelUnpackBufferBinding); |  | 
| 993   } |  | 
| 994 } | 998 } | 
| 995 | 999 | 
| 996 void DrawingBuffer::restoreFramebufferBindings() { | 1000 void DrawingBuffer::restoreAllState() { | 
| 997   if (m_drawFramebufferBinding && m_readFramebufferBinding) { | 1001   m_client->DrawingBufferClientRestoreScissorTest(); | 
| 998     if (m_drawFramebufferBinding == m_readFramebufferBinding) { | 1002   m_client->DrawingBufferClientRestoreMaskAndClearValues(); | 
| 999       m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_readFramebufferBinding); | 1003   m_client->DrawingBufferClientRestorePixelPackAlignment(); | 
| 1000     } else { | 1004   m_client->DrawingBufferClientRestoreTexture2DBinding(); | 
| 1001       m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding); | 1005   m_client->DrawingBufferClientRestoreRenderbufferBinding(); | 
| 1002       m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding); | 1006   m_client->DrawingBufferClientRestoreFramebufferBinding(); | 
| 1003     } | 1007   m_client->DrawingBufferClientRestorePixelUnpackBufferBinding(); | 
| 1004     return; |  | 
| 1005   } |  | 
| 1006   if (!m_drawFramebufferBinding && !m_readFramebufferBinding) { |  | 
| 1007     bind(GL_FRAMEBUFFER); |  | 
| 1008     return; |  | 
| 1009   } |  | 
| 1010   if (!m_drawFramebufferBinding) { |  | 
| 1011     bind(GL_DRAW_FRAMEBUFFER); |  | 
| 1012     m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding); |  | 
| 1013   } else { |  | 
| 1014     bind(GL_READ_FRAMEBUFFER); |  | 
| 1015     m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding); |  | 
| 1016   } |  | 
| 1017 } | 1008 } | 
| 1018 | 1009 | 
| 1019 bool DrawingBuffer::multisample() const { | 1010 bool DrawingBuffer::multisample() const { | 
| 1020   return m_antiAliasingMode != None; | 1011   return m_antiAliasingMode != None; | 
| 1021 } | 1012 } | 
| 1022 | 1013 | 
| 1023 void DrawingBuffer::bind(GLenum target) { | 1014 void DrawingBuffer::bind(GLenum target) { | 
| 1024   m_gl->BindFramebuffer(target, | 1015   m_gl->BindFramebuffer(target, | 
| 1025                         wantExplicitResolve() ? m_multisampleFBO : m_fbo); | 1016                         wantExplicitResolve() ? m_multisampleFBO : m_fbo); | 
| 1026 } | 1017 } | 
| 1027 | 1018 | 
| 1028 void DrawingBuffer::setPackAlignment(GLint param) { |  | 
| 1029   m_packAlignment = param; |  | 
| 1030 } |  | 
| 1031 |  | 
| 1032 bool DrawingBuffer::paintRenderingResultsToImageData( | 1019 bool DrawingBuffer::paintRenderingResultsToImageData( | 
| 1033     int& width, | 1020     int& width, | 
| 1034     int& height, | 1021     int& height, | 
| 1035     SourceDrawingBuffer sourceBuffer, | 1022     SourceDrawingBuffer sourceBuffer, | 
| 1036     WTF::ArrayBufferContents& contents) { | 1023     WTF::ArrayBufferContents& contents) { | 
|  | 1024   ScopedStateRestorer scopedStateRestorer(this); | 
|  | 1025 | 
| 1037   ASSERT(!m_premultipliedAlpha); | 1026   ASSERT(!m_premultipliedAlpha); | 
| 1038   width = size().width(); | 1027   width = size().width(); | 
| 1039   height = size().height(); | 1028   height = size().height(); | 
| 1040 | 1029 | 
| 1041   CheckedNumeric<int> dataSize = 4; | 1030   CheckedNumeric<int> dataSize = 4; | 
| 1042   dataSize *= width; | 1031   dataSize *= width; | 
| 1043   dataSize *= height; | 1032   dataSize *= height; | 
| 1044   if (!dataSize.IsValid()) | 1033   if (!dataSize.IsValid()) | 
| 1045     return false; | 1034     return false; | 
| 1046 | 1035 | 
| 1047   WTF::ArrayBufferContents pixels(width * height, 4, | 1036   WTF::ArrayBufferContents pixels(width * height, 4, | 
| 1048                                   WTF::ArrayBufferContents::NotShared, | 1037                                   WTF::ArrayBufferContents::NotShared, | 
| 1049                                   WTF::ArrayBufferContents::DontInitialize); | 1038                                   WTF::ArrayBufferContents::DontInitialize); | 
| 1050 | 1039 | 
| 1051   GLuint fbo = 0; | 1040   GLuint fbo = 0; | 
|  | 1041   m_stateRestorer->setFramebufferBindingDirty(); | 
| 1052   if (sourceBuffer == FrontBuffer && m_frontColorBuffer) { | 1042   if (sourceBuffer == FrontBuffer && m_frontColorBuffer) { | 
| 1053     m_gl->GenFramebuffers(1, &fbo); | 1043     m_gl->GenFramebuffers(1, &fbo); | 
| 1054     m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 1044     m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 
| 1055     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1045     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 1056                                m_frontColorBuffer->parameters.target, | 1046                                m_frontColorBuffer->parameters.target, | 
| 1057                                m_frontColorBuffer->textureId, 0); | 1047                                m_frontColorBuffer->textureId, 0); | 
| 1058   } else { | 1048   } else { | 
| 1059     m_gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer()); | 1049     m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 1060   } | 1050   } | 
| 1061 | 1051 | 
| 1062   readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, | 1052   readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, | 
| 1063                       ReadbackRGBA, WebGLImageConversion::AlphaDoNothing); | 1053                       ReadbackRGBA, WebGLImageConversion::AlphaDoNothing); | 
| 1064   flipVertically(static_cast<uint8_t*>(pixels.data()), width, height); | 1054   flipVertically(static_cast<uint8_t*>(pixels.data()), width, height); | 
| 1065 | 1055 | 
| 1066   if (fbo) { | 1056   if (fbo) { | 
| 1067     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1057     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 1068                                m_frontColorBuffer->parameters.target, 0, 0); | 1058                                m_frontColorBuffer->parameters.target, 0, 0); | 
| 1069     m_gl->DeleteFramebuffers(1, &fbo); | 1059     m_gl->DeleteFramebuffers(1, &fbo); | 
| 1070   } | 1060   } | 
| 1071 | 1061 | 
| 1072   restoreFramebufferBindings(); |  | 
| 1073 |  | 
| 1074   pixels.transfer(contents); | 1062   pixels.transfer(contents); | 
| 1075   return true; | 1063   return true; | 
| 1076 } | 1064 } | 
| 1077 | 1065 | 
| 1078 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, | 1066 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, | 
| 1079                                         int width, | 1067                                         int width, | 
| 1080                                         int height, | 1068                                         int height, | 
| 1081                                         ReadbackOrder readbackOrder, | 1069                                         ReadbackOrder readbackOrder, | 
| 1082                                         WebGLImageConversion::AlphaOp op) { | 1070                                         WebGLImageConversion::AlphaOp op) { | 
| 1083   if (m_packAlignment > 4) | 1071   m_stateRestorer->setPixelPackAlignmentDirty(); | 
| 1084     m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1); | 1072   m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1); | 
| 1085   m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 1073   m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); | 
| 1086   if (m_packAlignment > 4) |  | 
| 1087     m_gl->PixelStorei(GL_PACK_ALIGNMENT, m_packAlignment); |  | 
| 1088 | 1074 | 
| 1089   size_t bufferSize = 4 * width * height; | 1075   size_t bufferSize = 4 * width * height; | 
| 1090 | 1076 | 
| 1091   if (readbackOrder == ReadbackSkia) { | 1077   if (readbackOrder == ReadbackSkia) { | 
| 1092 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 1078 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 
| 1093     // Swizzle red and blue channels to match SkBitmap's byte ordering. | 1079     // Swizzle red and blue channels to match SkBitmap's byte ordering. | 
| 1094     // TODO(kbr): expose GL_BGRA as extension. | 1080     // TODO(kbr): expose GL_BGRA as extension. | 
| 1095     for (size_t i = 0; i < bufferSize; i += 4) { | 1081     for (size_t i = 0; i < bufferSize; i += 4) { | 
| 1096       std::swap(pixels[i], pixels[i + 2]); | 1082       std::swap(pixels[i], pixels[i + 2]); | 
| 1097     } | 1083     } | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 1119     uint8_t* rowA = framebuffer + i * rowBytes; | 1105     uint8_t* rowA = framebuffer + i * rowBytes; | 
| 1120     uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; | 1106     uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; | 
| 1121     memcpy(scanline.data(), rowB, rowBytes); | 1107     memcpy(scanline.data(), rowB, rowBytes); | 
| 1122     memcpy(rowB, rowA, rowBytes); | 1108     memcpy(rowB, rowA, rowBytes); | 
| 1123     memcpy(rowA, scanline.data(), rowBytes); | 1109     memcpy(rowA, scanline.data(), rowBytes); | 
| 1124   } | 1110   } | 
| 1125 } | 1111 } | 
| 1126 | 1112 | 
| 1127 RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer( | 1113 RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer( | 
| 1128     const IntSize& size) { | 1114     const IntSize& size) { | 
|  | 1115   m_stateRestorer->setFramebufferBindingDirty(); | 
|  | 1116   m_stateRestorer->setTextureBindingDirty(); | 
|  | 1117 | 
| 1129   // Select the Parameters for the texture object. Allocate the backing | 1118   // Select the Parameters for the texture object. Allocate the backing | 
| 1130   // GpuMemoryBuffer and GLImage, if one is going to be used. | 1119   // GpuMemoryBuffer and GLImage, if one is going to be used. | 
| 1131   ColorBufferParameters parameters; | 1120   ColorBufferParameters parameters; | 
| 1132   GLuint imageId = 0; | 1121   GLuint imageId = 0; | 
| 1133   if (shouldUseChromiumImage()) { | 1122   if (shouldUseChromiumImage()) { | 
| 1134     parameters = gpuMemoryBufferColorBufferParameters(); | 1123     parameters = gpuMemoryBufferColorBufferParameters(); | 
| 1135     imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( | 1124     imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( | 
| 1136         size.width(), size.height(), parameters.creationInternalColorFormat, | 1125         size.width(), size.height(), parameters.creationInternalColorFormat, | 
| 1137         GC3D_SCANOUT_CHROMIUM); | 1126         GC3D_SCANOUT_CHROMIUM); | 
| 1138   } else { | 1127   } else { | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1171                        parameters.creationInternalColorFormat, size.width(), | 1160                        parameters.creationInternalColorFormat, size.width(), | 
| 1172                        size.height(), 0, parameters.colorFormat, | 1161                        size.height(), 0, parameters.colorFormat, | 
| 1173                        GL_UNSIGNED_BYTE, 0); | 1162                        GL_UNSIGNED_BYTE, 0); | 
| 1174     } | 1163     } | 
| 1175   } | 1164   } | 
| 1176 | 1165 | 
| 1177   // Clear the alpha channel if this is RGB emulated. | 1166   // Clear the alpha channel if this is RGB emulated. | 
| 1178   if (imageId && !m_wantAlphaChannel && | 1167   if (imageId && !m_wantAlphaChannel && | 
| 1179       contextProvider()->getCapabilities().chromium_image_rgb_emulation) { | 1168       contextProvider()->getCapabilities().chromium_image_rgb_emulation) { | 
| 1180     GLuint fbo = 0; | 1169     GLuint fbo = 0; | 
|  | 1170 | 
|  | 1171     m_stateRestorer->setClearStateDirty(); | 
| 1181     m_gl->GenFramebuffers(1, &fbo); | 1172     m_gl->GenFramebuffers(1, &fbo); | 
| 1182     m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 1173     m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); | 
| 1183     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1174     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 1184                                parameters.target, textureId, 0); | 1175                                parameters.target, textureId, 0); | 
| 1185     m_gl->ClearColor(0, 0, 0, 1); | 1176     m_gl->ClearColor(0, 0, 0, 1); | 
| 1186     m_gl->ColorMask(false, false, false, true); | 1177     m_gl->ColorMask(false, false, false, true); | 
| 1187     m_gl->Clear(GL_COLOR_BUFFER_BIT); | 1178     m_gl->Clear(GL_COLOR_BUFFER_BIT); | 
| 1188     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 1179     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | 
| 1189                                parameters.target, 0, 0); | 1180                                parameters.target, 0, 0); | 
| 1190     m_gl->DeleteFramebuffers(1, &fbo); | 1181     m_gl->DeleteFramebuffers(1, &fbo); | 
| 1191     restoreFramebufferBindings(); |  | 
| 1192     m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], |  | 
| 1193                      m_clearColor[3]); |  | 
| 1194     m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], |  | 
| 1195                     m_colorMask[3]); |  | 
| 1196   } | 1182   } | 
| 1197 | 1183 | 
| 1198   return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId)); | 1184   return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId)); | 
| 1199 } | 1185 } | 
| 1200 | 1186 | 
| 1201 void DrawingBuffer::attachColorBufferToReadFramebuffer() { | 1187 void DrawingBuffer::attachColorBufferToReadFramebuffer() { | 
|  | 1188   m_stateRestorer->setFramebufferBindingDirty(); | 
|  | 1189   m_stateRestorer->setTextureBindingDirty(); | 
|  | 1190 | 
| 1202   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 1191   m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); | 
| 1203 | 1192 | 
| 1204   GLenum target = m_backColorBuffer->parameters.target; | 1193   GLenum target = m_backColorBuffer->parameters.target; | 
| 1205   GLenum id = m_backColorBuffer->textureId; | 1194   GLenum id = m_backColorBuffer->textureId; | 
| 1206 | 1195 | 
| 1207   m_gl->BindTexture(target, id); | 1196   m_gl->BindTexture(target, id); | 
| 1208 | 1197 | 
| 1209   if (m_antiAliasingMode == MSAAImplicitResolve) | 1198   if (m_antiAliasingMode == MSAAImplicitResolve) | 
| 1210     m_gl->FramebufferTexture2DMultisampleEXT( | 1199     m_gl->FramebufferTexture2DMultisampleEXT( | 
| 1211         GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount); | 1200         GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount); | 
| 1212   else | 1201   else | 
| 1213     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, | 1202     m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, | 
| 1214                                0); | 1203                                0); | 
| 1215 |  | 
| 1216   restoreTextureBindings(); |  | 
| 1217   restoreFramebufferBindings(); |  | 
| 1218 } | 1204 } | 
| 1219 | 1205 | 
| 1220 bool DrawingBuffer::wantExplicitResolve() { | 1206 bool DrawingBuffer::wantExplicitResolve() { | 
| 1221   return m_antiAliasingMode == MSAAExplicitResolve; | 1207   return m_antiAliasingMode == MSAAExplicitResolve; | 
| 1222 } | 1208 } | 
| 1223 | 1209 | 
| 1224 bool DrawingBuffer::wantDepthOrStencil() { | 1210 bool DrawingBuffer::wantDepthOrStencil() { | 
| 1225   return m_wantDepth || m_wantStencil; | 1211   return m_wantDepth || m_wantStencil; | 
| 1226 } | 1212 } | 
| 1227 | 1213 | 
| 1228 GLenum DrawingBuffer::getMultisampledRenderbufferFormat() { | 1214 GLenum DrawingBuffer::getMultisampledRenderbufferFormat() { | 
| 1229   DCHECK(wantExplicitResolve()); | 1215   DCHECK(wantExplicitResolve()); | 
| 1230   if (m_wantAlphaChannel) | 1216   if (m_wantAlphaChannel) | 
| 1231     return GL_RGBA8_OES; | 1217     return GL_RGBA8_OES; | 
| 1232   if (shouldUseChromiumImage() && | 1218   if (shouldUseChromiumImage() && | 
| 1233       contextProvider()->getCapabilities().chromium_image_rgb_emulation) | 1219       contextProvider()->getCapabilities().chromium_image_rgb_emulation) | 
| 1234     return GL_RGBA8_OES; | 1220     return GL_RGBA8_OES; | 
| 1235   if (contextProvider() | 1221   if (contextProvider() | 
| 1236           ->getCapabilities() | 1222           ->getCapabilities() | 
| 1237           .disable_webgl_rgb_multisampling_usage) | 1223           .disable_webgl_rgb_multisampling_usage) | 
| 1238     return GL_RGBA8_OES; | 1224     return GL_RGBA8_OES; | 
| 1239   return GL_RGB8_OES; | 1225   return GL_RGB8_OES; | 
| 1240 } | 1226 } | 
| 1241 | 1227 | 
| 1242 void DrawingBuffer::restoreTextureBindings() { | 1228 DrawingBuffer::ScopedStateRestorer::ScopedStateRestorer( | 
| 1243   // This class potentially modifies the bindings for GL_TEXTURE_2D and | 1229     DrawingBuffer* drawingBuffer) | 
| 1244   // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since | 1230     : m_drawingBuffer(drawingBuffer) { | 
| 1245   // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. | 1231   DCHECK(!m_drawingBuffer->m_stateRestorer); | 
| 1246   m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); | 1232   m_drawingBuffer->m_stateRestorer = this; | 
|  | 1233 } | 
|  | 1234 | 
|  | 1235 DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() { | 
|  | 1236   m_drawingBuffer->m_stateRestorer = nullptr; | 
|  | 1237   Client* client = m_drawingBuffer->m_client; | 
|  | 1238   if (!client) | 
|  | 1239     return; | 
|  | 1240 | 
|  | 1241   if (m_clearStateDirty) { | 
|  | 1242     client->DrawingBufferClientRestoreScissorTest(); | 
|  | 1243     client->DrawingBufferClientRestoreMaskAndClearValues(); | 
|  | 1244   } | 
|  | 1245   if (m_pixelPackAlignmentDirty) | 
|  | 1246     client->DrawingBufferClientRestorePixelPackAlignment(); | 
|  | 1247   if (m_textureBindingDirty) | 
|  | 1248     client->DrawingBufferClientRestoreTexture2DBinding(); | 
|  | 1249   if (m_renderbufferBindingDirty) | 
|  | 1250     client->DrawingBufferClientRestoreRenderbufferBinding(); | 
|  | 1251   if (m_framebufferBindingDirty) | 
|  | 1252     client->DrawingBufferClientRestoreFramebufferBinding(); | 
|  | 1253   if (m_pixelUnpackBufferBindingDirty) | 
|  | 1254     client->DrawingBufferClientRestorePixelUnpackBufferBinding(); | 
| 1247 } | 1255 } | 
| 1248 | 1256 | 
| 1249 bool DrawingBuffer::shouldUseChromiumImage() { | 1257 bool DrawingBuffer::shouldUseChromiumImage() { | 
| 1250   return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && | 1258   return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && | 
| 1251          m_chromiumImageUsage == AllowChromiumImage; | 1259          m_chromiumImageUsage == AllowChromiumImage; | 
| 1252 } | 1260 } | 
| 1253 | 1261 | 
| 1254 }  // namespace blink | 1262 }  // namespace blink | 
| OLD | NEW | 
|---|