示例#1
0
bool FECustomFilter::applyShader()
{
    Uint8ClampedArray* dstPixelArray = createUnmultipliedImageResult();
    if (!dstPixelArray)
        return false;

    if (!prepareForDrawing())
        return false;

    FilterEffect* in = inputEffect(0);
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    IntSize newContextSize(effectDrawingRect.size());
    if (!resizeContextIfNeeded(newContextSize))
        return false;

    bool needsInputTexture = programNeedsInputTexture();
    if (needsInputTexture) {
        RefPtr<Uint8ClampedArray> srcPixelArray = in->asUnmultipliedImage(effectDrawingRect);
        uploadInputTexture(srcPixelArray.get());
    }
    drawFilterMesh(needsInputTexture ? m_inputTexture : 0);

    ASSERT(static_cast<size_t>(newContextSize.width() * newContextSize.height() * 4) == dstPixelArray->length());
    m_context->readPixels(0, 0, newContextSize.width(), newContextSize.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, dstPixelArray->data());

    return true;
}
void CustomFilterRenderer::bindProgramAndBuffers(Platform3DObject inputTexture)
{
    ASSERT(m_compiledProgram->isInitialized());

    m_context->useProgram(m_compiledProgram->program());

    if (programNeedsInputTexture()) {
        // We should be binding the DOM element texture sampler only if the author is using the CSS mix function.
        ASSERT(m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
        ASSERT(m_compiledProgram->samplerLocation() != -1);

        m_context->activeTexture(GraphicsContext3D::TEXTURE0);
        m_context->uniform1i(m_compiledProgram->samplerLocation(), 0);
        m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, inputTexture);
        m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
        m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_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);
    }

    if (m_compiledProgram->projectionMatrixLocation() != -1) {
        TransformationMatrix projectionMatrix;
        orthogonalProjectionMatrix(projectionMatrix, -0.5, 0.5, -0.5, 0.5);
        float glProjectionMatrix[16];
        projectionMatrix.toColumnMajorFloatArray(glProjectionMatrix);
        m_context->uniformMatrix4fv(m_compiledProgram->projectionMatrixLocation(), 1, false, &glProjectionMatrix[0]);
    }

    ASSERT(m_meshColumns);
    ASSERT(m_meshRows);

    if (m_compiledProgram->meshSizeLocation() != -1)
        m_context->uniform2f(m_compiledProgram->meshSizeLocation(), m_meshColumns, m_meshRows);

    if (m_compiledProgram->tileSizeLocation() != -1)
        m_context->uniform2f(m_compiledProgram->tileSizeLocation(), 1.0 / m_meshColumns, 1.0 / m_meshRows);

    if (m_compiledProgram->meshBoxLocation() != -1) {
        // FIXME: This will change when filter margins will be implemented,
        // see https://bugs.webkit.org/show_bug.cgi?id=71400
        m_context->uniform4f(m_compiledProgram->meshBoxLocation(), -0.5, -0.5, 1.0, 1.0);
    }

    if (m_compiledProgram->samplerSizeLocation() != -1)
        m_context->uniform2f(m_compiledProgram->samplerSizeLocation(), m_contextSize.width(), m_contextSize.height());

    m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_mesh->verticesBufferObject());
    m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_mesh->elementsBufferObject());

    bindVertexAttribute(m_compiledProgram->positionAttribLocation(), PositionAttribSize, PositionAttribOffset);
    bindVertexAttribute(m_compiledProgram->texAttribLocation(), TexAttribSize, TexAttribOffset);
    bindVertexAttribute(m_compiledProgram->meshAttribLocation(), MeshAttribSize, MeshAttribOffset);
    if (m_meshType == MeshTypeDetached)
        bindVertexAttribute(m_compiledProgram->triangleAttribLocation(), TriangleAttribSize, TriangleAttribOffset);

    bindProgramParameters();
}
示例#3
0
bool FECustomFilter::prepareForDrawing(CustomFilterDrawType filterDrawType)
{
    if (!m_context && !initializeContext())
        return false;
    m_context->makeContextCurrent();

    // If the shader had compiler errors we cannot draw anything.
    if (!m_compiledProgram->isInitialized())
        return false;

    // Only allocate a texture if the program needs one and the caller doesn't allocate one by itself.
    if ((programNeedsInputTexture() && (filterDrawType == NEEDS_INPUT_TEXTURE) && !ensureInputTexture())
            || !ensureFrameBuffer())
        return false;

    return true;
}
示例#4
0
void FECustomFilter::bindProgramAndBuffers(Platform3DObject inputTexture)
{
    ASSERT(m_compiledProgram->isInitialized());

    m_context->useProgram(m_compiledProgram->program());

    if (programNeedsInputTexture()) {
        // We should be binding the DOM element texture sampler only if the author is using the CSS mix function.
        ASSERT(m_validatedProgram->programInfo().programType() == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE);
        ASSERT(m_compiledProgram->samplerLocation() != -1);

        m_context->activeTexture(GraphicsContext3D::TEXTURE0);
        m_context->uniform1i(m_compiledProgram->samplerLocation(), 0);
        m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, inputTexture);
        m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
        m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_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);
    }

    if (m_compiledProgram->projectionMatrixLocation() != -1) {
        TransformationMatrix projectionMatrix;
        orthogonalProjectionMatrix(projectionMatrix, -0.5, 0.5, -0.5, 0.5);
        float glProjectionMatrix[16];
        projectionMatrix.toColumnMajorFloatArray(glProjectionMatrix);
        m_context->uniformMatrix4fv(m_compiledProgram->projectionMatrixLocation(), 1, false, &glProjectionMatrix[0]);
    }

    ASSERT(m_meshColumns);
    ASSERT(m_meshRows);

    if (m_compiledProgram->meshSizeLocation() != -1)
        m_context->uniform2f(m_compiledProgram->meshSizeLocation(), m_meshColumns, m_meshRows);

    if (m_compiledProgram->tileSizeLocation() != -1)
        m_context->uniform2f(m_compiledProgram->tileSizeLocation(), 1.0 / m_meshColumns, 1.0 / m_meshRows);

    if (m_compiledProgram->meshBoxLocation() != -1) {
        // FIXME: This will change when filter margins will be implemented,
        // see https://bugs.webkit.org/show_bug.cgi?id=71400
        m_context->uniform4f(m_compiledProgram->meshBoxLocation(), -0.5, -0.5, 1.0, 1.0);
    }

    if (m_compiledProgram->samplerSizeLocation() != -1)
        m_context->uniform2f(m_compiledProgram->samplerSizeLocation(), m_contextSize.width(), m_contextSize.height());

    m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_mesh->verticesBufferObject());
    m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_mesh->elementsBufferObject());

    // FIXME: Ideally, these should be public members of CustomFilterMesh.
    // https://bugs.webkit.org/show_bug.cgi?id=94755
    static const unsigned PositionAttribSize = 4;
    static const unsigned TexAttribSize = 2;
    static const unsigned MeshAttribSize = 2;
    static const unsigned TriangleAttribSize = 3;

    static const unsigned PositionAttribOffset = 0;
    static const unsigned TexAttribOffset = PositionAttribOffset + PositionAttribSize * sizeof(float);
    static const unsigned MeshAttribOffset = TexAttribOffset + TexAttribSize * sizeof(float);
    static const unsigned TriangleAttribOffset = MeshAttribOffset + MeshAttribSize * sizeof(float);

    bindVertexAttribute(m_compiledProgram->positionAttribLocation(), PositionAttribSize, PositionAttribOffset);
    bindVertexAttribute(m_compiledProgram->texAttribLocation(), TexAttribSize, TexAttribOffset);
    // FIXME: Get rid of the internal tex coord attribute "css_a_texCoord".
    // https://bugs.webkit.org/show_bug.cgi?id=94358
    bindVertexAttribute(m_compiledProgram->internalTexCoordAttribLocation(), TexAttribSize, TexAttribOffset);
    bindVertexAttribute(m_compiledProgram->meshAttribLocation(), MeshAttribSize, MeshAttribOffset);
    if (m_meshType == CustomFilterOperation::DETACHED)
        bindVertexAttribute(m_compiledProgram->triangleAttribLocation(), TriangleAttribSize, TriangleAttribOffset);

    bindProgramParameters();
}