bool ImageBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY) { if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(GL_TEXTURE_2D, internalFormat, destType, level)) return false; if (!isSurfaceValid()) return false; RefPtr<const SkImage> textureImage = m_surface->newImageSnapshot(PreferAcceleration); if (!textureImage) return false; if (!m_surface->isAccelerated()) return false; ASSERT(textureImage->isTextureBacked()); // isAccelerated() check above should guarantee this // Get the texture ID, flushing pending operations if needed. Platform3DObject textureId = textureImage->getTextureHandle(true); if (!textureId) return false; OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider()); if (!provider) return false; WebGraphicsContext3D* sharedContext = provider->context3d(); if (!sharedContext) return false; OwnPtr<WebExternalTextureMailbox> mailbox = adoptPtr(new WebExternalTextureMailbox); // Contexts may be in a different share group. We must transfer the texture through a mailbox first sharedContext->genMailboxCHROMIUM(mailbox->name); sharedContext->produceTextureDirectCHROMIUM(textureId, GL_TEXTURE_2D, mailbox->name); sharedContext->flush(); mailbox->validSyncToken = sharedContext->insertSyncPoint(mailbox->syncToken); if (mailbox->validSyncToken) context->waitSyncToken(mailbox->syncToken); Platform3DObject sourceTexture = context->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox->name); // The canvas is stored in a premultiplied format, so unpremultiply if necessary. // The canvas is stored in an inverted position, so the flip semantics are reversed. context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture, texture, internalFormat, destType, flipY ? GL_FALSE : GL_TRUE, GL_FALSE, premultiplyAlpha ? GL_FALSE : GL_TRUE); context->deleteTexture(sourceTexture); context->flush(); WGC3Dbyte syncToken[24]; if (context->insertSyncPoint(syncToken)) sharedContext->waitSyncToken(syncToken); // Undo grContext texture binding changes introduced in this function provider->grContext()->resetContext(kTextureBinding_GrGLBackendState); return true; }
bool ImageBuffer::copyToPlatformTexture(WebGraphicsContext3D* context, Platform3DObject texture, GLenum internalFormat, GLenum destType, GLint level, bool premultiplyAlpha, bool flipY) { if (!m_surface->isAccelerated() || !getBackingTexture() || !isSurfaceValid()) return false; if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(internalFormat, destType, level)) return false; OwnPtr<WebGraphicsContext3DProvider> provider = adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider()); if (!provider) return false; WebGraphicsContext3D* sharedContext = provider->context3d(); if (!sharedContext) return false; OwnPtr<WebExternalTextureMailbox> mailbox = adoptPtr(new WebExternalTextureMailbox); // Contexts may be in a different share group. We must transfer the texture through a mailbox first sharedContext->genMailboxCHROMIUM(mailbox->name); sharedContext->produceTextureDirectCHROMIUM(getBackingTexture(), GL_TEXTURE_2D, mailbox->name); sharedContext->flush(); mailbox->syncPoint = sharedContext->insertSyncPoint(); context->waitSyncPoint(mailbox->syncPoint); Platform3DObject sourceTexture = context->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox->name); // The canvas is stored in a premultiplied format, so unpremultiply if necessary. context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, !premultiplyAlpha); // The canvas is stored in an inverted position, so the flip semantics are reversed. context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, !flipY); context->copyTextureCHROMIUM(GL_TEXTURE_2D, sourceTexture, texture, level, internalFormat, destType); context->pixelStorei(GC3D_UNPACK_FLIP_Y_CHROMIUM, false); context->pixelStorei(GC3D_UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false); context->deleteTexture(sourceTexture); context->flush(); sharedContext->waitSyncPoint(context->insertSyncPoint()); // Undo grContext texture binding changes introduced in this function provider->grContext()->resetContext(kTextureBinding_GrGLBackendState); return true; }