| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, Google Inc. All rights reserved. |
| 3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> | 3 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> |
| 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. | 4 * Copyright (C) 2010 Torch Mobile (Beijing) Co. Ltd. All rights reserved. |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions are | 7 * modification, are permitted provided that the following conditions are |
| 8 * met: | 8 * met: |
| 9 * | 9 * |
| 10 * * Redistributions of source code must retain the above copyright | 10 * * Redistributions of source code must retain the above copyright |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 using namespace std; | 60 using namespace std; |
| 61 | 61 |
| 62 namespace WebCore { | 62 namespace WebCore { |
| 63 | 63 |
| 64 // We pass a technically-uninitialized canvas to the platform context here since | 64 // We pass a technically-uninitialized canvas to the platform context here since |
| 65 // the canvas initialization completes in ImageBuffer::ImageBuffer. But | 65 // the canvas initialization completes in ImageBuffer::ImageBuffer. But |
| 66 // PlatformContext doesn't actually need to use the object, and this makes all | 66 // PlatformContext doesn't actually need to use the object, and this makes all |
| 67 // the ownership easier to manage. | 67 // the ownership easier to manage. |
| 68 ImageBufferData::ImageBufferData(const IntSize& size) | 68 ImageBufferData::ImageBufferData(const IntSize& size) |
| 69 : m_platformContext(0) // Canvas is set in ImageBuffer constructor. | |
| 70 { | 69 { |
| 71 } | 70 } |
| 72 | 71 |
| 73 static SkCanvas* createAcceleratedCanvas(const IntSize& size, ImageBufferData* d
ata) | 72 static SkCanvas* createAcceleratedCanvas(const IntSize& size, GraphicsContext* c
ontext, ImageBufferData* data) |
| 74 { | 73 { |
| 75 RefPtr<GraphicsContext3D> context3D = SharedGraphicsContext3D::get(); | 74 RefPtr<GraphicsContext3D> context3D = SharedGraphicsContext3D::get(); |
| 76 if (!context3D) | 75 if (!context3D) |
| 77 return 0; | 76 return 0; |
| 78 GrContext* gr = context3D->grContext(); | 77 GrContext* gr = context3D->grContext(); |
| 79 if (!gr) | 78 if (!gr) |
| 80 return 0; | 79 return 0; |
| 81 gr->resetContext(); | 80 gr->resetContext(); |
| 82 Canvas2DLayerBridge::ThreadMode threadMode = WebKit::Platform::current()->is
ThreadedCompositingEnabled() ? Canvas2DLayerBridge::Threaded : Canvas2DLayerBrid
ge::SingleThread; | 81 Canvas2DLayerBridge::ThreadMode threadMode = WebKit::Platform::current()->is
ThreadedCompositingEnabled() ? Canvas2DLayerBridge::Threaded : Canvas2DLayerBrid
ge::SingleThread; |
| 83 SkImage::Info info; | 82 SkImage::Info info; |
| 84 info.fWidth = size.width(); | 83 info.fWidth = size.width(); |
| 85 info.fHeight = size.height(); | 84 info.fHeight = size.height(); |
| 86 info.fColorType = SkImage::kPMColor_ColorType; | 85 info.fColorType = SkImage::kPMColor_ColorType; |
| 87 info.fAlphaType = SkImage::kPremul_AlphaType; | 86 info.fAlphaType = SkImage::kPremul_AlphaType; |
| 88 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context3D->grCont
ext(), info)); | 87 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context3D->grCont
ext(), info)); |
| 89 if (!surface.get()) | 88 if (!surface.get()) |
| 90 return 0; | 89 return 0; |
| 91 SkDeferredCanvas* canvas = new SkDeferredCanvas(surface.get()); | 90 SkDeferredCanvas* canvas = new SkDeferredCanvas(surface.get()); |
| 92 data->m_layerBridge = Canvas2DLayerBridge::create(context3D.release(), canva
s, threadMode); | 91 data->m_layerBridge = Canvas2DLayerBridge::create(context3D.release(), canva
s, threadMode); |
| 93 // If canvas buffer allocation failed, debug build will have asserted | 92 // If canvas buffer allocation failed, debug build will have asserted |
| 94 // For release builds, we must verify whether the device has a render target | 93 // For release builds, we must verify whether the device has a render target |
| 95 data->m_platformContext.setAccelerated(true); | 94 context->platformContext()->setAccelerated(true); |
| 96 return canvas; | 95 return canvas; |
| 97 } | 96 } |
| 98 | 97 |
| 99 static SkCanvas* createNonPlatformCanvas(const IntSize& size) | 98 static SkCanvas* createNonPlatformCanvas(const IntSize& size) |
| 100 { | 99 { |
| 101 SkAutoTUnref<SkDevice> device(new SkDevice(SkBitmap::kARGB_8888_Config, size
.width(), size.height())); | 100 SkAutoTUnref<SkDevice> device(new SkDevice(SkBitmap::kARGB_8888_Config, size
.width(), size.height())); |
| 102 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); | 101 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); |
| 103 return pixelRef ? new SkCanvas(device) : 0; | 102 return pixelRef ? new SkCanvas(device) : 0; |
| 104 } | 103 } |
| 105 | 104 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 129 return; | 128 return; |
| 130 } | 129 } |
| 131 | 130 |
| 132 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); | 131 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); |
| 133 if (!pixelRef) { | 132 if (!pixelRef) { |
| 134 success = false; | 133 success = false; |
| 135 return; | 134 return; |
| 136 } | 135 } |
| 137 | 136 |
| 138 m_data.m_canvas = adoptPtr(new SkCanvas(device)); | 137 m_data.m_canvas = adoptPtr(new SkCanvas(device)); |
| 139 m_data.m_platformContext.setCanvas(m_data.m_canvas.get()); | 138 m_context = adoptPtr(new GraphicsContext(m_data.m_canvas.get())); |
| 140 m_context = adoptPtr(new GraphicsContext(&m_data.m_platformContext)); | |
| 141 m_context->setShouldSmoothFonts(false); | 139 m_context->setShouldSmoothFonts(false); |
| 142 m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale)); | 140 m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale)); |
| 143 | 141 |
| 144 success = true; | 142 success = true; |
| 145 } | 143 } |
| 146 | 144 |
| 147 ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace,
RenderingMode renderingMode, bool& success) | 145 ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace,
RenderingMode renderingMode, bool& success) |
| 148 : m_data(size) | 146 : m_data(size) |
| 149 , m_size(size) | 147 , m_size(size) |
| 150 , m_logicalSize(size) | 148 , m_logicalSize(size) |
| 151 , m_resolutionScale(resolutionScale) | 149 , m_resolutionScale(resolutionScale) |
| 152 { | 150 { |
| 153 OwnPtr<SkCanvas> canvas; | 151 OwnPtr<SkCanvas> canvas; |
| 154 | 152 |
| 155 if (renderingMode == Accelerated) | 153 if (renderingMode == Accelerated) |
| 156 canvas = adoptPtr(createAcceleratedCanvas(size, &m_data)); | 154 canvas = adoptPtr(createAcceleratedCanvas(size, context(), &m_data)); |
| 157 else if (renderingMode == UnacceleratedNonPlatformBuffer) | 155 else if (renderingMode == UnacceleratedNonPlatformBuffer) |
| 158 canvas = adoptPtr(createNonPlatformCanvas(size)); | 156 canvas = adoptPtr(createNonPlatformCanvas(size)); |
| 159 | 157 |
| 160 if (!canvas) | 158 if (!canvas) |
| 161 canvas = adoptPtr(skia::TryCreateBitmapCanvas(size.width(), size.height(
), false)); | 159 canvas = adoptPtr(skia::TryCreateBitmapCanvas(size.width(), size.height(
), false)); |
| 162 | 160 |
| 163 if (!canvas) { | 161 if (!canvas) { |
| 164 success = false; | 162 success = false; |
| 165 return; | 163 return; |
| 166 } | 164 } |
| 167 | 165 |
| 168 m_data.m_canvas = canvas.release(); | 166 m_data.m_canvas = canvas.release(); |
| 169 m_data.m_platformContext.setCanvas(m_data.m_canvas.get()); | 167 m_context = adoptPtr(new GraphicsContext(m_data.m_canvas.get())); |
| 170 m_context = adoptPtr(new GraphicsContext(&m_data.m_platformContext)); | |
| 171 m_context->setShouldSmoothFonts(false); | 168 m_context->setShouldSmoothFonts(false); |
| 172 m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale)); | 169 m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale)); |
| 173 | 170 |
| 174 // Make the background transparent. It would be nice if this wasn't | 171 // Make the background transparent. It would be nice if this wasn't |
| 175 // required, but the canvas is currently filled with the magic transparency | 172 // required, but the canvas is currently filled with the magic transparency |
| 176 // color. Can we have another way to manage this? | 173 // color. Can we have another way to manage this? |
| 177 m_data.m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); | 174 m_data.m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); |
| 178 | 175 |
| 179 success = true; | 176 success = true; |
| 180 } | 177 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 197 { | 194 { |
| 198 SkBitmap tmp; | 195 SkBitmap tmp; |
| 199 if (!bitmap.deepCopyTo(&tmp, bitmap.config())) | 196 if (!bitmap.deepCopyTo(&tmp, bitmap.config())) |
| 200 bitmap.copyTo(&tmp, bitmap.config()); | 197 bitmap.copyTo(&tmp, bitmap.config()); |
| 201 | 198 |
| 202 return tmp; | 199 return tmp; |
| 203 } | 200 } |
| 204 | 201 |
| 205 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
avior) const | 202 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh
avior) const |
| 206 { | 203 { |
| 207 const SkBitmap& bitmap = *m_data.m_platformContext.bitmap(); | 204 const SkBitmap& bitmap = *context()->platformContext()->bitmap(); |
| 208 // FIXME: Start honoring ScaleBehavior to scale 2x buffers down to 1x. | 205 // FIXME: Start honoring ScaleBehavior to scale 2x buffers down to 1x. |
| 209 return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBacki
ngStore ? deepSkBitmapCopy(bitmap) : bitmap, m_resolutionScale)); | 206 return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBacki
ngStore ? deepSkBitmapCopy(bitmap) : bitmap, m_resolutionScale)); |
| 210 } | 207 } |
| 211 | 208 |
| 212 BackingStoreCopy ImageBuffer::fastCopyImageMode() | 209 BackingStoreCopy ImageBuffer::fastCopyImageMode() |
| 213 { | 210 { |
| 214 return DontCopyBackingStore; | 211 return DontCopyBackingStore; |
| 215 } | 212 } |
| 216 | 213 |
| 217 PlatformLayer* ImageBuffer::platformLayer() const | 214 PlatformLayer* ImageBuffer::platformLayer() const |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 } | 250 } |
| 254 | 251 |
| 255 static bool drawNeedsCopy(GraphicsContext* src, GraphicsContext* dst) | 252 static bool drawNeedsCopy(GraphicsContext* src, GraphicsContext* dst) |
| 256 { | 253 { |
| 257 return (src == dst); | 254 return (src == dst); |
| 258 } | 255 } |
| 259 | 256 |
| 260 void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con
st FloatRect& destRect, const FloatRect& srcRect, | 257 void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con
st FloatRect& destRect, const FloatRect& srcRect, |
| 261 CompositeOperator op, BlendMode, bool useLowQualityScale) | 258 CompositeOperator op, BlendMode, bool useLowQualityScale) |
| 262 { | 259 { |
| 263 const SkBitmap& bitmap = *m_data.m_platformContext.bitmap(); | 260 const SkBitmap& bitmap = *context->platformContext()->bitmap(); |
| 264 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC
opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); | 261 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC
opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); |
| 265 context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, DoNo
tRespectImageOrientation, useLowQualityScale); | 262 context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, DoNo
tRespectImageOrientation, useLowQualityScale); |
| 266 } | 263 } |
| 267 | 264 |
| 268 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect
, const AffineTransform& patternTransform, | 265 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect
, const AffineTransform& patternTransform, |
| 269 const FloatPoint& phase, ColorSpace styleColorSpac
e, CompositeOperator op, const FloatRect& destRect) | 266 const FloatPoint& phase, ColorSpace styleColorSpac
e, CompositeOperator op, const FloatRect& destRect) |
| 270 { | 267 { |
| 271 const SkBitmap& bitmap = *m_data.m_platformContext.bitmap(); | 268 const SkBitmap& bitmap = *context->platformContext()->bitmap(); |
| 272 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC
opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); | 269 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC
opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); |
| 273 image->drawPattern(context, srcRect, patternTransform, phase, styleColorSpac
e, op, destRect); | 270 image->drawPattern(context, srcRect, patternTransform, phase, styleColorSpac
e, op, destRect); |
| 274 } | 271 } |
| 275 | 272 |
| 276 void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) | 273 void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) |
| 277 { | 274 { |
| 278 // FIXME: Disable color space conversions on accelerated canvases (for now). | 275 // FIXME: Disable color space conversions on accelerated canvases (for now). |
| 279 if (m_data.m_platformContext.isAccelerated()) | 276 if (context()->platformContext()->isAccelerated()) |
| 280 return; | 277 return; |
| 281 | 278 |
| 282 const SkBitmap& bitmap = *context()->platformContext()->bitmap(); | 279 const SkBitmap& bitmap = *context()->platformContext()->bitmap(); |
| 283 if (bitmap.isNull()) | 280 if (bitmap.isNull()) |
| 284 return; | 281 return; |
| 285 | 282 |
| 286 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); | 283 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); |
| 287 SkAutoLockPixels bitmapLock(bitmap); | 284 SkAutoLockPixels bitmapLock(bitmap); |
| 288 for (int y = 0; y < m_size.height(); ++y) { | 285 for (int y = 0; y < m_size.height(); ++y) { |
| 289 uint32_t* srcRow = bitmap.getAddr32(0, y); | 286 uint32_t* srcRow = bitmap.getAddr32(0, y); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 Vector<char> base64Data; | 416 Vector<char> base64Data; |
| 420 base64Encode(encodedImage, base64Data); | 417 base64Encode(encodedImage, base64Data); |
| 421 | 418 |
| 422 return "data:" + mimeType + ";base64," + base64Data; | 419 return "data:" + mimeType + ";base64," + base64Data; |
| 423 } | 420 } |
| 424 | 421 |
| 425 void ImageBufferData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) cons
t | 422 void ImageBufferData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) cons
t |
| 426 { | 423 { |
| 427 MemoryClassInfo info(memoryObjectInfo, this); | 424 MemoryClassInfo info(memoryObjectInfo, this); |
| 428 info.addMember(m_canvas, "canvas"); | 425 info.addMember(m_canvas, "canvas"); |
| 429 info.addMember(m_platformContext, "platformContext"); | |
| 430 info.addMember(m_layerBridge, "layerBridge"); | 426 info.addMember(m_layerBridge, "layerBridge"); |
| 431 } | 427 } |
| 432 | 428 |
| 433 String ImageDataToDataURL(const ImageData& imageData, const String& mimeType, co
nst double* quality) | 429 String ImageDataToDataURL(const ImageData& imageData, const String& mimeType, co
nst double* quality) |
| 434 { | 430 { |
| 435 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); | 431 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); |
| 436 | 432 |
| 437 Vector<char> encodedImage; | 433 Vector<char> encodedImage; |
| 438 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) | 434 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) |
| 439 return "data:,"; | 435 return "data:,"; |
| 440 | 436 |
| 441 Vector<char> base64Data; | 437 Vector<char> base64Data; |
| 442 base64Encode(encodedImage, base64Data); | 438 base64Encode(encodedImage, base64Data); |
| 443 | 439 |
| 444 return "data:" + mimeType + ";base64," + base64Data; | 440 return "data:" + mimeType + ";base64," + base64Data; |
| 445 } | 441 } |
| 446 | 442 |
| 447 } // namespace WebCore | 443 } // namespace WebCore |
| OLD | NEW |