Exemplo n.º 1
0
void TransparencyWin::compositeOpaqueComposite()
{
    if (!m_validLayer)
        return;

    SkCanvas* destCanvas = canvasForContext(*m_destContext);
    destCanvas->save();

    SkBitmap* bitmap = const_cast<SkBitmap*>(
        &bitmapForContext(*m_layerBuffer->context()));
    
    // This function will be called for WhiteLayer as well, which we don't want
    // to change.
    if (m_layerMode == OpaqueCompositeLayer) {
        // Fix up our bitmap, making it contain only the pixels which changed
        // and transparent everywhere else.
        SkAutoLockPixels sourceLock(*m_referenceBitmap);
        SkAutoLockPixels lock(*bitmap);
        for (int y = 0; y < bitmap->height(); y++) {
            uint32_t* source = m_referenceBitmap->getAddr32(0, y);
            uint32_t* dest = bitmap->getAddr32(0, y);
            for (int x = 0; x < bitmap->width(); x++) {
                // Clear out any pixels that were untouched.
                if (dest[x] == source[x])
                    dest[x] = 0;
                else
                    dest[x] |= (0xFF << SK_A32_SHIFT);
            }
        }
    } else
        makeLayerOpaque();

    SkRect destRect;
    if (m_transformMode != Untransform) {
        // We want to use Untransformed space.
        //
        // Note that we DON'T call m_layerBuffer->image() here. This actually
        // makes a copy of the image, which is unnecessary and slow. Instead, we
        // just draw the image from inside the destination context.
        SkMatrix identity;
        identity.reset();
        destCanvas->setMatrix(identity);

        destRect.set(m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.maxX(), m_transformedSourceRect.maxY());
    } else
        destRect.set(m_sourceRect.x(), m_sourceRect.y(), m_sourceRect.maxX(), m_sourceRect.maxY());

    SkPaint paint;
    paint.setFilterBitmap(true);
    paint.setAntiAlias(true);

    // Note that we need to specify the source layer subset, since the bitmap
    // may have been cached and it could be larger than what we're using.
    SkIRect sourceRect = { 0, 0, m_layerSize.width(), m_layerSize.height() };
    destCanvas->drawBitmapRect(*bitmap, &sourceRect, destRect, &paint);
    destCanvas->restore();
}
Exemplo n.º 2
0
void TransparencyWin::initializeNewContext()
{
    int pixelSize = m_layerSize.width() * m_layerSize.height();
    if (pixelSize <= 0) 
        return;

    if (pixelSize > maxCachedBufferPixelSize) {
        // Create a 1-off buffer for drawing into. We only need the reference
        // buffer if we're making an OpaqueCompositeLayer.
        bool needReferenceBitmap = m_layerMode == OpaqueCompositeLayer;
        m_ownedBuffers = adoptPtr(new OwnedBuffers(m_layerSize, needReferenceBitmap));
        m_layerBuffer = m_ownedBuffers->destBitmap();
        if (!m_layerBuffer)
            return;

        m_drawContext = m_layerBuffer->context();
        if (needReferenceBitmap) {
            m_referenceBitmap = m_ownedBuffers->referenceBitmap();
            if (!m_referenceBitmap || !m_referenceBitmap->getPixels()) 
                return;
        }
        m_validLayer = true;
        return;
    }

    if (m_cachedBuffers && m_cachedBuffers->canHandleSize(m_layerSize)) {
        // We can re-use the existing buffer. We don't need to clear it since
        // all layer modes will clear it in their initialization.
        m_layerBuffer = m_cachedBuffers->destBitmap();
        m_drawContext = m_cachedBuffers->destBitmap()->context();
        bitmapForContext(*m_drawContext).eraseARGB(0, 0, 0, 0);
        m_referenceBitmap = m_cachedBuffers->referenceBitmap();
        m_referenceBitmap->eraseARGB(0, 0, 0, 0);
        m_validLayer = true;
        return;
    }

    // Create a new cached buffer.
    if (m_cachedBuffers)
      delete m_cachedBuffers;
    m_cachedBuffers = new OwnedBuffers(m_layerSize, true);

    m_layerBuffer = m_cachedBuffers->destBitmap();
    m_drawContext = m_cachedBuffers->destBitmap()->context();
    m_referenceBitmap = m_cachedBuffers->referenceBitmap();
    m_validLayer = true;
}
Exemplo n.º 3
0
void TransparencyWin::setupLayerForOpaqueCompositeLayer()
{
    initializeNewContext();
    if (!m_validLayer)
        return;

    AffineTransform mapping;
    mapping.translate(-m_transformedSourceRect.x(), -m_transformedSourceRect.y());
    if (m_transformMode == Untransform){ 
        // Compute the inverse mapping from the canvas space to the
        // coordinate space of our bitmap.
        mapping *= m_orgTransform.inverse();
    }
    compositeToCopy(*m_destContext, *m_drawContext, mapping);

    // Save the reference layer so we can tell what changed.
    SkCanvas referenceCanvas(*m_referenceBitmap);
    referenceCanvas.drawBitmap(bitmapForContext(*m_drawContext), 0, 0);
    // Layer rect represents the part of the original layer.
}