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, OpacityMode opacityMode) | 72 static SkCanvas* createAcceleratedCanvas(const IntSize& size, ImageBufferData* d ata, OpacityMode opacityMode) |
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::OpacityMode bridgeOpacityMode = opacityMode == Opaque ? Canvas2DLayerBridge::Opaque : Canvas2DLayerBridge::NonOpaque; | 81 Canvas2DLayerBridge::OpacityMode bridgeOpacityMode = opacityMode == Opaque ? Canvas2DLayerBridge::Opaque : Canvas2DLayerBridge::NonOpaque; |
83 Canvas2DLayerBridge::ThreadMode threadMode = WebKit::Platform::current()->is ThreadedCompositingEnabled() ? Canvas2DLayerBridge::Threaded : Canvas2DLayerBrid ge::SingleThread; | 82 Canvas2DLayerBridge::ThreadMode threadMode = WebKit::Platform::current()->is ThreadedCompositingEnabled() ? Canvas2DLayerBridge::Threaded : Canvas2DLayerBrid ge::SingleThread; |
84 SkImage::Info info; | 83 SkImage::Info info; |
85 info.fWidth = size.width(); | 84 info.fWidth = size.width(); |
86 info.fHeight = size.height(); | 85 info.fHeight = size.height(); |
87 info.fColorType = SkImage::kPMColor_ColorType; | 86 info.fColorType = SkImage::kPMColor_ColorType; |
88 info.fAlphaType = SkImage::kPremul_AlphaType; | 87 info.fAlphaType = SkImage::kPremul_AlphaType; |
89 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context3D->grCont ext(), info)); | 88 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context3D->grCont ext(), info)); |
90 if (!surface.get()) | 89 if (!surface.get()) |
91 return 0; | 90 return 0; |
92 SkDeferredCanvas* canvas = new SkDeferredCanvas(surface.get()); | 91 SkDeferredCanvas* canvas = new SkDeferredCanvas(surface.get()); |
93 data->m_layerBridge = Canvas2DLayerBridge::create(context3D.release(), canva s, bridgeOpacityMode, threadMode); | 92 data->m_layerBridge = Canvas2DLayerBridge::create(context3D.release(), canva s, bridgeOpacityMode, threadMode); |
94 // If canvas buffer allocation failed, debug build will have asserted | 93 // If canvas buffer allocation failed, debug build will have asserted |
95 // For release builds, we must verify whether the device has a render target | 94 // For release builds, we must verify whether the device has a render target |
96 data->m_platformContext.setAccelerated(true); | |
97 return canvas; | 95 return canvas; |
98 } | 96 } |
99 | 97 |
100 static SkCanvas* createNonPlatformCanvas(const IntSize& size) | 98 static SkCanvas* createNonPlatformCanvas(const IntSize& size) |
101 { | 99 { |
102 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())); |
103 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); | 101 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); |
104 return pixelRef ? new SkCanvas(device) : 0; | 102 return pixelRef ? new SkCanvas(device) : 0; |
105 } | 103 } |
106 | 104 |
(...skipping 23 matching lines...) Expand all Loading... | |
130 return; | 128 return; |
131 } | 129 } |
132 | 130 |
133 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); | 131 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); |
134 if (!pixelRef) { | 132 if (!pixelRef) { |
135 success = false; | 133 success = false; |
136 return; | 134 return; |
137 } | 135 } |
138 | 136 |
139 m_data.m_canvas = adoptPtr(new SkCanvas(device)); | 137 m_data.m_canvas = adoptPtr(new SkCanvas(device)); |
140 m_data.m_platformContext.setCanvas(m_data.m_canvas.get()); | 138 m_context = adoptPtr(new GraphicsContext(m_data.m_canvas.get())); |
141 m_context = adoptPtr(new GraphicsContext(&m_data.m_platformContext)); | |
142 m_context->setShouldSmoothFonts(false); | 139 m_context->setShouldSmoothFonts(false); |
143 m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale)); | 140 m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale)); |
144 | 141 |
145 success = true; | 142 success = true; |
146 } | 143 } |
147 | 144 |
148 ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace, RenderingMode renderingMode, OpacityMode opacityMode, bool& success) | 145 ImageBuffer::ImageBuffer(const IntSize& size, float resolutionScale, ColorSpace, RenderingMode renderingMode, OpacityMode opacityMode, bool& success) |
149 : m_data(size) | 146 : m_data(size) |
150 , m_size(size) | 147 , m_size(size) |
151 , m_logicalSize(size) | 148 , m_logicalSize(size) |
152 , m_resolutionScale(resolutionScale) | 149 , m_resolutionScale(resolutionScale) |
153 { | 150 { |
154 OwnPtr<SkCanvas> canvas; | 151 OwnPtr<SkCanvas> canvas; |
155 | 152 |
156 if (renderingMode == Accelerated) | 153 bool isAccelerated = false; |
jamesr
2013/04/30 19:57:08
nit: isAccelerated is the same as renderingMode ==
| |
154 if (renderingMode == Accelerated) { | |
157 canvas = adoptPtr(createAcceleratedCanvas(size, &m_data, opacityMode)); | 155 canvas = adoptPtr(createAcceleratedCanvas(size, &m_data, opacityMode)); |
156 isAccelerated = true; | |
157 } | |
158 else if (renderingMode == UnacceleratedNonPlatformBuffer) | 158 else if (renderingMode == UnacceleratedNonPlatformBuffer) |
159 canvas = adoptPtr(createNonPlatformCanvas(size)); | 159 canvas = adoptPtr(createNonPlatformCanvas(size)); |
160 | 160 |
161 if (!canvas) | 161 if (!canvas) |
162 canvas = adoptPtr(skia::TryCreateBitmapCanvas(size.width(), size.height( ), false)); | 162 canvas = adoptPtr(skia::TryCreateBitmapCanvas(size.width(), size.height( ), false)); |
163 | 163 |
164 if (!canvas) { | 164 if (!canvas) { |
165 success = false; | 165 success = false; |
166 return; | 166 return; |
167 } | 167 } |
168 | 168 |
169 m_data.m_canvas = canvas.release(); | 169 m_data.m_canvas = canvas.release(); |
170 m_data.m_platformContext.setCanvas(m_data.m_canvas.get()); | 170 m_context = adoptPtr(new GraphicsContext(m_data.m_canvas.get())); |
171 m_context = adoptPtr(new GraphicsContext(&m_data.m_platformContext)); | |
172 m_context->setShouldSmoothFonts(opacityMode == Opaque); | 171 m_context->setShouldSmoothFonts(opacityMode == Opaque); |
172 m_context->platformContext()->setAccelerated(isAccelerated); | |
173 m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale)); | 173 m_context->scale(FloatSize(m_resolutionScale, m_resolutionScale)); |
174 | 174 |
175 // Clear the background transparent or opaque, as required. It would be nice if this wasn't | 175 // Clear the background transparent or opaque, as required. It would be nice if this wasn't |
176 // required, but the canvas is currently filled with the magic transparency | 176 // required, but the canvas is currently filled with the magic transparency |
177 // color. Can we have another way to manage this? | 177 // color. Can we have another way to manage this? |
178 if (opacityMode == Opaque) | 178 if (opacityMode == Opaque) |
179 m_data.m_canvas->drawARGB(255, 0, 0, 0, SkXfermode::kSrc_Mode); | 179 m_data.m_canvas->drawARGB(255, 0, 0, 0, SkXfermode::kSrc_Mode); |
180 else | 180 else |
181 m_data.m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); | 181 m_data.m_canvas->drawARGB(0, 0, 0, 0, SkXfermode::kClear_Mode); |
182 | 182 |
(...skipping 18 matching lines...) Expand all Loading... | |
201 { | 201 { |
202 SkBitmap tmp; | 202 SkBitmap tmp; |
203 if (!bitmap.deepCopyTo(&tmp, bitmap.config())) | 203 if (!bitmap.deepCopyTo(&tmp, bitmap.config())) |
204 bitmap.copyTo(&tmp, bitmap.config()); | 204 bitmap.copyTo(&tmp, bitmap.config()); |
205 | 205 |
206 return tmp; | 206 return tmp; |
207 } | 207 } |
208 | 208 |
209 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh avior) const | 209 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh avior) const |
210 { | 210 { |
211 const SkBitmap& bitmap = *m_data.m_platformContext.bitmap(); | 211 const SkBitmap& bitmap = *context()->platformContext()->bitmap(); |
212 // FIXME: Start honoring ScaleBehavior to scale 2x buffers down to 1x. | 212 // FIXME: Start honoring ScaleBehavior to scale 2x buffers down to 1x. |
213 return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBacki ngStore ? deepSkBitmapCopy(bitmap) : bitmap, m_resolutionScale)); | 213 return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBacki ngStore ? deepSkBitmapCopy(bitmap) : bitmap, m_resolutionScale)); |
214 } | 214 } |
215 | 215 |
216 BackingStoreCopy ImageBuffer::fastCopyImageMode() | 216 BackingStoreCopy ImageBuffer::fastCopyImageMode() |
217 { | 217 { |
218 return DontCopyBackingStore; | 218 return DontCopyBackingStore; |
219 } | 219 } |
220 | 220 |
221 PlatformLayer* ImageBuffer::platformLayer() const | 221 PlatformLayer* ImageBuffer::platformLayer() const |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
257 } | 257 } |
258 | 258 |
259 static bool drawNeedsCopy(GraphicsContext* src, GraphicsContext* dst) | 259 static bool drawNeedsCopy(GraphicsContext* src, GraphicsContext* dst) |
260 { | 260 { |
261 return (src == dst); | 261 return (src == dst); |
262 } | 262 } |
263 | 263 |
264 void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con st FloatRect& destRect, const FloatRect& srcRect, | 264 void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con st FloatRect& destRect, const FloatRect& srcRect, |
265 CompositeOperator op, BlendMode, bool useLowQualityScale) | 265 CompositeOperator op, BlendMode, bool useLowQualityScale) |
266 { | 266 { |
267 const SkBitmap& bitmap = *m_data.m_platformContext.bitmap(); | 267 const SkBitmap& bitmap = *m_context->platformContext()->bitmap(); |
268 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); | 268 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); |
269 context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, DoNo tRespectImageOrientation, useLowQualityScale); | 269 context->drawImage(image.get(), styleColorSpace, destRect, srcRect, op, DoNo tRespectImageOrientation, useLowQualityScale); |
270 } | 270 } |
271 | 271 |
272 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect , const AffineTransform& patternTransform, | 272 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect , const AffineTransform& patternTransform, |
273 const FloatPoint& phase, ColorSpace styleColorSpac e, CompositeOperator op, const FloatRect& destRect) | 273 const FloatPoint& phase, ColorSpace styleColorSpac e, CompositeOperator op, const FloatRect& destRect) |
274 { | 274 { |
275 const SkBitmap& bitmap = *m_data.m_platformContext.bitmap(); | 275 const SkBitmap& bitmap = *m_context->platformContext()->bitmap(); |
276 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); | 276 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); |
277 image->drawPattern(context, srcRect, patternTransform, phase, styleColorSpac e, op, destRect); | 277 image->drawPattern(context, srcRect, patternTransform, phase, styleColorSpac e, op, destRect); |
278 } | 278 } |
279 | 279 |
280 void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) | 280 void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) |
281 { | 281 { |
282 // FIXME: Disable color space conversions on accelerated canvases (for now). | 282 // FIXME: Disable color space conversions on accelerated canvases (for now). |
283 if (m_data.m_platformContext.isAccelerated()) | 283 if (context()->platformContext()->isAccelerated()) |
284 return; | 284 return; |
285 | 285 |
286 const SkBitmap& bitmap = *context()->platformContext()->bitmap(); | 286 const SkBitmap& bitmap = *context()->platformContext()->bitmap(); |
287 if (bitmap.isNull()) | 287 if (bitmap.isNull()) |
288 return; | 288 return; |
289 | 289 |
290 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); | 290 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); |
291 SkAutoLockPixels bitmapLock(bitmap); | 291 SkAutoLockPixels bitmapLock(bitmap); |
292 for (int y = 0; y < m_size.height(); ++y) { | 292 for (int y = 0; y < m_size.height(); ++y) { |
293 uint32_t* srcRow = bitmap.getAddr32(0, y); | 293 uint32_t* srcRow = bitmap.getAddr32(0, y); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 Vector<char> base64Data; | 423 Vector<char> base64Data; |
424 base64Encode(encodedImage, base64Data); | 424 base64Encode(encodedImage, base64Data); |
425 | 425 |
426 return "data:" + mimeType + ";base64," + base64Data; | 426 return "data:" + mimeType + ";base64," + base64Data; |
427 } | 427 } |
428 | 428 |
429 void ImageBufferData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) cons t | 429 void ImageBufferData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) cons t |
430 { | 430 { |
431 MemoryClassInfo info(memoryObjectInfo, this); | 431 MemoryClassInfo info(memoryObjectInfo, this); |
432 info.addMember(m_canvas, "canvas"); | 432 info.addMember(m_canvas, "canvas"); |
433 info.addMember(m_platformContext, "platformContext"); | |
434 info.addMember(m_layerBridge, "layerBridge"); | 433 info.addMember(m_layerBridge, "layerBridge"); |
435 } | 434 } |
436 | 435 |
437 String ImageDataToDataURL(const ImageData& imageData, const String& mimeType, co nst double* quality) | 436 String ImageDataToDataURL(const ImageData& imageData, const String& mimeType, co nst double* quality) |
438 { | 437 { |
439 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); | 438 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); |
440 | 439 |
441 Vector<char> encodedImage; | 440 Vector<char> encodedImage; |
442 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) | 441 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) |
443 return "data:,"; | 442 return "data:,"; |
444 | 443 |
445 Vector<char> base64Data; | 444 Vector<char> base64Data; |
446 base64Encode(encodedImage, base64Data); | 445 base64Encode(encodedImage, base64Data); |
447 | 446 |
448 return "data:" + mimeType + ";base64," + base64Data; | 447 return "data:" + mimeType + ";base64," + base64Data; |
449 } | 448 } |
450 | 449 |
451 } // namespace WebCore | 450 } // namespace WebCore |
OLD | NEW |