Esempio n. 1
0
void DrawingBuffer::initialize(const IntSize& size)
{
    ASSERT(m_context);
    m_attributes = m_context->getContextAttributes();

    if (m_attributes.alpha) {
        m_internalColorFormat = GraphicsContext3D::RGBA;
        m_colorFormat = GraphicsContext3D::RGBA;
        m_internalRenderbufferFormat = Extensions3D::RGBA8_OES;
    } else {
        m_internalColorFormat = GraphicsContext3D::RGB;
        m_colorFormat = GraphicsContext3D::RGB;
        m_internalRenderbufferFormat = Extensions3D::RGB8_OES;
    }

    m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize);

    m_fbo = m_context->createFramebuffer();

    if (m_separateFrontTexture)
        m_frontColorBuffer = createColorTexture();

    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
    m_colorBuffer = createColorTexture();
    m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0);
    createSecondaryBuffers();
    reset(size);
#if ENABLE(CANVAS_USES_MAILBOX)
    m_lastColorBuffer = createNewMailbox(m_colorBuffer);
#endif // ENABLE(CANVAS_USES_MAILBOX)
}
Esempio n. 2
0
void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer)
{
    if (!m_context || !m_context->makeContextCurrent() || m_context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR)
        return;

    Extensions3D* extensions = m_context->getExtensions();
#if ENABLE(CANVAS_USES_MAILBOX)
    // 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.
    unsigned sourceTexture = createColorTexture(m_size);
    extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_frontColorBuffer, sourceTexture, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE);
#else
    // FIXME: Re-examine general correctness of this code beacause m_colorBuffer may contain a stale copy of the data
    // that was sent to the compositor at some point in the past.
    unsigned sourceTexture = frontColorBuffer();
#endif // ENABLE(CANVAS_USES_MAILBOX)

    // 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.
    GC3Dint previousFramebuffer = 0;
    m_context->getIntegerv(GraphicsContext3D::FRAMEBUFFER_BINDING, &previousFramebuffer);

    Platform3DObject framebuffer = m_context->createFramebuffer();
    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, framebuffer);
    m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, sourceTexture, 0);

    extensions->paintFramebufferToCanvas(framebuffer, size().width(), size().height(), !m_attributes.premultipliedAlpha, imageBuffer);
    m_context->deleteFramebuffer(framebuffer);
#if ENABLE(CANVAS_USES_MAILBOX)
    m_context->deleteTexture(sourceTexture);
#endif // ENABLE(CANVAS_USES_MAILBOX)

    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, previousFramebuffer);
}
Esempio n. 3
0
bool DrawingBuffer::prepareMailbox(WebKit::WebExternalTextureMailbox* outMailbox)
{
    if (!m_context || !m_contentsChanged || !m_lastColorBuffer)
        return false;

    m_context->makeContextCurrent();

    // Resolve the multisampled buffer into the texture referenced by m_lastColorBuffer mailbox.
    if (multisample())
        commit();

    // We must restore the texture binding since creating new textures,
    // consuming and producing mailboxes changes it.
    ScopedTextureUnit0BindingRestorer restorer(m_context.get(), m_activeTextureUnit, m_texture2DBinding);

    // First try to recycle an old buffer.
    RefPtr<MailboxInfo> nextFrontColorBuffer = getRecycledMailbox();

    // No buffer available to recycle, create a new one.
    if (!nextFrontColorBuffer) {
        unsigned newColorBuffer = createColorTexture(m_size);
        // Bad things happened, abandon ship.
        if (!newColorBuffer)
            return false;

        nextFrontColorBuffer = createNewMailbox(newColorBuffer);
    }

    if (m_preserveDrawingBuffer == Discard) {
        m_colorBuffer = nextFrontColorBuffer->textureId;
        swap(nextFrontColorBuffer, m_lastColorBuffer);
        // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a
        // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding.
        // If this stops being true at some point, we should track the current framebuffer binding in the DrawingBuffer and restore
        // it after attaching the new back buffer here.
        m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
        m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0);
    } else {
        Extensions3D* extensions = m_context->getExtensions();
        extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, m_colorBuffer, nextFrontColorBuffer->textureId, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE);
    }

    if (multisample() && !m_framebufferBinding)
        bind();
    else
        restoreFramebufferBinding();

    m_contentsChanged = false;

    context()->bindTexture(GraphicsContext3D::TEXTURE_2D, nextFrontColorBuffer->textureId);
    context()->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, nextFrontColorBuffer->mailbox.name);
    context()->flush();
    m_context->markLayerComposited();

    *outMailbox = nextFrontColorBuffer->mailbox;
    m_frontColorBuffer = nextFrontColorBuffer->textureId;
    return true;
}
Esempio n. 4
0
DrawingBuffer::TextureInfo DrawingBuffer::createDefaultTextureAndAllocateMemory(const IntSize& size)
{
    TextureParameters parameters = defaultTextureParameters();
    GLuint textureId = createColorTexture(parameters);
    texImage2DResourceSafe(parameters.target, 0, parameters.creationInternalColorFormat, size.width(), size.height(), 0, parameters.colorFormat, GL_UNSIGNED_BYTE);

    DrawingBuffer::TextureInfo info;
    info.textureId = textureId;
    info.parameters = parameters;
    return info;
}
Esempio n. 5
0
void DrawingBuffer::initialize(const IntSize& size)
{
    ASSERT(m_context);
    m_attributes = m_context->getContextAttributes();
    Extensions3DUtil extensionsUtil(m_context);

    if (m_attributes.alpha) {
        m_internalColorFormat = GL_RGBA;
        m_colorFormat = GL_RGBA;
        m_internalRenderbufferFormat = GL_RGBA8_OES;
    } else {
        m_internalColorFormat = GL_RGB;
        m_colorFormat = GL_RGB;
        m_internalRenderbufferFormat = GL_RGB8_OES;
    }

    m_context->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);

    int maxSampleCount = 0;
    m_multisampleMode = None;
    if (m_attributes.antialias && m_multisampleExtensionSupported) {
        m_context->getIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSampleCount);
        m_multisampleMode = ExplicitResolve;
        if (extensionsUtil.supportsExtension("GL_EXT_multisampled_render_to_texture"))
            m_multisampleMode = ImplicitResolve;
    }
    m_sampleCount = std::min(4, maxSampleCount);

    m_fbo = m_context->createFramebuffer();

    m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
    m_colorBuffer = createColorTexture();
    if (m_multisampleMode == ImplicitResolve)
        m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0, m_sampleCount);
    else
        m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0);
    createSecondaryBuffers();
    reset(size);
}
Esempio n. 6
0
DrawingBuffer::TextureInfo DrawingBuffer::createTextureAndAllocateMemory(const IntSize& size)
{
    if (!RuntimeEnabledFeatures::webGLImageChromiumEnabled())
        return createDefaultTextureAndAllocateMemory(size);

    // First, try to allocate a CHROMIUM_image. This always has the potential to
    // fail.
    TextureParameters parameters = chromiumImageTextureParameters();
    GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(size.width(), size.height(), parameters.creationInternalColorFormat, GC3D_SCANOUT_CHROMIUM);
    if (!imageId)
        return createDefaultTextureAndAllocateMemory(size);

    GLuint textureId = createColorTexture(parameters);
    m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId);

    TextureInfo info;
    info.textureId = textureId;
    info.imageId = imageId;
    info.parameters = parameters;
    clearChromiumImageAlpha(info);
    return info;
}
Esempio n. 7
0
void DrawingBuffer::paintCompositedResultsToCanvas(ImageBuffer* imageBuffer)
{
    if (!m_context || !m_context->makeContextCurrent() || m_context->getGraphicsResetStatusARB() != GL_NO_ERROR)
        return;

    if (!imageBuffer)
        return;
    Platform3DObject tex = imageBuffer->getBackingTexture();
    if (tex) {
        m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer,
            tex, 0, GL_RGBA, GL_UNSIGNED_BYTE);
        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(m_size);
    m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_frontColorBuffer, 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);

    paintFramebufferToCanvas(framebuffer, size().width(), size().height(), !m_attributes.premultipliedAlpha, imageBuffer);
    m_context->deleteFramebuffer(framebuffer);
    m_context->deleteTexture(sourceTexture);

    m_context->bindFramebuffer(GL_FRAMEBUFFER, previousFramebuffer);
}
Esempio n. 8
0
bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, blink::WebExternalBitmap* bitmap)
{
    if (!m_context || !m_contentsChanged)
        return false;

    m_context->makeContextCurrent();

    // Resolve the multisampled buffer into m_colorBuffer texture.
    if (m_multisampleMode != None)
        commit();

    if (bitmap) {
        bitmap->setSize(size());

        unsigned char* pixels = bitmap->pixels();
        bool needPremultiply = m_attributes.alpha && !m_attributes.premultipliedAlpha;
        WebGLImageConversion::AlphaOp op = needPremultiply ? WebGLImageConversion::AlphaDoPremultiply : WebGLImageConversion::AlphaDoNothing;
        if (pixels)
            readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSkia, op);
    }

    // We must restore the texture binding since creating new textures,
    // consuming and producing mailboxes changes it.
    ScopedTextureUnit0BindingRestorer restorer(m_context, m_activeTextureUnit, m_texture2DBinding);

    // First try to recycle an old buffer.
    RefPtr<MailboxInfo> frontColorBufferMailbox = recycledMailbox();

    // No buffer available to recycle, create a new one.
    if (!frontColorBufferMailbox) {
        unsigned newColorBuffer = createColorTexture(m_size);
        // Bad things happened, abandon ship.
        if (!newColorBuffer)
            return false;

        frontColorBufferMailbox = createNewMailbox(newColorBuffer);
    }

    if (m_preserveDrawingBuffer == Discard) {
        swap(frontColorBufferMailbox->textureId, m_colorBuffer);
        // It appears safe to overwrite the context's framebuffer binding in the Discard case since there will always be a
        // WebGLRenderingContext::clearIfComposited() call made before the next draw call which restores the framebuffer binding.
        // If this stops being true at some point, we should track the current framebuffer binding in the DrawingBuffer and restore
        // it after attaching the new back buffer here.
        m_context->bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
        if (m_multisampleMode == ImplicitResolve)
            m_context->framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0, m_sampleCount);
        else
            m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0);
    } else {
        m_context->copyTextureCHROMIUM(GL_TEXTURE_2D, m_colorBuffer, frontColorBufferMailbox->textureId, 0, GL_RGBA, GL_UNSIGNED_BYTE);
    }

    if (m_multisampleMode != None && !m_framebufferBinding)
        bind();
    else
        restoreFramebufferBinding();

    m_contentsChanged = false;

    m_context->bindTexture(GL_TEXTURE_2D, frontColorBufferMailbox->textureId);
    m_context->produceTextureCHROMIUM(GL_TEXTURE_2D, frontColorBufferMailbox->mailbox.name);
    m_context->flush();
    frontColorBufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint();
    markLayerComposited();

    *outMailbox = frontColorBufferMailbox->mailbox;
    m_frontColorBuffer = frontColorBufferMailbox->textureId;
    return true;
}
Esempio n. 9
0
void RenderBlock::
beginVboRendering(BlockLayout block_size)
{
    GlException_CHECK_ERROR();
    //unsigned meshW = collection->samples_per_block();
    //unsigned meshH = collection->scales_per_block();

    createColorTexture(24); // These will be linearly interpolated when rendering, so a high resolution texture is not needed
    glActiveTexture(GL_TEXTURE2);
    _colorTexture->bindTexture2D();
    glActiveTexture(GL_TEXTURE0);

    glUseProgram(_shader_prog);

    // TODO check if this takes any time
    {   // Set default uniform variables parameters for the vertex and pixel shader
        TIME_RENDERER_BLOCKS TaskTimer tt("Setting shader parameters");
        GLuint uniVertText0,
               uniVertText2,
               uniColorTextureFactor,
               uniFixedColor,
               uniClearColor,
               uniContourPlot,
               uniFlatness,
               uniYScale,
               uniYOffset,
               uniLogScale,
               uniScaleTex,
               uniOffsTex;

        uniVertText0 = glGetUniformLocation(_shader_prog, "tex");
        glUniform1i(uniVertText0, 0); // GL_TEXTURE0 + i

//        uniVertText1 = glGetUniformLocation(_shader_prog, "tex_nearest");
//        glUniform1i(uniVertText1, _mesh_width*_mesh_height>4 ? 0 : 0);

        uniVertText2 = glGetUniformLocation(_shader_prog, "tex_color");
        glUniform1i(uniVertText2, 2);

        uniFixedColor = glGetUniformLocation(_shader_prog, "fixedColor");
        switch (render_settings->color_mode)
        {
        case RenderSettings::ColorMode_Grayscale:
            glUniform4f(uniFixedColor, 0.f, 0.f, 0.f, 0.f);
            break;
        case RenderSettings::ColorMode_BlackGrayscale:
            glUniform4f(uniFixedColor, 1.f, 1.f, 1.f, 0.f);
            break;
        default:
        {
            tvector<4, float> fixed_color = render_settings->fixed_color;
            glUniform4f(uniFixedColor, fixed_color[0], fixed_color[1], fixed_color[2], fixed_color[3]);
            break;
        }
        }

        uniClearColor = glGetUniformLocation(_shader_prog, "clearColor");
        tvector<4, float> clear_color = render_settings->clear_color;
        glUniform4f(uniClearColor, clear_color[0], clear_color[1], clear_color[2], clear_color[3]);

        uniColorTextureFactor = glGetUniformLocation(_shader_prog, "colorTextureFactor");
        switch(render_settings->color_mode)
        {
        case RenderSettings::ColorMode_Rainbow:
        case RenderSettings::ColorMode_GreenRed:
        case RenderSettings::ColorMode_GreenWhite:
        case RenderSettings::ColorMode_Green:
            glUniform1f(uniColorTextureFactor, 1.f);
            break;
        default:
            glUniform1f(uniColorTextureFactor, 0.f);
            break;
        }

        uniContourPlot = glGetUniformLocation(_shader_prog, "contourPlot");
        glUniform1f(uniContourPlot, render_settings->draw_contour_plot ? 1.f : 0.f );

        uniFlatness = glGetUniformLocation(_shader_prog, "flatness");
        float v = render_settings->draw_flat ? 0 : 2*render_settings->last_ysize; // as glScalef in setupGlStates
        glUniform1f(uniFlatness, v);

        uniYScale = glGetUniformLocation(_shader_prog, "yScale");
        glUniform1f(uniYScale, render_settings->y_scale);

        uniYOffset = glGetUniformLocation(_shader_prog, "yOffset");
        glUniform1f(uniYOffset, render_settings->y_offset);

        // yOffset specifies 'b' which says which 'v' that should render as 0
        // yOffset=-1 => v>1 => fragColor>0
        // yOffset=0  => v>L => fragColor>0
        // yOffset=1  => v>0 => fragColor>0
        float L = 0.00001;
        float tb = 1.0/L - 1.0;
        float tc = L/(1.0 - tb);
        float ta = L - tc;
        float b = ta * exp(-render_settings->y_offset * log(tb)) + tc;

        // yScale specifies which intensity 'v=1' should have
        // v<1 => fragColor < yScale
        // v=1 => fragColor = yScale
        // v>1 => fragColor > yScale
        float x1 = render_settings->y_scale / (log(1.0) - log(b));
        float x2 = - log(b) * x1;

        uniLogScale = glGetUniformLocation(_shader_prog, "logScale");
        glUniform3f(uniLogScale, render_settings->log_scale, x1, x2);

        float
        w = block_size.texels_per_row (),
        h = block_size.texels_per_column ();

        uniScaleTex = glGetUniformLocation(_shader_prog, "scale_tex");
        glUniform2f(uniScaleTex, (w-1.f)/w, (h-1.f)/h);

        uniOffsTex = glGetUniformLocation(_shader_prog, "offset_tex");
        glUniform2f(uniOffsTex, .5f/w, .5f/h);
    }

    glBindBuffer(GL_ARRAY_BUFFER, *_mesh_position);
    glVertexPointer(4, GL_FLOAT, 0, 0);
    glEnableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _mesh_index_buffer);

    GlException_CHECK_ERROR();
}