bool Canvas2DLayerBridge::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox, WebKit::WebExternalBitmap* bitmap) { ASSERT(!bitmap); if (!isValid()) return false; // Release to skia textures that were previouosly released by the // compositor. We do this before acquiring the next snapshot in // order to cap maximum gpu memory consumption. m_context->makeContextCurrent(); flush(); Vector<MailboxInfo>::iterator mailboxInfo; for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mailboxInfo++) { if (mailboxInfo->m_status == MailboxReleased) { if (mailboxInfo->m_mailbox.syncPoint) { context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); mailboxInfo->m_mailbox.syncPoint = 0; } // Invalidate texture state in case the compositor altered it since the copy-on-write. mailboxInfo->m_image->getTexture()->invalidateCachedState(); mailboxInfo->m_image.reset(0); mailboxInfo->m_status = MailboxAvailable; } } SkAutoTUnref<SkImage> image(m_canvas->newImageSnapshot()); // Early exit if canvas was not drawn to since last prepareMailbox if (image->uniqueID() == m_lastImageId) return false; m_lastImageId = image->uniqueID(); mailboxInfo = createMailboxInfo(); mailboxInfo->m_status = MailboxInUse; mailboxInfo->m_image.swap(&image); // Because of texture sharing with the compositor, we must invalidate // the state cached in skia so that the deferred copy on write // in SkSurface_Gpu does not make any false assumptions. mailboxInfo->m_image->getTexture()->invalidateCachedState(); ASSERT(mailboxInfo->m_mailbox.syncPoint == 0); ASSERT(mailboxInfo->m_image.get()); ASSERT(mailboxInfo->m_image->getTexture()); m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, mailboxInfo->m_image->getTexture()->getTextureHandle()); m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo->m_mailbox.name); context()->flush(); mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); // Because we are changing the texture binding without going through skia, // we must dirty the context. m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); *outMailbox = mailboxInfo->m_mailbox; return true; }
bool Canvas2DLayerBridge::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox) { #if ENABLE(CANVAS_USES_MAILBOX) // Release to skia textures that were previouosly released by the // compositor. We do this before acquiring the next snapshot in // order to cap maximum gpu memory consumption. m_context->makeContextCurrent(); Vector<MailboxInfo>::iterator mailboxInfo; for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mailboxInfo++) { if (mailboxInfo->m_status == MailboxReleased) { if (mailboxInfo->m_mailbox.syncPoint) { context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); mailboxInfo->m_mailbox.syncPoint = 0; } // Invalidate texture state in case the compositor altered it since the copy-on-write. mailboxInfo->m_image->getTexture()->invalidateCachedState(); mailboxInfo->m_image.reset(0); mailboxInfo->m_status = MailboxAvailable; } } SkAutoTUnref<SkImage> image(m_canvas->newImageSnapshot()); // Early exit if canvas was not drawn to since last prepareMailbox if (image->uniqueID() == m_lastImageId) return false; m_lastImageId = image->uniqueID(); mailboxInfo = createMailboxInfo(); mailboxInfo->m_status = MailboxInUse; mailboxInfo->m_image.swap(&image); // Because of texture sharing with the compositor, we must invalidate // the state cached in skia so that the deferred copy on write // in SkSurface_Gpu does not make any false assumptions. mailboxInfo->m_image->getTexture()->invalidateCachedState(); ASSERT(mailboxInfo->m_mailbox.syncPoint == 0); ASSERT(mailboxInfo->m_image.get()); ASSERT(mailboxInfo->m_image->getTexture()); // Because we are changing the texture binding without going through skia, // we must restore it to its previous value to keep skia's state cache in // sync. GC3Dint savedTexBinding = 0; m_context->getIntegerv(GraphicsContext3D::TEXTURE_BINDING_2D, &savedTexBinding); m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, mailboxInfo->m_image->getTexture()->getTextureHandle()); context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, mailboxInfo->m_mailbox.name); mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, savedTexBinding); *outMailbox = mailboxInfo->m_mailbox; return true; #else ASSERT_NOT_REACHED(); return false; #endif }
bool Canvas2DLayerBridge::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, blink::WebExternalBitmap* bitmap) { if (bitmap) { // Using accelerated 2d canvas with software renderer, which // should only happen in tests that use fake graphics contexts // or in Android WebView in software mode. In this case, we do // not care about producing any results for this canvas. m_canvas->silentFlush(); m_lastImageId = 0; return false; } if (!isValid()) return false; // Release to skia textures that were previouosly released by the // compositor. We do this before acquiring the next snapshot in // order to cap maximum gpu memory consumption. m_context->makeContextCurrent(); flush(); Vector<MailboxInfo>::iterator mailboxInfo; for (mailboxInfo = m_mailboxes.begin(); mailboxInfo < m_mailboxes.end(); mailboxInfo++) { if (mailboxInfo->m_status == MailboxReleased) { if (mailboxInfo->m_mailbox.syncPoint) { context()->waitSyncPoint(mailboxInfo->m_mailbox.syncPoint); mailboxInfo->m_mailbox.syncPoint = 0; } // Invalidate texture state in case the compositor altered it since the copy-on-write. mailboxInfo->m_image->getTexture()->invalidateCachedState(); mailboxInfo->m_image.reset(0); mailboxInfo->m_status = MailboxAvailable; } } SkAutoTUnref<SkImage> image(m_canvas->newImageSnapshot()); // Early exit if canvas was not drawn to since last prepareMailbox if (image->uniqueID() == m_lastImageId) return false; m_lastImageId = image->uniqueID(); mailboxInfo = createMailboxInfo(); mailboxInfo->m_status = MailboxInUse; mailboxInfo->m_image.swap(&image); // Because of texture sharing with the compositor, we must invalidate // the state cached in skia so that the deferred copy on write // in SkSurface_Gpu does not make any false assumptions. mailboxInfo->m_image->getTexture()->invalidateCachedState(); ASSERT(mailboxInfo->m_mailbox.syncPoint == 0); ASSERT(mailboxInfo->m_image.get()); ASSERT(mailboxInfo->m_image->getTexture()); m_context->bindTexture(GL_TEXTURE_2D, mailboxInfo->m_image->getTexture()->getTextureHandle()); m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); m_context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailboxInfo->m_mailbox.name); context()->flush(); mailboxInfo->m_mailbox.syncPoint = context()->insertSyncPoint(); m_context->bindTexture(GL_TEXTURE_2D, 0); // Because we are changing the texture binding without going through skia, // we must dirty the context. m_context->grContext()->resetContext(kTextureBinding_GrGLBackendState); // set m_parentLayerBridge to make sure 'this' stays alive as long as it has // live mailboxes ASSERT(!mailboxInfo->m_parentLayerBridge); mailboxInfo->m_parentLayerBridge = this; *outMailbox = mailboxInfo->m_mailbox; return true; }