void ContentLayerChromium::draw()
{
    if (m_skipsDraw)
        return;

    ASSERT(layerRenderer());
    const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues();
    ASSERT(sv && sv->initialized());
    GraphicsContext3D* context = layerRendererContext();
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_contentsTexture));
    layerRenderer()->useShader(sv->contentShaderProgram());
    GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));

    if (requiresClippedUpdateRect()) {
        float m43 = drawTransform().m43();
        TransformationMatrix transform;
        transform.translate3d(m_largeLayerDrawRect.center().x(), m_largeLayerDrawRect.center().y(), m43);
        drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
                         transform, m_largeLayerDrawRect.width(),
                         m_largeLayerDrawRect.height(), drawOpacity(),
                         sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
    } else {
        drawTexturedQuad(context, layerRenderer()->projectionMatrix(),
                         drawTransform(), m_bounds.width(), m_bounds.height(),
                         drawOpacity(), sv->shaderMatrixLocation(),
                         sv->shaderAlphaLocation());
    }
}
示例#2
0
void VideoLayerChromium::drawYUV(const SharedValues* sv)
{
    GraphicsContext3D* context = layerRendererContext();
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::yPlane]));
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::uPlane]));
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane]));

    layerRenderer()->useShader(sv->yuvShaderProgram());
    unsigned frameWidth = m_frameSizes[VideoFrameChromium::yPlane].width();
    unsigned textureWidth = m_textureSizes[VideoFrameChromium::yPlane].width();
    float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
    GLC(context, context->uniform1f(sv->yuvWidthScaleFactorLocation(), widthScaleFactor));

    GLC(context, context->uniform1i(sv->yTextureLocation(), 1));
    GLC(context, context->uniform1i(sv->uTextureLocation(), 2));
    GLC(context, context->uniform1i(sv->vTextureLocation(), 3));

    GLC(context, context->uniformMatrix3fv(sv->ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));

    drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
                     bounds().width(), bounds().height(), drawOpacity(),
                     sv->yuvShaderMatrixLocation(), sv->yuvAlphaLocation());

    // Reset active texture back to texture 0.
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
}
示例#3
0
TransformationMatrix CCSolidColorLayerImpl::quadTransform() const
{
    TransformationMatrix solidColorTransform = drawTransform();
    solidColorTransform.translate(-bounds().width() / 2.0, -bounds().height() / 2.0);

    return solidColorTransform;
}
示例#4
0
PassOwnPtr<CCSharedQuadState> CCLayerImpl::createSharedQuadState() const
{
    IntRect layerClipRect;
    if (usesLayerClipping())
        layerClipRect = clipRect();
    return CCSharedQuadState::create(quadTransform(), drawTransform(), visibleLayerRect(), layerClipRect, drawOpacity(), opaque());
}
void ContentLayerChromium::calculateClippedUpdateRect(IntRect& dirtyRect, IntRect& drawRect) const
{
    // For the given layer size and content rect, calculate:
    // 1) The minimal texture space rectangle to be uploaded, returned in dirtyRect.
    // 2) The rectangle to draw this texture in relative to the target render surface, returned in drawRect.

    ASSERT(m_targetRenderSurface);
    const IntRect clipRect = m_targetRenderSurface->contentRect();

    TransformationMatrix layerOriginTransform = drawTransform();
    layerOriginTransform.translate3d(-0.5 * m_bounds.width(), -0.5 * m_bounds.height(), 0);

    // For now we apply the large layer treatment only for layers that are either untransformed
    // or are purely translated. Their matrix is expected to be invertible.
    ASSERT(layerOriginTransform.isInvertible());

    TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse();
    IntRect clipRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect);
    clipRectInLayerCoords.intersect(IntRect(0, 0, m_bounds.width(), m_bounds.height()));

    dirtyRect = clipRectInLayerCoords;

    // Map back to the target surface coordinate system.
    drawRect = layerOriginTransform.mapRect(dirtyRect);
}
示例#6
0
const IntRect CCLayerImpl::getDrawRect() const
{
    // Form the matrix used by the shader to map the corners of the layer's
    // bounds into the view space.
    FloatRect layerRect(-0.5 * bounds().width(), -0.5 * bounds().height(), bounds().width(), bounds().height());
    IntRect mappedRect = enclosingIntRect(drawTransform().mapRect(layerRect));
    return mappedRect;
}
示例#7
0
TransformationMatrix CCLayerImpl::quadTransform() const
{
    TransformationMatrix quadTransformation = drawTransform();

    float offsetX = -0.5 * bounds().width();
    float offsetY = -0.5 * bounds().height();
    quadTransformation.translate(offsetX, offsetY);

    return quadTransformation;
}
void CanvasLayerChromium::draw()
{
    ASSERT(layerRenderer());
    const CanvasLayerChromium::SharedValues* sv = layerRenderer()->canvasLayerSharedValues();
    ASSERT(sv && sv->initialized());
    GLC(glActiveTexture(GL_TEXTURE0));
    GLC(glBindTexture(GL_TEXTURE_2D, m_textureId));
    layerRenderer()->useShader(sv->canvasShaderProgram());
    GLC(glUniform1i(sv->shaderSamplerLocation(), 0));
    drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(),
                     bounds().width(), bounds().height(), drawOpacity(),
                     sv->shaderMatrixLocation(), sv->shaderAlphaLocation());

}
示例#9
0
TransformationMatrix TiledLayerChromium::tilingTransform() const
{
    TransformationMatrix transform = drawTransform();

    if (contentBounds().isEmpty())
        return transform;

    transform.scaleNonUniform(bounds().width() / static_cast<double>(contentBounds().width()),
                              bounds().height() / static_cast<double>(contentBounds().height()));

    // Tiler draws with a different origin from other layers.
    transform.translate(-contentBounds().width() / 2.0, -contentBounds().height() / 2.0);

    transform.translate(-scrollPosition().x(), -scrollPosition().y());

    return transform;
}
示例#10
0
void ContentLayerChromium::draw()
{
    if (m_skipsDraw)
        return;

    ASSERT(layerRenderer());
    const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues();
    ASSERT(sv && sv->initialized());
    GraphicsContext3D* context = layerRendererContext();
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_contentsTexture));
    layerRenderer()->useShader(sv->contentShaderProgram());
    GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0));
    drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
                     bounds().width(), bounds().height(), drawOpacity(),
                     sv->shaderMatrixLocation(), sv->shaderAlphaLocation());
}
bool FixedBackgroundImageLayerAndroid::drawGL(bool layerTilesDisabled)
{
    if (layerTilesDisabled)
        return false;
    if (!m_imageCRC)
        return false;

    ImageTexture* imageTexture = ImagesManager::instance()->retainImage(m_imageCRC);
    if (!imageTexture) {
        ImagesManager::instance()->releaseImage(m_imageCRC);
        return false;
    }

    // We have a fixed background image, let's draw it
    if (m_fixedPosition && m_fixedPosition->isBackgroundImagePositioning()) {
        BackgroundImagePositioning* position =
            static_cast<BackgroundImagePositioning*>(m_fixedPosition);

        IntPoint repeatTimes(position->nbRepeatX(), position->nbRepeatY());
        FloatPoint startPoint(position->offsetX() * getWidth(),
                              position->offsetY() * getHeight());

        FloatPoint origin;
        origin = drawTransform()->mapPoint(origin);

        Color backgroundColor = Color((int)SkColorGetR(m_backgroundColor),
                                      (int)SkColorGetG(m_backgroundColor),
                                      (int)SkColorGetB(m_backgroundColor),
                                      (int)SkColorGetA(m_backgroundColor));

        bool drawSimpleQuadSuccess = drawSimpleQuad(imageTexture, position,
                                                    repeatTimes, startPoint,
                                                    origin, backgroundColor);

        if (!drawSimpleQuadSuccess) {
            drawRepeatedGrid(imageTexture, position, repeatTimes, startPoint,
                             origin, backgroundColor);
        }
    } else
        imageTexture->drawGL(this, getOpacity());

    ImagesManager::instance()->releaseImage(m_imageCRC);

    return false;
}
void CCCanvasLayerImpl::draw(const IntRect&)
{
    ASSERT(layerRenderer());
    const CCCanvasLayerImpl::Program* program = layerRenderer()->canvasLayerProgram();
    ASSERT(program && program->initialized());
    GraphicsContext3D* context = layerRenderer()->context();
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));
    GC3Denum sfactor = m_premultipliedAlpha ? GraphicsContext3D::ONE : GraphicsContext3D::SRC_ALPHA;
    GLC(context, context->blendFunc(sfactor, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
    layerRenderer()->useShader(program->program());
    GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
    LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
                                    bounds().width(), bounds().height(), drawOpacity(),
                                    program->vertexShader().matrixLocation(),
                                    program->fragmentShader().alphaLocation());

}
示例#13
0
void VideoLayerChromium::drawRGBA(const SharedValues* sv)
{
    GraphicsContext3D* context = layerRendererContext();
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::rgbPlane]));

    layerRenderer()->useShader(sv->rgbaShaderProgram());
    unsigned frameWidth = m_frameSizes[VideoFrameChromium::rgbPlane].width();
    unsigned textureWidth = m_textureSizes[VideoFrameChromium::rgbPlane].width();
    float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
    GLC(context, context->uniform1f(sv->rgbaWidthScaleFactorLocation(), widthScaleFactor));

    GLC(context, context->uniform1i(sv->rgbaTextureLocation(), 0));

    drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
                     bounds().width(), bounds().height(), drawOpacity(),
                     sv->rgbaShaderMatrixLocation(), sv->rgbaAlphaLocation());
}
示例#14
0
bool Surface::drawGL(bool layerTilesDisabled)
{
    bool tilesDisabled = layerTilesDisabled && !isBase();
    // SAMSUNG CHANGE ++ : google handwriting 'g' icon display issue, Youtube.com 356x2 height line display issue
	// This patch should be applied with DEV CL 56175
	// WAS:if (singleLayer() && !getFirstLayer()->visible())
	if (singleLayer() && (!getFirstLayer()->visible() || getFirstLayer()->drawOpacity() <= 0.0f))
        return false;
	//SAMSUNG CHANGE --

    if (!isBase()) {
        FloatRect drawClip = getFirstLayer()->drawClip();
        if (!singleLayer()) {
            for (unsigned int i = 1; i < m_layers.size(); i++)
                drawClip.unite(m_layers[i]->drawClip());
        }
        FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
        TilesManager::instance()->shader()->clip(clippingRect);
    }

    bool askRedraw = false;
    if (m_surfaceBacking && !tilesDisabled) {
        ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking,
              getFirstLayer()->subclassName().ascii().data(), getFirstLayer()->uniqueId());

        bool force3dContentVisible = true;
        IntRect drawArea = visibleContentArea(force3dContentVisible);
        m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(),
                                 useAggressiveRendering(), background());
    }

    // draw member layers (draws image textures, glextras)
    for (unsigned int i = 0; i < m_layers.size(); i++) {
        if (m_layers[i]->drawGL(tilesDisabled)) {
           m_layers[i]->addDirtyArea();
           askRedraw = true;
        }
    }

    return askRedraw;
}
示例#15
0
void CCVideoLayerImpl::drawNativeTexture(LayerRendererChromium* layerRenderer) const
{
    const NativeTextureProgram* program = layerRenderer->videoLayerNativeTextureProgram();
    ASSERT(program && program->initialized());

    GraphicsContext3D* context = layerRenderer->context();

    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_nativeTextureId));

    GLC(context, context->useProgram(program->program()));
    float widthScaleFactor = static_cast<float>(m_nativeTextureVisibleSize.width()) / m_nativeTextureSize.width();
    GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1));

    GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));

    layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
                                    program->vertexShader().matrixLocation(),
                                    program->fragmentShader().alphaLocation(),
                                    -1);
}
示例#16
0
void CCVideoLayerImpl::drawYUV(LayerRendererChromium* layerRenderer) const
{
    const YUVProgram* program = layerRenderer->videoLayerYUVProgram();
    ASSERT(program && program->initialized());

    GraphicsContext3D* context = layerRenderer->context();
    CCVideoLayerImpl::Texture yTexture = m_textures[VideoFrameChromium::yPlane];
    CCVideoLayerImpl::Texture uTexture = m_textures[VideoFrameChromium::uPlane];
    CCVideoLayerImpl::Texture vTexture = m_textures[VideoFrameChromium::vPlane];

    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, yTexture.id));
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, uTexture.id));
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, vTexture.id));

    GLC(context, context->useProgram(program->program()));

    float yWidthScaleFactor = static_cast<float>(yTexture.visibleSize.width()) / yTexture.size.width();
    // Arbitrarily take the u sizes because u and v dimensions are identical.
    float uvWidthScaleFactor = static_cast<float>(uTexture.visibleSize.width()) / uTexture.size.width();
    GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor));
    GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor));

    GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1));
    GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2));
    GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3));

    GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
    GLC(context, context->uniform3fv(program->fragmentShader().yuvAdjLocation(), const_cast<float*>(yuvAdjust), 1));

    layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), FloatQuad(),
                                    program->vertexShader().matrixLocation(),
                                    program->fragmentShader().alphaLocation(),
                                    -1);

    // Reset active texture back to texture 0.
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
}
void CCPluginLayerImpl::draw()
{
    ASSERT(layerRenderer());
    const CCPluginLayerImpl::Program* program = layerRenderer()->pluginLayerProgram();
    ASSERT(program && program->initialized());
    GraphicsContext3D* context = layerRenderer()->context();
    GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
    GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));

    // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
    // where it will only happen once per texture.
    GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
    GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
    GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
    GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));

    layerRenderer()->useShader(program->program());
    GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0));
    LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
                                    bounds().width(), bounds().height(), drawOpacity(),
                                    program->vertexShader().matrixLocation(),
                                    program->fragmentShader().alphaLocation());
}
示例#18
0
bool Surface::drawGL(bool layerTilesDisabled)
{
    bool tilesDisabled = layerTilesDisabled && !isBase();
    if (singleLayer() && !getFirstLayer()->visible())
        return false;

    if (!isBase()) {
        FloatRect drawClip = getFirstLayer()->drawClip();
        if (!singleLayer()) {
            for (unsigned int i = 1; i < m_layers.size(); i++)
                drawClip.unite(m_layers[i]->drawClip());
        }
        FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
        TilesManager::instance()->shader()->clip(clippingRect);
    }

    bool askRedraw = false;
    if (m_surfaceBacking && !tilesDisabled) {
        ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking,
              getFirstLayer()->subclassName(), getFirstLayer()->uniqueId());

        bool force3dContentVisible = true;
        IntRect drawArea = visibleContentArea(force3dContentVisible);
        m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(),
                                 useAggressiveRendering(), background());
    }

    // draw member layers (draws image textures, glextras)
    for (unsigned int i = 0; i < m_layers.size(); i++) {
        if (m_layers[i]->drawGL(tilesDisabled)) {
           m_layers[i]->addDirtyArea();
           askRedraw = true;
        }
    }

    return askRedraw;
}
示例#19
0
PassOwnPtr<CCSharedQuadState> CCRenderSurface::createSharedQuadState() const
{
    bool isOpaque = false;
    return CCSharedQuadState::create(originTransform(), drawTransform(), contentRect(), clipRect(), drawOpacity(), isOpaque);
}
示例#20
0
void CCDelegatedRendererLayerImpl::appendRenderPassQuads(CCQuadSink& quadSink, CCAppendQuadsData& appendQuadsData, CCRenderPass* delegatedRenderPass) const
{
    const CCSharedQuadState* currentSharedQuadState = 0;
    CCSharedQuadState* copiedSharedQuadState = 0;
    for (size_t i = 0; i < delegatedRenderPass->quadList().size(); ++i) {
        CCDrawQuad* quad = delegatedRenderPass->quadList()[i];

        if (quad->sharedQuadState() != currentSharedQuadState) {
            currentSharedQuadState = quad->sharedQuadState();
            copiedSharedQuadState = quadSink.useSharedQuadState(currentSharedQuadState->copy());
        }
        ASSERT(copiedSharedQuadState);

        bool targetIsFromDelegatedRendererLayer = appendQuadsData.renderPassId.layerId == id();
        if (!targetIsFromDelegatedRendererLayer) {
            // Should be the root render pass.
            ASSERT(delegatedRenderPass == m_renderPassesInDrawOrder.last());
            // This layer must be drawing to a renderTarget other than itself.
            ASSERT(renderTarget() != this);

            copiedSharedQuadState->quadTransform = copiedSharedQuadState->quadTransform * drawTransform();
            copiedSharedQuadState->opacity *= drawOpacity();
        }

        scoped_ptr<CCDrawQuad> copyQuad;
        if (quad->material() != CCDrawQuad::RenderPass)
            copyQuad = quad->copy(copiedSharedQuadState);
        else {
            CCRenderPass::Id contributingDelegatedRenderPassId = CCRenderPassDrawQuad::materialCast(quad)->renderPassId();
            CCRenderPass::Id contributingRenderPassId = convertDelegatedRenderPassId(contributingDelegatedRenderPassId);
            ASSERT(contributingRenderPassId != appendQuadsData.renderPassId);

            copyQuad = CCRenderPassDrawQuad::materialCast(quad)->copy(copiedSharedQuadState, contributingRenderPassId).PassAs<CCDrawQuad>();
        }
        ASSERT(copyQuad.get());

        quadSink.append(copyQuad.Pass(), appendQuadsData);
    }
}
void ContentLayerChromium::updateContents()
{
    RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
    if (!backing || backing->paintingGoesToWindow())
        return;

    ASSERT(drawsContent());

    ASSERT(layerRenderer());

    void* pixels = 0;
    IntRect dirtyRect;
    IntRect updateRect;
    IntSize requiredTextureSize;
    IntSize bitmapSize;

    // FIXME: Remove this test when tiled layers are implemented.
    if (requiresClippedUpdateRect()) {
        // A layer with 3D transforms could require an arbitrarily large number
        // of texels to be repainted, so ignore these layers until tiling is
        // implemented.
        if (!drawTransform().isIdentityOrTranslation()) {
            m_skipsDraw = true;
            return;
        }

        calculateClippedUpdateRect(dirtyRect, m_largeLayerDrawRect);
        if (!layerRenderer()->checkTextureSize(m_largeLayerDrawRect.size())) {
            m_skipsDraw = true;
            return;
        }

        // If the portion of the large layer that's visible hasn't changed
        // then we don't need to update it, _unless_ its contents have changed
        // in which case we only update the dirty bits.
        if (m_largeLayerDirtyRect == dirtyRect) {
            if (!m_dirtyRect.intersects(dirtyRect))
                return;
            dirtyRect.intersect(IntRect(m_dirtyRect));
            updateRect = dirtyRect;
            requiredTextureSize = m_largeLayerDirtyRect.size();
        } else {
            m_largeLayerDirtyRect = dirtyRect;
            requiredTextureSize = dirtyRect.size();
            updateRect = IntRect(IntPoint(0, 0), dirtyRect.size());
        }
    } else {
        dirtyRect = IntRect(m_dirtyRect);
        IntRect boundsRect(IntPoint(0, 0), m_bounds);
        requiredTextureSize = m_bounds;
        // If the texture needs to be reallocated then we must redraw the entire
        // contents of the layer.
        if (requiredTextureSize != m_allocatedTextureSize)
            dirtyRect = boundsRect;
        else {
            // Clip the dirtyRect to the size of the layer to avoid drawing
            // outside the bounds of the backing texture.
            dirtyRect.intersect(boundsRect);
        }
        updateRect = dirtyRect;
    }

    if (dirtyRect.isEmpty())
        return;

#if PLATFORM(SKIA)
    const SkBitmap* skiaBitmap = 0;
    OwnPtr<skia::PlatformCanvas> canvas;
    OwnPtr<PlatformContextSkia> skiaContext;
    OwnPtr<GraphicsContext> graphicsContext;

    canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
    skiaContext.set(new PlatformContextSkia(canvas.get()));

    // This is needed to get text to show up correctly.
    // FIXME: Does this take us down a very slow text rendering path?
    skiaContext->setDrawingToImageBuffer(true);

    graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));

    // Bring the canvas into the coordinate system of the paint rect.
    canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));

    m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
    const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
    skiaBitmap = &bitmap;
    ASSERT(skiaBitmap);

    SkAutoLockPixels lock(*skiaBitmap);
    SkBitmap::Config skiaConfig = skiaBitmap->config();
    // FIXME: do we need to support more image configurations?
    if (skiaConfig == SkBitmap::kARGB_8888_Config) {
        pixels = skiaBitmap->getPixels();
        bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
    }
#elif PLATFORM(CG)
    Vector<uint8_t> tempVector;
    int rowBytes = 4 * dirtyRect.width();
    tempVector.resize(rowBytes * dirtyRect.height());
    memset(tempVector.data(), 0, tempVector.size());
    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
    RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
                                                                     dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
                                                                     colorSpace.get(),
                                                                     kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));
    CGContextTranslateCTM(contextCG.get(), 0, dirtyRect.height());
    CGContextScaleCTM(contextCG.get(), 1, -1);

    GraphicsContext graphicsContext(contextCG.get());

    // Translate the graphics context into the coordinate system of the dirty rect.
    graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());

    m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect);

    pixels = tempVector.data();
    bitmapSize = dirtyRect.size();
#else
#error "Need to implement for your platform."
#endif

    unsigned textureId = m_contentsTexture;
    if (!textureId)
        textureId = layerRenderer()->createLayerTexture();

    if (pixels)
        updateTextureRect(pixels, bitmapSize, requiredTextureSize, updateRect, textureId);
}
// Return true when fast draw succeeds.
// For the repeated image content, we just need to draw a single quad and use
// the GL shader to repeat.
bool FixedBackgroundImageLayerAndroid::drawSimpleQuad(ImageTexture* imageTexture,
                                                      BackgroundImagePositioning* position,
                                                      const IntPoint& repeatTimes,
                                                      const FloatPoint& startPoint,
                                                      const FloatPoint& origin,
                                                      const Color& backgroundColor)
{
    // The limitation for current implementation is that we can only speed up
    // single tile size image.
    // TODO: add the fast path to imageTexture which contains >1 tiles.
    GLuint imageTextureId = imageTexture->getImageTextureId();
    if (!imageTextureId)
        return false;

    int nbX = repeatTimes.x();
    int nbY = repeatTimes.y();
    float startX = startPoint.x();
    float startY = startPoint.y();
    bool repeatX = position->repeatX();
    bool repeatY = position->repeatY();

    // Draw the entire background when repeat only in one direction or no repeat.
    if (!repeatX || !repeatY) {
        SkRect backgroundRect;
        backgroundRect.fLeft = origin.x() - startX;
        backgroundRect.fTop = origin.y() - startY;
        backgroundRect.fRight = backgroundRect.fLeft + getWidth() * nbX;
        backgroundRect.fBottom = backgroundRect.fTop + getHeight() * nbY;
        PureColorQuadData backgroundData(backgroundColor, BaseQuad,
                                         0, &backgroundRect, 1.0, true);
        TilesManager::instance()->shader()->drawQuad(&backgroundData);
    }

    // Now draw the repeated images.
    // We set the quad size as the image size, then imageRepeatRanges will
    // control how many times the image will be repeated by expanding the
    // quad and texture coordinates.
    // The image size can be smaller than a tile, so repeatScale will passed
    // into the shader to scale the texture coordinates.
    SkRect imageRect = SkRect::MakeXYWH(0, 0, getWidth(), getHeight());
    FloatRect imageRepeatRanges(0, 0, repeatX ? nbX : 1, repeatY ? nbY : 1);

    FloatSize repeatScale(float(getWidth()) / TilesManager::tileWidth(),
                          float(getHeight()) / TilesManager::tileHeight());

    ALOGV("repeatedQuadData: startX %f, startY %f , getWidth() %f, getHeight() %f,"
          " nbX %d, nbY %d, repeatImageTimesX, repeatImageTimesY %d %d"
          " repeatScale width %f, height %f, origin x %f y %f",
          startX , startY  , getWidth(), getHeight(), nbX , nbY,
          imageRepeatRanges.width(), imageRepeatRanges.height(),
          repeatScale.width(), repeatScale.height(), origin.x(), origin.y());

    // Adding startX and startY into the transform can handle the fixed right /
    // fixed bottom case.
    TransformationMatrix matrix = *drawTransform();
    matrix.translate(repeatX ? -startX : 0, repeatY ? -startY : 0);

    TextureQuadData repeatedQuadData(imageTextureId, GL_TEXTURE_2D, GL_LINEAR,
                                     LayerQuad, &matrix, &imageRect, getOpacity(),
                                     true, imageRepeatRanges, repeatScale);
    TilesManager::instance()->shader()->drawQuad(&repeatedQuadData);
    return true;
}
示例#23
0
PassOwnPtr<CCSharedQuadState> CCLayerImpl::createSharedQuadState() const
{
    return CCSharedQuadState::create(quadTransform(), drawTransform(), visibleLayerRect(), m_scissorRect, drawOpacity(), opaque());
}
示例#24
0
void CCTiledLayerImpl::appendQuads(CCQuadSink& quadSink, CCAppendQuadsData& appendQuadsData)
{
    const IntRect& contentRect = visibleContentRect();

    if (!m_tiler || m_tiler->hasEmptyBounds() || contentRect.isEmpty())
        return;

    CCSharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQuadState());
    appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData);

    int left, top, right, bottom;
    m_tiler->contentRectToTileIndices(contentRect, left, top, right, bottom);

    if (hasDebugBorders()) {
        for (int j = top; j <= bottom; ++j) {
            for (int i = left; i <= right; ++i) {
                DrawableTile* tile = tileAt(i, j);
                IntRect tileRect = m_tiler->tileBounds(i, j);
                SkColor borderColor;

                if (m_skipsDraw || !tile || !tile->resourceId())
                    borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTileBorderMissingTileColorRed, debugTileBorderMissingTileColorGreen, debugTileBorderMissingTileColorBlue);
                else
                    borderColor = SkColorSetARGB(debugTileBorderAlpha, debugTileBorderColorRed, debugTileBorderColorGreen, debugTileBorderColorBlue);
                quadSink.append(CCDebugBorderDrawQuad::create(sharedQuadState, tileRect, borderColor, debugTileBorderWidth).PassAs<CCDrawQuad>(), appendQuadsData);
            }
        }
    }

    if (m_skipsDraw)
        return;

    for (int j = top; j <= bottom; ++j) {
        for (int i = left; i <= right; ++i) {
            DrawableTile* tile = tileAt(i, j);
            IntRect tileRect = m_tiler->tileBounds(i, j);
            IntRect displayRect = tileRect;
            tileRect.intersect(contentRect);

            // Skip empty tiles.
            if (tileRect.isEmpty())
                continue;

            if (!tile || !tile->resourceId()) {
                if (drawCheckerboardForMissingTiles()) {
                    SkColor defaultColor = SkColorSetRGB(defaultCheckerboardColorRed, defaultCheckerboardColorGreen, defaultCheckerboardColorBlue);
                    SkColor evictedColor = SkColorSetRGB(debugTileEvictedCheckerboardColorRed, debugTileEvictedCheckerboardColorGreen, debugTileEvictedCheckerboardColorBlue);
                    SkColor invalidatedColor = SkColorSetRGB(debugTileInvalidatedCheckerboardColorRed, debugTileEvictedCheckerboardColorGreen, debugTileEvictedCheckerboardColorBlue);

                    SkColor checkerColor;
                    if (hasDebugBorders())
                        checkerColor = tile ? invalidatedColor : evictedColor;
                    else
                        checkerColor = defaultColor;

                    appendQuadsData.hadMissingTiles |= quadSink.append(CCCheckerboardDrawQuad::create(sharedQuadState, tileRect, checkerColor).PassAs<CCDrawQuad>(), appendQuadsData);
                } else
                    appendQuadsData.hadMissingTiles |= quadSink.append(CCSolidColorDrawQuad::create(sharedQuadState, tileRect, backgroundColor()).PassAs<CCDrawQuad>(), appendQuadsData);
                continue;
            }

            IntRect tileOpaqueRect = tile->opaqueRect();
            tileOpaqueRect.intersect(contentRect);

            // Keep track of how the top left has moved, so the texture can be
            // offset the same amount.
            IntSize displayOffset = tileRect.minXMinYCorner() - displayRect.minXMinYCorner();
            IntPoint textureOffset = m_tiler->textureOffset(i, j) + displayOffset;
            float tileWidth = static_cast<float>(m_tiler->tileSize().width());
            float tileHeight = static_cast<float>(m_tiler->tileSize().height());
            IntSize textureSize(tileWidth, tileHeight);

            bool clipped = false;
            FloatQuad visibleContentInTargetQuad = CCMathUtil::mapQuad(drawTransform(), FloatQuad(visibleContentRect()), clipped);
            bool isAxisAlignedInTarget = !clipped && visibleContentInTargetQuad.isRectilinear();
            bool useAA = m_tiler->hasBorderTexels() && !isAxisAlignedInTarget;

            bool leftEdgeAA = !i && useAA;
            bool topEdgeAA = !j && useAA;
            bool rightEdgeAA = i == m_tiler->numTilesX() - 1 && useAA;
            bool bottomEdgeAA = j == m_tiler->numTilesY() - 1 && useAA;

            const GC3Dint textureFilter = m_tiler->hasBorderTexels() ? GraphicsContext3D::LINEAR : GraphicsContext3D::NEAREST;
            quadSink.append(CCTileDrawQuad::create(sharedQuadState, tileRect, tileOpaqueRect, tile->resourceId(), textureOffset, textureSize, textureFilter, contentsSwizzled(), leftEdgeAA, topEdgeAA, rightEdgeAA, bottomEdgeAA).PassAs<CCDrawQuad>(), appendQuadsData);
        }
    }
}
示例#25
0
void CCPluginLayerImpl::draw(LayerRendererChromium* layerRenderer)
{
    ASSERT(CCProxy::isImplThread());

    if (m_ioSurfaceChanged) {
        GraphicsContext3D* context = layerRenderer->context();
        Extensions3DChromium* extensions = static_cast<Extensions3DChromium*>(context->getExtensions());
        ASSERT(extensions->supports("GL_CHROMIUM_iosurface"));
        ASSERT(extensions->supports("GL_ARB_texture_rectangle"));

        if (!m_ioSurfaceTextureId)
            m_ioSurfaceTextureId = context->createTexture();

        GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
        GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceTextureId));
        GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
        GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
        GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
        GLC(context, context->texParameteri(Extensions3D::TEXTURE_RECTANGLE_ARB, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
        extensions->texImageIOSurface2DCHROMIUM(Extensions3D::TEXTURE_RECTANGLE_ARB,
                                                m_ioSurfaceWidth,
                                                m_ioSurfaceHeight,
                                                m_ioSurfaceId,
                                                0);
        // Do not check for error conditions. texImageIOSurface2DCHROMIUM is supposed to hold on to
        // the last good IOSurface if the new one is already closed. This is only a possibility
        // during live resizing of plugins. However, it seems that this is not sufficient to
        // completely guard against garbage being drawn. If this is found to be a significant issue,
        // it may be necessary to explicitly tell the embedder when to free the surfaces it has
        // allocated.
        m_ioSurfaceChanged = false;
    }

    if (m_ioSurfaceTextureId) {
        TexTransformPluginProgramBinding binding;
        if (m_flipped)
            binding.set(layerRenderer->pluginLayerTexRectProgramFlip());
        else
            binding.set(layerRenderer->pluginLayerTexRectProgram());

        GraphicsContext3D* context = layerRenderer->context();
        GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
        GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, m_ioSurfaceTextureId));

        GLC(context, context->useProgram(binding.programId));
        GLC(context, context->uniform1i(binding.samplerLocation, 0));
        // Note: this code path ignores m_uvRect.
        GLC(context, context->uniform4f(binding.texTransformLocation, 0, 0, m_ioSurfaceWidth, m_ioSurfaceHeight));
        layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
                                        binding.matrixLocation,
                                        binding.alphaLocation,
                                        -1);
        GLC(context, context->bindTexture(Extensions3D::TEXTURE_RECTANGLE_ARB, 0));
    } else {
        TexStretchPluginProgramBinding binding;
        if (m_flipped)
            binding.set(layerRenderer->pluginLayerProgramFlip());
        else
            binding.set(layerRenderer->pluginLayerProgram());

        GraphicsContext3D* context = layerRenderer->context();
        GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
        GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId));

        // FIXME: setting the texture parameters every time is redundant. Move this code somewhere
        // where it will only happen once per texture.
        GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
        GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
        GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
        GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));

        GLC(context, context->useProgram(binding.programId));
        GLC(context, context->uniform1i(binding.samplerLocation, 0));
        GLC(context, context->uniform2f(binding.offsetLocation, m_uvRect.x(), m_uvRect.y()));
        GLC(context, context->uniform2f(binding.scaleLocation, m_uvRect.width(), m_uvRect.height()));
        layerRenderer->drawTexturedQuad(drawTransform(), bounds().width(), bounds().height(), drawOpacity(), layerRenderer->sharedGeometryQuad(),
                                        binding.matrixLocation,
                                        binding.alphaLocation,
                                        -1);
    }
}