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(); }
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; }
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. }