Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}