Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / graphics / gpu / DrawingBuffer.cpp
index 68772af..cde2ebc 100644 (file)
@@ -49,7 +49,7 @@
 
 using namespace std;
 
-namespace WebCore {
+namespace blink {
 
 namespace {
 // Global resource ceiling (expressed in terms of pixels) for DrawingBuffer creation and resize.
@@ -66,7 +66,7 @@ DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, drawingBufferCounter, ("Dra
 
 class ScopedTextureUnit0BindingRestorer {
 public:
-    ScopedTextureUnit0BindingRestorer(blink::WebGraphicsContext3D* context, GLenum activeTextureUnit, Platform3DObject textureUnitZeroId)
+    ScopedTextureUnit0BindingRestorer(WebGraphicsContext3D* context, GLenum activeTextureUnit, Platform3DObject textureUnitZeroId)
         : m_context(context)
         , m_oldActiveTextureUnit(activeTextureUnit)
         , m_oldTextureUnitZeroId(textureUnitZeroId)
@@ -80,14 +80,14 @@ public:
     }
 
 private:
-    blink::WebGraphicsContext3D* m_context;
+    WebGraphicsContext3D* m_context;
     GLenum m_oldActiveTextureUnit;
     Platform3DObject m_oldTextureUnitZeroId;
 };
 
 } // namespace
 
-PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<blink::WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, blink::WebGraphicsContext3D::Attributes requestedAttributes, PassRefPtr<ContextEvictionManager> contextEvictionManager)
+PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, WebGraphicsContext3D::Attributes requestedAttributes, PassRefPtr<ContextEvictionManager> contextEvictionManager)
 {
     ASSERT(context);
     OwnPtr<Extensions3DUtil> extensionsUtil = Extensions3DUtil::create(context.get());
@@ -116,12 +116,12 @@ PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<blink::WebGraphicsCon
     return drawingBuffer.release();
 }
 
-DrawingBuffer::DrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D> context,
+DrawingBuffer::DrawingBuffer(PassOwnPtr<WebGraphicsContext3D> context,
     PassOwnPtr<Extensions3DUtil> extensionsUtil,
     bool multisampleExtensionSupported,
     bool packedDepthStencilExtensionSupported,
     PreserveDrawingBuffer preserve,
-    blink::WebGraphicsContext3D::Attributes requestedAttributes,
+    WebGraphicsContext3D::Attributes requestedAttributes,
     PassRefPtr<ContextEvictionManager> contextEvictionManager)
     : m_preserveDrawingBuffer(preserve)
     , m_scissorEnabled(false)
@@ -188,12 +188,12 @@ void DrawingBuffer::markLayerComposited()
     m_layerComposited = true;
 }
 
-blink::WebGraphicsContext3D* DrawingBuffer::context()
+WebGraphicsContext3D* DrawingBuffer::context()
 {
     return m_context.get();
 }
 
-bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, blink::WebExternalBitmap* bitmap)
+bool DrawingBuffer::prepareMailbox(WebExternalTextureMailbox* outMailbox, WebExternalBitmap* bitmap)
 {
     if (!m_contentsChanged)
         return false;
@@ -264,8 +264,7 @@ bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox,
 
     m_contentsChanged = false;
 
-    m_context->bindTexture(GL_TEXTURE_2D, frontColorBufferMailbox->textureInfo.textureId);
-    m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, frontColorBufferMailbox->mailbox.name);
+    m_context->produceTextureDirectCHROMIUM(frontColorBufferMailbox->textureInfo.textureId, GL_TEXTURE_2D, frontColorBufferMailbox->mailbox.name);
     m_context->flush();
     frontColorBufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint();
     frontColorBufferMailbox->mailbox.allowOverlay = frontColorBufferMailbox->textureInfo.imageId != 0;
@@ -279,9 +278,9 @@ bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox,
     return true;
 }
 
-void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mailbox)
+void DrawingBuffer::mailboxReleased(const WebExternalTextureMailbox& mailbox, bool lostResource)
 {
-    if (m_destructionInProgress) {
+    if (m_destructionInProgress || m_context->isContextLost() || lostResource) {
         mailboxReleasedWhileDestructionInProgress(mailbox);
         return;
     }
@@ -299,7 +298,7 @@ void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mail
     ASSERT_NOT_REACHED();
 }
 
-void DrawingBuffer::mailboxReleasedWhileDestructionInProgress(const blink::WebExternalTextureMailbox& mailbox)
+void DrawingBuffer::mailboxReleasedWhileDestructionInProgress(const WebExternalTextureMailbox& mailbox)
 {
     ASSERT(m_textureMailboxes.size());
     m_context->makeContextCurrent();
@@ -313,7 +312,14 @@ PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox()
     if (m_recycledMailboxQueue.isEmpty())
         return PassRefPtr<MailboxInfo>();
 
-    blink::WebExternalTextureMailbox mailbox = m_recycledMailboxQueue.takeLast();
+    WebExternalTextureMailbox mailbox;
+    while (!m_recycledMailboxQueue.isEmpty()) {
+        mailbox = m_recycledMailboxQueue.takeLast();
+        // Never have more than one mailbox in the released state.
+        if (!m_recycledMailboxQueue.isEmpty())
+            deleteMailbox(mailbox);
+    }
+
     RefPtr<MailboxInfo> mailboxInfo;
     for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
         if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) {
@@ -347,7 +353,7 @@ PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(const Tex
     return returnMailbox.release();
 }
 
-void DrawingBuffer::deleteMailbox(const blink::WebExternalTextureMailbox& mailbox)
+void DrawingBuffer::deleteMailbox(const WebExternalTextureMailbox& mailbox)
 {
     for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
         if (nameEquals(m_textureMailboxes[i]->mailbox, mailbox)) {
@@ -414,17 +420,17 @@ bool DrawingBuffer::initialize(const IntSize& size)
     // If that succeeds, we then see what we actually got and update our actual attributes to reflect that.
     m_actualAttributes = m_requestedAttributes;
     if (m_requestedAttributes.alpha) {
-        blink::WGC3Dint alphaBits = 0;
+        WGC3Dint alphaBits = 0;
         m_context->getIntegerv(GL_ALPHA_BITS, &alphaBits);
         m_actualAttributes.alpha = alphaBits > 0;
     }
     if (m_requestedAttributes.depth) {
-        blink::WGC3Dint depthBits = 0;
+        WGC3Dint depthBits = 0;
         m_context->getIntegerv(GL_DEPTH_BITS, &depthBits);
         m_actualAttributes.depth = depthBits > 0;
     }
     if (m_requestedAttributes.stencil) {
-        blink::WGC3Dint stencilBits = 0;
+        WGC3Dint stencilBits = 0;
         m_context->getIntegerv(GL_STENCIL_BITS, &stencilBits);
         m_actualAttributes.stencil = stencilBits > 0;
     }
@@ -432,13 +438,13 @@ bool DrawingBuffer::initialize(const IntSize& size)
     return true;
 }
 
-bool DrawingBuffer::copyToPlatformTexture(blink::WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, bool fromFrontBuffer)
+bool DrawingBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY, bool fromFrontBuffer)
 {
     if (!m_context->makeContextCurrent())
         return false;
 
     GLint textureId = m_colorBuffer.textureId;
-    if (fromFrontBuffer)
+    if (fromFrontBuffer && m_frontColorBuffer.textureId)
         textureId = m_frontColorBuffer.textureId;
 
     if (m_contentsChanged) {
@@ -497,10 +503,10 @@ Platform3DObject DrawingBuffer::framebuffer() const
     return m_fbo;
 }
 
-blink::WebLayer* DrawingBuffer::platformLayer()
+WebLayer* DrawingBuffer::platformLayer()
 {
     if (!m_layer) {
-        m_layer = adoptPtr(blink::Platform::current()->compositorSupport()->createExternalTextureLayer(this));
+        m_layer = adoptPtr(Platform::current()->compositorSupport()->createExternalTextureLayer(this));
 
         m_layer->setOpaque(!m_actualAttributes.alpha);
         m_layer->setBlendBackgroundColor(m_actualAttributes.alpha);
@@ -522,57 +528,37 @@ void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer)
     if (tex) {
         RefPtr<MailboxInfo> bufferMailbox = adoptRef(new MailboxInfo());
         m_context->genMailboxCHROMIUM(bufferMailbox->mailbox.name);
-        m_context->bindTexture(GL_TEXTURE_2D, m_frontColorBuffer.textureId);
-        m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, bufferMailbox->mailbox.name);
+        m_context->produceTextureDirectCHROMIUM(m_frontColorBuffer.textureId, GL_TEXTURE_2D, bufferMailbox->mailbox.name);
         m_context->flush();
 
         bufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint();
-        OwnPtr<blink::WebGraphicsContext3DProvider> provider =
-            adoptPtr(blink::Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
+        OwnPtr<WebGraphicsContext3DProvider> provider =
+            adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
         if (!provider)
             return;
-        blink::WebGraphicsContext3D* context = provider->context3d();
+        WebGraphicsContext3D* context = provider->context3d();
         if (!context || !context->makeContextCurrent())
             return;
 
-        Platform3DObject sourceTexture = context->createTexture();
-        GLint boundTexture = 0;
-        context->getIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
-        context->bindTexture(GL_TEXTURE_2D, sourceTexture);
         context->waitSyncPoint(bufferMailbox->mailbox.syncPoint);
-        context->consumeTextureCHROMIUM(GL_TEXTURE_2D, bufferMailbox->mailbox.name);
+        Platform3DObject sourceTexture = context->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, bufferMailbox->mailbox.name);
         context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture,
             tex, 0, GL_RGBA, GL_UNSIGNED_BYTE);
-        context->bindTexture(GL_TEXTURE_2D, boundTexture);
         context->deleteTexture(sourceTexture);
         context->flush();
         m_context->waitSyncPoint(context->insertSyncPoint());
         return;
     }
 
-    // Since the m_frontColorBuffer was produced and sent to the compositor, it cannot be bound to an fbo.
-    // We have to make a copy of it here and bind that copy instead.
-    // FIXME: That's not true any more, provided we don't change texture
-    // parameters.
-    unsigned sourceTexture = createColorTexture();
-    texImage2DResourceSafe(GL_TEXTURE_2D, 0, m_internalColorFormat, m_size.width(), m_size.height(), 0, m_colorFormat, GL_UNSIGNED_BYTE);
-    m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer.textureId, sourceTexture, 0, GL_RGBA, GL_UNSIGNED_BYTE);
-
-    // Since we're using the same context as WebGL, we have to restore any state we change (in this case, just the framebuffer binding).
-    // FIXME: The WebGLRenderingContext tracks the current framebuffer binding, it would be slightly more efficient to use this value
-    // rather than querying it off of the context.
-    GLint previousFramebuffer = 0;
-    m_context->getIntegerv(GL_FRAMEBUFFER_BINDING, &previousFramebuffer);
-
     Platform3DObject framebuffer = m_context->createFramebuffer();
     m_context->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
-    m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sourceTexture, 0);
+    // We don't need to bind a copy of m_frontColorBuffer since the texture parameters are untouched.
+    m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_frontColorBuffer.textureId, 0);
 
     paintFramebufferToCanvas(framebuffer, size().width(), size().height(), !m_actualAttributes.premultipliedAlpha, imageBuffer);
     m_context->deleteFramebuffer(framebuffer);
-    m_context->deleteTexture(sourceTexture);
-
-    m_context->bindFramebuffer(GL_FRAMEBUFFER, previousFramebuffer);
+    // Since we're using the same context as WebGL, we have to restore any state we change (in this case, just the framebuffer binding).
+    restoreFramebufferBinding();
 }
 
 void DrawingBuffer::clearPlatformLayer()
@@ -961,7 +947,7 @@ void DrawingBuffer::paintFramebufferToCanvas(int framebuffer, int width, int hei
 
     const SkBitmap& canvasBitmap = imageBuffer->bitmap();
     const SkBitmap* readbackBitmap = 0;
-    ASSERT(canvasBitmap.colorType() == kPMColor_SkColorType);
+    ASSERT(canvasBitmap.colorType() == kN32_SkColorType);
     if (canvasBitmap.width() == width && canvasBitmap.height() == height) {
         // This is the fastest and most common case. We read back
         // directly into the canvas's backing store.
@@ -1072,4 +1058,4 @@ void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info)
     }
 }
 
-} // namespace WebCore
+} // namespace blink