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

Side by Side Diff: Source/core/platform/graphics/ImageBuffer.cpp

Issue 16032003: Fixing Canvas2DLayerBridge to handle lost graphics contexts (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Resolved merge with rate limiter CL Created 7 years, 5 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
59 59
60 using namespace std; 60 using namespace std;
61 61
62 namespace WebCore { 62 namespace WebCore {
63 63
64 static SkCanvas* createAcceleratedCanvas(const IntSize& size, OwnPtr<Canvas2DLay erBridge>* outLayerBridge, OpacityMode opacityMode) 64 static SkCanvas* createAcceleratedCanvas(const IntSize& size, OwnPtr<Canvas2DLay erBridge>* outLayerBridge, OpacityMode opacityMode)
65 { 65 {
66 RefPtr<GraphicsContext3D> context3D = SharedGraphicsContext3D::get(); 66 RefPtr<GraphicsContext3D> context3D = SharedGraphicsContext3D::get();
67 if (!context3D) 67 if (!context3D)
68 return 0; 68 return 0;
69 GrContext* gr = context3D->grContext();
70 if (!gr)
71 return 0;
72 gr->resetContext();
73 Canvas2DLayerBridge::OpacityMode bridgeOpacityMode = opacityMode == Opaque ? Canvas2DLayerBridge::Opaque : Canvas2DLayerBridge::NonOpaque; 69 Canvas2DLayerBridge::OpacityMode bridgeOpacityMode = opacityMode == Opaque ? Canvas2DLayerBridge::Opaque : Canvas2DLayerBridge::NonOpaque;
74 SkImage::Info info; 70 *outLayerBridge = Canvas2DLayerBridge::create(context3D.release(), size, bri dgeOpacityMode);
75 info.fWidth = size.width();
76 info.fHeight = size.height();
77 info.fColorType = SkImage::kPMColor_ColorType;
78 info.fAlphaType = SkImage::kPremul_AlphaType;
79 SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(context3D->grCont ext(), info));
80 if (!surface.get())
81 return 0;
82 SkDeferredCanvas* canvas = new SkDeferredCanvas(surface.get());
83 *outLayerBridge = Canvas2DLayerBridge::create(context3D.release(), canvas, b ridgeOpacityMode);
84 // If canvas buffer allocation failed, debug build will have asserted 71 // If canvas buffer allocation failed, debug build will have asserted
85 // For release builds, we must verify whether the device has a render target 72 // For release builds, we must verify whether the device has a render target
86 return canvas; 73 return (*outLayerBridge) ? (*outLayerBridge)->getCanvas() : 0;
87 } 74 }
88 75
89 static SkCanvas* createNonPlatformCanvas(const IntSize& size) 76 static SkCanvas* createNonPlatformCanvas(const IntSize& size)
90 { 77 {
91 SkAutoTUnref<SkDevice> device(new SkDevice(SkBitmap::kARGB_8888_Config, size .width(), size.height())); 78 SkAutoTUnref<SkDevice> device(new SkDevice(SkBitmap::kARGB_8888_Config, size .width(), size.height()));
92 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef(); 79 SkPixelRef* pixelRef = device->accessBitmap(false).pixelRef();
93 return pixelRef ? new SkCanvas(device) : 0; 80 return pixelRef ? new SkCanvas(device) : 0;
94 } 81 }
95 82
96 PassOwnPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const IntSize& size, float resolutionScale, const GraphicsContext* context, bool hasAlpha) 83 PassOwnPtr<ImageBuffer> ImageBuffer::createCompatibleBuffer(const IntSize& size, float resolutionScale, const GraphicsContext* context, bool hasAlpha)
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 GraphicsContext* ImageBuffer::context() const 164 GraphicsContext* ImageBuffer::context() const
178 { 165 {
179 if (m_layerBridge) { 166 if (m_layerBridge) {
180 // We're using context acquisition as a signal that someone is about to render into our buffer and we need 167 // We're using context acquisition as a signal that someone is about to render into our buffer and we need
181 // to be ready. This isn't logically const-correct, hence the cast. 168 // to be ready. This isn't logically const-correct, hence the cast.
182 const_cast<Canvas2DLayerBridge*>(m_layerBridge.get())->contextAcquired() ; 169 const_cast<Canvas2DLayerBridge*>(m_layerBridge.get())->contextAcquired() ;
183 } 170 }
184 return m_context.get(); 171 return m_context.get();
185 } 172 }
186 173
174
175 bool ImageBuffer::isValid() const
176 {
177 if (m_layerBridge.get())
178 return const_cast<Canvas2DLayerBridge*>(m_layerBridge.get())->isValid();
179 return true;
180 }
181
187 static SkBitmap deepSkBitmapCopy(const SkBitmap& bitmap) 182 static SkBitmap deepSkBitmapCopy(const SkBitmap& bitmap)
188 { 183 {
189 SkBitmap tmp; 184 SkBitmap tmp;
190 if (!bitmap.deepCopyTo(&tmp, bitmap.config())) 185 if (!bitmap.deepCopyTo(&tmp, bitmap.config()))
191 bitmap.copyTo(&tmp, bitmap.config()); 186 bitmap.copyTo(&tmp, bitmap.config());
192 187
193 return tmp; 188 return tmp;
194 } 189 }
195 190
196 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh avior) const 191 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior, ScaleBeh avior) const
197 { 192 {
193 if (!isValid())
194 return BitmapImage::create(NativeImageSkia::create());
195
198 const SkBitmap& bitmap = *context()->bitmap(); 196 const SkBitmap& bitmap = *context()->bitmap();
199 // FIXME: Start honoring ScaleBehavior to scale 2x buffers down to 1x. 197 // FIXME: Start honoring ScaleBehavior to scale 2x buffers down to 1x.
200 return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBacki ngStore ? deepSkBitmapCopy(bitmap) : bitmap, m_resolutionScale)); 198 return BitmapImage::create(NativeImageSkia::create(copyBehavior == CopyBacki ngStore ? deepSkBitmapCopy(bitmap) : bitmap, m_resolutionScale));
201 } 199 }
202 200
203 BackingStoreCopy ImageBuffer::fastCopyImageMode() 201 BackingStoreCopy ImageBuffer::fastCopyImageMode()
204 { 202 {
205 return DontCopyBackingStore; 203 return DontCopyBackingStore;
206 } 204 }
207 205
208 WebKit::WebLayer* ImageBuffer::platformLayer() const 206 WebKit::WebLayer* ImageBuffer::platformLayer() const
209 { 207 {
210 return m_layerBridge ? m_layerBridge->layer() : 0; 208 return m_layerBridge ? m_layerBridge->layer() : 0;
211 } 209 }
212 210
213 bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3DOb ject texture, GC3Denum internalFormat, GC3Denum destType, GC3Dint level, bool pr emultiplyAlpha, bool flipY) 211 bool ImageBuffer::copyToPlatformTexture(GraphicsContext3D& context, Platform3DOb ject texture, GC3Denum internalFormat, GC3Denum destType, GC3Dint level, bool pr emultiplyAlpha, bool flipY)
214 { 212 {
215 if (!m_layerBridge || !platformLayer()) 213 if (!m_layerBridge || !platformLayer() || !isValid())
216 return false; 214 return false;
217 215
218 Platform3DObject sourceTexture = m_layerBridge->backBufferTexture(); 216 Platform3DObject sourceTexture = m_layerBridge->backBufferTexture();
219 217
220 if (!context.makeContextCurrent()) 218 if (!context.makeContextCurrent())
221 return false; 219 return false;
222 220
223 Extensions3D* extensions = context.getExtensions(); 221 Extensions3D* extensions = context.getExtensions();
224 if (!extensions->supports("GL_CHROMIUM_copy_texture") || !extensions->suppor ts("GL_CHROMIUM_flipy") 222 if (!extensions->supports("GL_CHROMIUM_copy_texture") || !extensions->suppor ts("GL_CHROMIUM_flipy")
225 || !extensions->canUseCopyTextureCHROMIUM(internalFormat, destType, leve l)) 223 || !extensions->canUseCopyTextureCHROMIUM(internalFormat, destType, leve l))
(...skipping 14 matching lines...) Expand all
240 } 238 }
241 239
242 static bool drawNeedsCopy(GraphicsContext* src, GraphicsContext* dst) 240 static bool drawNeedsCopy(GraphicsContext* src, GraphicsContext* dst)
243 { 241 {
244 return (src == dst); 242 return (src == dst);
245 } 243 }
246 244
247 void ImageBuffer::draw(GraphicsContext* context, const FloatRect& destRect, cons t FloatRect& srcRect, 245 void ImageBuffer::draw(GraphicsContext* context, const FloatRect& destRect, cons t FloatRect& srcRect,
248 CompositeOperator op, BlendMode blendMode, bool useLowQualityScale) 246 CompositeOperator op, BlendMode blendMode, bool useLowQualityScale)
249 { 247 {
248 if (!isValid())
249 return;
250
250 const SkBitmap& bitmap = *m_context->bitmap(); 251 const SkBitmap& bitmap = *m_context->bitmap();
251 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); 252 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap));
252 context->drawImage(image.get(), destRect, srcRect, op, blendMode, DoNotRespe ctImageOrientation, useLowQualityScale); 253 context->drawImage(image.get(), destRect, srcRect, op, blendMode, DoNotRespe ctImageOrientation, useLowQualityScale);
253 } 254 }
254 255
255 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect , const FloatSize& scale, 256 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect , const FloatSize& scale,
256 const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect) 257 const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect)
257 { 258 {
259 if (!isValid())
260 return;
261
258 const SkBitmap& bitmap = *m_context->bitmap(); 262 const SkBitmap& bitmap = *m_context->bitmap();
259 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap)); 263 RefPtr<Image> image = BitmapImage::create(NativeImageSkia::create(drawNeedsC opy(m_context.get(), context) ? deepSkBitmapCopy(bitmap) : bitmap));
260 image->drawPattern(context, srcRect, scale, phase, op, destRect); 264 image->drawPattern(context, srcRect, scale, phase, op, destRect);
261 } 265 }
262 266
263 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo lorSpace) 267 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstCo lorSpace)
264 { 268 {
265 if (srcColorSpace == dstColorSpace) 269 if (srcColorSpace == dstColorSpace)
266 return; 270 return;
267 271
268 // only sRGB <-> linearRGB are supported at the moment 272 // only sRGB <-> linearRGB are supported at the moment
269 if ((srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceDevi ceRGB) 273 if ((srcColorSpace != ColorSpaceLinearRGB && srcColorSpace != ColorSpaceDevi ceRGB)
270 || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceD eviceRGB)) 274 || (dstColorSpace != ColorSpaceLinearRGB && dstColorSpace != ColorSpaceD eviceRGB))
271 return; 275 return;
272 276
273 // FIXME: Disable color space conversions on accelerated canvases (for now). 277 // FIXME: Disable color space conversions on accelerated canvases (for now).
274 if (context()->isAccelerated()) 278 if (context()->isAccelerated() || !isValid())
275 return; 279 return;
276 280
277 const SkBitmap& bitmap = *context()->bitmap(); 281 const SkBitmap& bitmap = *context()->bitmap();
278 if (bitmap.isNull()) 282 if (bitmap.isNull())
279 return; 283 return;
280 284
281 const Vector<uint8_t>& lookUpTable = dstColorSpace == ColorSpaceLinearRGB ? 285 const Vector<uint8_t>& lookUpTable = dstColorSpace == ColorSpaceLinearRGB ?
282 getLinearRgbLUT() : getDeviceRgbLUT(); 286 getLinearRgbLUT() : getDeviceRgbLUT();
283 287
284 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); 288 ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 config8888 = SkCanvas::kRGBA_Premul_Config8888; 358 config8888 = SkCanvas::kRGBA_Premul_Config8888;
355 else 359 else
356 config8888 = SkCanvas::kRGBA_Unpremul_Config8888; 360 config8888 = SkCanvas::kRGBA_Unpremul_Config8888;
357 361
358 context->readPixels(&destBitmap, rect.x(), rect.y(), config8888); 362 context->readPixels(&destBitmap, rect.x(), rect.y(), config8888);
359 return result.release(); 363 return result.release();
360 } 364 }
361 365
362 PassRefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRec t& rect, CoordinateSystem) const 366 PassRefPtr<Uint8ClampedArray> ImageBuffer::getUnmultipliedImageData(const IntRec t& rect, CoordinateSystem) const
363 { 367 {
368 if (!isValid())
369 return Uint8ClampedArray::create(rect.width() * rect.height() * 4);
364 return getImageData<Unmultiplied>(rect, context(), m_size); 370 return getImageData<Unmultiplied>(rect, context(), m_size);
365 } 371 }
366 372
367 PassRefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRe ct& rect, CoordinateSystem) const 373 PassRefPtr<Uint8ClampedArray> ImageBuffer::getPremultipliedImageData(const IntRe ct& rect, CoordinateSystem) const
368 { 374 {
375 if (!isValid())
376 return Uint8ClampedArray::create(rect.width() * rect.height() * 4);
369 return getImageData<Premultiplied>(rect, context(), m_size); 377 return getImageData<Premultiplied>(rect, context(), m_size);
370 } 378 }
371 379
372 void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c onst IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem) 380 void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, c onst IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem)
373 { 381 {
382 if (!isValid())
383 return;
384
374 ASSERT(sourceRect.width() > 0); 385 ASSERT(sourceRect.width() > 0);
375 ASSERT(sourceRect.height() > 0); 386 ASSERT(sourceRect.height() > 0);
376 387
377 int originX = sourceRect.x(); 388 int originX = sourceRect.x();
378 int destX = destPoint.x() + sourceRect.x(); 389 int destX = destPoint.x() + sourceRect.x();
379 ASSERT(destX >= 0); 390 ASSERT(destX >= 0);
380 ASSERT(destX < m_size.width()); 391 ASSERT(destX < m_size.width());
381 ASSERT(originX >= 0); 392 ASSERT(originX >= 0);
382 ASSERT(originX < sourceRect.maxX()); 393 ASSERT(originX < sourceRect.maxX());
383 394
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 } 466 }
456 467
457 return true; 468 return true;
458 } 469 }
459 470
460 String ImageBuffer::toDataURL(const String& mimeType, const double* quality, Coo rdinateSystem) const 471 String ImageBuffer::toDataURL(const String& mimeType, const double* quality, Coo rdinateSystem) const
461 { 472 {
462 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); 473 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
463 474
464 Vector<char> encodedImage; 475 Vector<char> encodedImage;
465 if (!encodeImage(*context()->bitmap(), mimeType, quality, &encodedImage)) 476 if (!isValid() || !encodeImage(*context()->bitmap(), mimeType, quality, &enc odedImage))
466 return "data:,"; 477 return "data:,";
467
468 Vector<char> base64Data; 478 Vector<char> base64Data;
469 base64Encode(encodedImage, base64Data); 479 base64Encode(encodedImage, base64Data);
470 480
471 return "data:" + mimeType + ";base64," + base64Data; 481 return "data:" + mimeType + ";base64," + base64Data;
472 } 482 }
473 483
474 String ImageDataToDataURL(const ImageData& imageData, const String& mimeType, co nst double* quality) 484 String ImageDataToDataURL(const ImageData& imageData, const String& mimeType, co nst double* quality)
475 { 485 {
476 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); 486 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType));
477 487
478 Vector<char> encodedImage; 488 Vector<char> encodedImage;
479 if (!encodeImage(imageData, mimeType, quality, &encodedImage)) 489 if (!encodeImage(imageData, mimeType, quality, &encodedImage))
480 return "data:,"; 490 return "data:,";
481 491
482 Vector<char> base64Data; 492 Vector<char> base64Data;
483 base64Encode(encodedImage, base64Data); 493 base64Encode(encodedImage, base64Data);
484 494
485 return "data:" + mimeType + ";base64," + base64Data; 495 return "data:" + mimeType + ";base64," + base64Data;
486 } 496 }
487 497
488 } // namespace WebCore 498 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/ImageBuffer.h ('k') | Source/core/platform/graphics/chromium/Canvas2DLayerBridge.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698