Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1224)

Unified Diff: Source/core/platform/graphics/ImageBuffer.cpp

Issue 104023007: Refactoring ImageBuffer to decouple it from Canvas2DLayerBridge (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: build fixes for win+mac Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/core/platform/graphics/ImageBuffer.cpp
diff --git a/Source/core/platform/graphics/ImageBuffer.cpp b/Source/core/platform/graphics/ImageBuffer.cpp
index 5389a97c0f4d45d1ba5f55e0e6990eadc590e0f4..a5b7153a95ff6e122002a08adee49ea85fd97377 100644
--- a/Source/core/platform/graphics/ImageBuffer.cpp
+++ b/Source/core/platform/graphics/ImageBuffer.cpp
@@ -35,7 +35,7 @@
#include "core/platform/graphics/BitmapImage.h"
#include "core/platform/graphics/Extensions3D.h"
-#include "core/platform/graphics/GaneshUtils.h"
+#include "core/platform/graphics/GraphicsContext.h"
#include "core/platform/graphics/GraphicsContext3D.h"
#include "core/platform/graphics/gpu/DrawingBuffer.h"
#include "core/platform/graphics/gpu/SharedGraphicsContext3D.h"
@@ -45,17 +45,8 @@
#include "core/platform/image-encoders/skia/PNGImageEncoder.h"
#include "core/platform/image-encoders/skia/WEBPImageEncoder.h"
#include "platform/MIMETypeRegistry.h"
-#include "platform/geometry/IntRect.h"
#include "public/platform/Platform.h"
-#include "skia/ext/platform_canvas.h"
-#include "third_party/skia/include/core/SkBitmapDevice.h"
-#include "third_party/skia/include/core/SkColorFilter.h"
-#include "third_party/skia/include/core/SkColorPriv.h"
-#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/effects/SkTableColorFilter.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/gpu/SkGpuDevice.h"
-#include "third_party/skia/include/gpu/SkGrPixelRef.h"
#include "wtf/MathExtras.h"
#include "wtf/text/Base64.h"
#include "wtf/text/WTFString.h"
@@ -63,145 +54,15 @@
using namespace std;
namespace WebCore {
-
-static PassRefPtr<SkCanvas> createAcceleratedCanvas(const IntSize& size, Canvas2DLayerBridgePtr* outLayerBridge, OpacityMode opacityMode, int msaaSampleCount)
-{
- RefPtr<GraphicsContext3D> context3D = SharedGraphicsContext3D::get();
- if (!context3D)
- return 0;
- Canvas2DLayerBridge::OpacityMode bridgeOpacityMode = opacityMode == Opaque ? Canvas2DLayerBridge::Opaque : Canvas2DLayerBridge::NonOpaque;
- *outLayerBridge = Canvas2DLayerBridge::create(context3D.release(), size, bridgeOpacityMode, msaaSampleCount);
- // If canvas buffer allocation failed, debug build will have asserted
- // For release builds, we must verify whether the device has a render target
- return (*outLayerBridge) ? (*outLayerBridge)->getCanvas() : 0;
-}
-
-static PassRefPtr<SkCanvas> createTextureBackedCanvas(const IntSize& size)
-{
- RefPtr<GraphicsContext3D> context3D = SharedGraphicsContext3D::get();
- if (!context3D)
- return 0;
- GrContext* gr = context3D->grContext();
- if (!gr)
- return 0;
- SkBitmap* bitmap = new SkBitmap;
- if (!bitmap || !ensureTextureBackedSkBitmap(gr, *bitmap, size, kDefault_GrSurfaceOrigin, kRGBA_8888_GrPixelConfig))
- return 0;
- return adoptRef(new SkCanvas(*bitmap));
-}
-
-static PassRefPtr<SkCanvas> createNonPlatformCanvas(const IntSize& size)
-{
- SkAutoTUnref<SkBaseDevice> device(new SkBitmapDevice(SkBitmap::kARGB_8888_Config, size.width(), size.height()));
- SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef();
- return adoptRef(pixelRef ? new SkCanvas(device) : 0);
-}
-
-PassOwnPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const IntSize& size, float resolutionScale, const GraphicsContext* context, bool hasAlpha)
-{
- bool success = false;
- OwnPtr<ImageBuffer> buf = adoptPtr(new ImageBuffer(size, resolutionScale, context, hasAlpha, success));
- if (!success)
- return nullptr;
- return buf.release();
-}
-
-PassOwnPtr<ImageBuffer> ImageBuffer::createBufferForTile(const FloatSize& tileSize, const FloatSize& clampedTileSize, RenderingMode renderingMode)
-{
- IntSize imageSize(roundedIntSize(clampedTileSize));
- IntSize unclampedImageSize(roundedIntSize(tileSize));
-
- // Don't create empty ImageBuffers.
- if (imageSize.isEmpty())
- return nullptr;
-
- OwnPtr<ImageBuffer> image = ImageBuffer::create(imageSize, 1, renderingMode);
- if (!image)
- return nullptr;
-
- GraphicsContext* imageContext = image->context();
- ASSERT(imageContext);
-
- // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.
- imageContext->scale(FloatSize(unclampedImageSize.width() / tileSize.width(), unclampedImageSize.height() / tileSize.height()));
-
- return image.release();
-}
-
-ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, const GraphicsContext* compatibleContext, bool hasAlpha, bool& success)
- : m_size(size)
- , m_logicalSize(size)
- , m_resolutionScale(resolutionScale)
+ImageBuffer::ImageBuffer(PassOwnPtr<ImageBufferSurface> surface)
+ : m_surface(surface)
{
- if (!compatibleContext) {
- success = false;
- return;
+ if (m_surface->isValid() || m_surface->canvas()) {
Stephen White 2013/12/04 21:18:40 Huh?
+ m_context = adoptPtr(new GraphicsContext(m_surface->canvas()));
+ m_context->setCertainlyOpaque(m_surface->opacityMode() == Opaque);
+ m_context->setAccelerated(m_surface->isAccelerated());
+ m_context->scale(FloatSize(m_surface->resolutionScale(), m_surface->resolutionScale()));
}
-
- SkAutoTUnref<SkBaseDevice> device(compatibleContext->createCompatibleDevice(size, hasAlpha));
- if (!device.get()) {
- success = false;
- return;
- }
-
- SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef();
- if (!pixelRef) {
- success = false;
- return;
- }
-
- m_canvas = adoptRef(new SkCanvas(device));
- m_context = adoptPtr(new GraphicsContext(m_canvas.get()));
- m_context->setCertainlyOpaque(!hasAlpha);
- m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale));
-
- success = true;
-}
-
-ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, RenderingMode renderingMode, OpacityMode opacityMode, int acceleratedSampleCount, bool& success)
- : m_size(size)
- , m_logicalSize(size)
- , m_resolutionScale(resolutionScale)
-{
- if (renderingMode == Accelerated) {
- m_canvas = createAcceleratedCanvas(size, &m_layerBridge, opacityMode, acceleratedSampleCount);
- if (!m_canvas)
- renderingMode = UnacceleratedNonPlatformBuffer;
- }
-
- if (renderingMode == TextureBacked) {
- m_canvas = createTextureBackedCanvas(size);
- if (!m_canvas)
- renderingMode = UnacceleratedNonPlatformBuffer;
- }
-
- if (renderingMode == UnacceleratedNonPlatformBuffer)
- m_canvas = createNonPlatformCanvas(size);
-
- if (!m_canvas)
- m_canvas = adoptRef(skia::TryCreateBitmapCanvas(size.width(), size.height(), false));
-
- if (!m_canvas) {
- success = false;
- return;
- }
-
- m_context = adoptPtr(new GraphicsContext(m_canvas.get()));
- m_context->setCertainlyOpaque(opacityMode == Opaque);
- m_context->setAccelerated(renderingMode == Accelerated);
- m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale));
-
- // Clear the background transparent or opaque, as required. It would be nice if this wasn't
- // required, but the canvas is currently filled with the magic transparency
- // color. Can we have another way to manage this?
- if (renderingMode != TextureBacked) {
- if (opacityMode == Opaque)
- m_canvas->drawARGB(255, 0, 0, 0, SkXfermode::kSrc_Mode);
- else
- m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode);
- }
-
- success = true;
}
ImageBuffer::~ImageBuffer()
@@ -210,20 +71,14 @@ ImageBuffer::~ImageBuffer()
GraphicsContext* ImageBuffer::context() const
{
- if (m_layerBridge) {
- // We're using context acquisition as a signal that someone is about to render into our buffer and we need
- // to be ready. This isn't logically const-correct, hence the cast.
- const_cast<Canvas2DLayerBridge*>(m_layerBridge.get())->contextAcquired();
- }
+ m_surface->aboutToUse();
return m_context.get();
}
bool ImageBuffer::isValid() const
{
- if (m_layerBridge)
- return const_cast<Canvas2DLayerBridge*>(m_layerBridge.get())->isValid();
- return true;
+ return m_surface->isValid();
}
static SkBitmap deepSkBitmapCopy(const SkBitmap& bitmap)
@@ -240,9 +95,8 @@ PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
if (!isValid())
return BitmapImage::create(NativeImageSkia::create());
- const SkBitmap& bitmap = *context()->bitmap();
- // FIXME: Start honoring ScaleBehavior to scale 2x buffers down to 1x.
- return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBackingStore ? deepSkBitmapCopy(bitmap) : bitmap, m_resolutionScale));
+ const SkBitmap& bitmap = m_surface->bitmap();
+ return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBackingStore ? deepSkBitmapCopy(bitmap) : bitmap, m_surface->resolutionScale()));
}
BackingStoreCopy ImageBuffer::fastCopyImageMode()
@@ -252,16 +106,14 @@ BackingStoreCopy ImageBuffer::fastCopyImageMode()
blink::WebLayer* ImageBuffer::platformLayer() const
{
- return m_layerBridge ? m_layerBridge->layer() : 0;
+ return m_surface->layer();
}
bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3DObject texture, GC3Denum internalFormat, GC3Denum destType, GC3Dint level, bool premultiplyAlpha, bool flipY)
{
- if (!m_layerBridge || !platformLayer() || !isValid())
+ if (!m_surface->isAccelerated() || !platformLayer() || !isValid())
return false;
- Platform3DObject sourceTexture = m_layerBridge->backBufferTexture();
-
if (!context.makeContextCurrent())
return false;
@@ -275,8 +127,7 @@ bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3DOb
// The canvas is stored in an inverted position, so the flip semantics are reversed.
context.pixelStorei(Extensions3D::UNPACK_FLIP_Y_CHROMIUM, !flipY);
-
- extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, sourceTexture, texture, level, internalFormat, destType);
+ extensions->copyTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, getBackingTexture(), texture, level, internalFormat, destType);
context.pixelStorei(Extensions3D::UNPACK_FLIP_Y_CHROMIUM, false);
context.pixelStorei(Extensions3D::UNPACK_UNPREMULTIPLY_ALPHA_CHROMIUM, false);
@@ -286,17 +137,13 @@ bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3DOb
static bool drawNeedsCopy(GraphicsContext* src, GraphicsContext* dst)
{
+ ASSERT(dst);
return (src == dst);
}
Platform3DObject ImageBuffer::getBackingTexture()
{
- if (!m_context || !m_context->bitmap())
- return 0;
- const SkBitmap& bitmap = *m_context->bitmap();
- if (bitmap.getTexture())
- return (bitmap.getTexture())->getTextureHandle();
- return 0;
+ return m_surface->getBackingTexture();
}
bool ImageBuffer::copyRenderingResultsFromDrawingBuffer(DrawingBuffer* drawingBuffer)
@@ -304,7 +151,7 @@ bool ImageBuffer::copyRenderingResultsFromDrawingBuffer(DrawingBuffer* drawingBu
if (!drawingBuffer)
return false;
RefPtr<GraphicsContext3D> context3D = SharedGraphicsContext3D::get();
- Platform3DObject tex = getBackingTexture();
+ Platform3DObject tex = m_surface->getBackingTexture();
if (!context3D || !tex)
return false;
@@ -318,7 +165,7 @@ void ImageBuffer::draw(GraphicsContext* context, const FloatRect& destRect, cons
if (!isValid())
return;
- const SkBitmap& bitmap = *m_context->bitmap();
+ const SkBitmap& bitmap = m_surface->bitmap();
RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsCopy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap));
context->drawImage(image.get(), destRect, srcRect, op, blendMode, DoNotRespectImageOrientation, useLowQualityScale);
}
@@ -329,7 +176,7 @@ void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect
if (!isValid())
return;
- const SkBitmap& bitmap = *m_context->bitmap();
+ const SkBitmap& bitmap = m_surface->bitmap();
RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsCopy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap));
image->drawPattern(context, srcRect, scale, phase, op, destRect, blendMode, repeatSpacing);
}
@@ -380,7 +227,7 @@ void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo
if (context()->isAccelerated() || !isValid())
return;
- const SkBitmap& bitmap = *context()->bitmap();
+ const SkBitmap& bitmap = m_surface->bitmap();
if (bitmap.isNull())
return;
@@ -388,10 +235,11 @@ void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo
getLinearRgbLUT() : getDeviceRgbLUT();
ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
+ IntSize size = m_surface->size();
SkAutoLockPixels bitmapLock(bitmap);
- for (int y = 0; y < m_size.height(); ++y) {
+ for (int y = 0; y < size.height(); ++y) {
uint32_t* srcRow = bitmap.getAddr32(0, y);
- for (int x = 0; x < m_size.width(); ++x) {
+ for (int x = 0; x < size.width(); ++x) {
SkColor color = SkPMColorToColor(srcRow[x]);
srcRow[x] = SkPreMultiplyARGB(
SkColorGetA(color),
@@ -457,14 +305,14 @@ PassRefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRec
{
if (!isValid())
return Uint8ClampedArray::create(rect.width() * rect.height() * 4);
- return getImageData<Unmultiplied>(rect, context(), m_size);
+ return getImageData<Unmultiplied>(rect, context(), m_surface->size());
}
PassRefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRect& rect, CoordinateSystem) const
{
if (!isValid())
return Uint8ClampedArray::create(rect.width() * rect.height() * 4);
- return getImageData<Premultiplied>(rect, context(), m_size);
+ return getImageData<Premultiplied>(rect, context(), m_surface->size());
}
void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem)
@@ -478,24 +326,24 @@ void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c
int originX = sourceRect.x();
int destX = destPoint.x() + sourceRect.x();
ASSERT(destX >= 0);
- ASSERT(destX < m_size.width());
+ ASSERT(destX < m_surface->size().width());
ASSERT(originX >= 0);
ASSERT(originX < sourceRect.maxX());
int endX = destPoint.x() + sourceRect.maxX();
- ASSERT(endX <= m_size.width());
+ ASSERT(endX <= m_surface->size().width());
int numColumns = endX - destX;
int originY = sourceRect.y();
int destY = destPoint.y() + sourceRect.y();
ASSERT(destY >= 0);
- ASSERT(destY < m_size.height());
+ ASSERT(destY < m_surface->size().height());
ASSERT(originY >= 0);
ASSERT(originY < sourceRect.maxY());
int endY = destPoint.y() + sourceRect.maxY();
- ASSERT(endY <= m_size.height());
+ ASSERT(endY <= m_surface->size().height());
int numRows = endY - destY;
unsigned srcBytesPerRow = 4 * sourceSize.width();
@@ -543,7 +391,7 @@ String ImageBuffer::toDataURL(const String& mimeType, const double* quality, Coo
ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
Vector<char> encodedImage;
- if (!isValid() || !encodeImage(*context()->bitmap(), mimeType, quality, &encodedImage))
+ if (!isValid() || !encodeImage(m_surface->bitmap(), mimeType, quality, &encodedImage))
return "data:,";
Vector<char> base64Data;
base64Encode(encodedImage, base64Data);

Powered by Google App Engine
This is Rietveld 408576698