Changeset 91496 in webkit
- Timestamp:
- Jul 21, 2011, 1:49:38 PM (14 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r91494 r91496 1 2011-07-19 Matthew Delaney <mdelaney@apple.com> 2 3 Add fast path for ImageBuffer::draw 4 https://bugs.webkit.org/show_bug.cgi?id=64535 5 6 Reviewed by Simon Fraser. 7 8 No new tests. This patch doesn't change behavior; current tests are sufficient. 9 10 * platform/graphics/GraphicsContext.cpp: 11 (WebCore::GraphicsContext::drawImage): Moved the main method version next to wrapper versions. 12 13 * platform/graphics/ImageBuffer.h: 14 1) Added BackingStoreCopy enum for choosing to copy backing store or not in copyImage(). 15 2) Added copyNativeImage() behind USE(CG) - same as copyImage() but gives NativeImagePtr. 16 * platform/graphics/cg/ImageBufferCG.cpp: Added new methods described above. 17 18 * platform/graphics/GraphicsContext.h: Adding drawNativeImage() for fast draw path. 19 * platform/graphics/cg/GraphicsContextCG.cpp: 20 (WebCore::GraphicsContext::drawNativeImage): Added. Draws a nativeImagePtr into context. 21 22 * platform/graphics/Image.h: Added imageWithColorSpace behind CG platform ifdef 23 * platform/graphics/cg/ImageCG.cpp: 24 (WebCore::BitmapImage::draw): Refactored out actual image drawing code into GraphicsContext, 25 so that it can be used by more than just BitmapImage without having to copy code. 26 (WebCore::Image::imageWithColorSpace): Made into an Image class function. 27 28 Updated copyImage() to for BackingStoreCopy: 29 * platform/graphics/qt/ImageBufferQt.cpp 30 * platform/graphics/filters/FETile.cpp 31 * platform/graphics/cairo/ImageBufferCairo.cpp 32 * platform/graphics/skia/ImageBufferSkia.cpp 33 * platform/graphics/wx/ImageBufferWx.cpp 34 * platform/graphics/wince/ImageBufferWinCE.cpp 35 * svg/SVGFEImageElement.cpp 36 * svg/graphics/SVGImage.cpp 37 * html/HTMLCanvasElement.cpp 38 * html/canvas/WebGLRenderingContext.cpp 39 * rendering/svg/RenderSVGResourcePattern.cpp 40 41 <<<<<<< .mine 42 2011-07-21 Matthew Delaney <mdelaney@apple.com> 43 44 Add fast path for ImageBuffer::draw, Take 2. 45 https://bugs.webkit.org/show_bug.cgi?id=64535 46 47 Reviewed by Simon Fraser. 48 49 No new tests. This patch doesn't change behavior; current tests are sufficient. 50 51 * platform/graphics/GraphicsContext.cpp: 52 (WebCore::GraphicsContext::drawImage): Moved the main method version next to wrapper versions. 53 54 * platform/graphics/ImageBuffer.h: 55 1) Added BackingStoreCopy enum for choosing to copy backing store or not in copyImage(). 56 2) Added copyNativeImage() behind USE(CG) - same as copyImage() but gives NativeImagePtr. 57 * platform/graphics/cg/ImageBufferCG.cpp: Added new methods described above. 58 59 * platform/graphics/GraphicsContext.h: Adding drawNativeImage() for fast draw path. 60 * platform/graphics/cg/GraphicsContextCG.cpp: 61 (WebCore::GraphicsContext::drawNativeImage): Added. Draws a nativeImagePtr into context. 62 63 * platform/graphics/Image.h: Added imageWithColorSpace behind CG platform ifdef 64 * platform/graphics/cg/ImageCG.cpp: 65 (WebCore::BitmapImage::draw): Refactored out actual image drawing code into GraphicsContext, 66 so that it can be used by more than just BitmapImage without having to copy code. 67 (WebCore::Image::imageWithColorSpace): Made into an Image class function. 68 69 Updated copyImage() to for BackingStoreCopy: 70 * platform/graphics/qt/ImageBufferQt.cpp 71 * platform/graphics/filters/FETile.cpp 72 * platform/graphics/cairo/ImageBufferCairo.cpp 73 * platform/graphics/skia/ImageBufferSkia.cpp 74 * platform/graphics/wx/ImageBufferWx.cpp 75 * platform/graphics/wince/ImageBufferWinCE.cpp 76 * svg/SVGFEImageElement.cpp 77 * svg/graphics/SVGImage.cpp 78 * html/HTMLCanvasElement.cpp 79 * html/canvas/WebGLRenderingContext.cpp 80 * rendering/svg/RenderSVGResourcePattern.cpp 81 82 ======= 1 83 2011-07-21 David Kilzer <ddkilzer@apple.com> 2 84 … … 74 156 on InlineBox to calculate the position. 75 157 158 >>>>>>> .r91495 76 159 2011-07-21 Pavel Feldman <pfeldman@google.com> 77 160 -
trunk/Source/WebCore/html/HTMLCanvasElement.cpp
r91446 r91496 310 310 if (!m_presentedImage) { 311 311 // The buffer contains the last presented data, so save a copy of it. 312 m_presentedImage = buffer()->copyImage( );312 m_presentedImage = buffer()->copyImage(CopyBackingStore); 313 313 } 314 314 } … … 473 473 if (m_context) 474 474 m_context->paintRenderingResultsToCanvas(); 475 m_copiedImage = buffer()->copyImage( );475 m_copiedImage = buffer()->copyImage(CopyBackingStore); 476 476 } 477 477 return m_copiedImage.get(); -
trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
r91446 r91496 3215 3215 // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback. 3216 3216 video->paintCurrentFrameInContext(buf->context(), destRect); 3217 return buf->copyImage( );3217 return buf->copyImage(CopyBackingStore); 3218 3218 } 3219 3219 -
trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp
r91446 r91496 352 352 } 353 353 354 void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntPoint& p, CompositeOperator op)355 {356 drawImage(image, styleColorSpace, p, IntRect(0, 0, -1, -1), op);357 }358 359 void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntRect& r, CompositeOperator op, bool useLowQualityScale)360 {361 drawImage(image, styleColorSpace, r, IntRect(0, 0, -1, -1), op, useLowQualityScale);362 }363 364 void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntPoint& dest, const IntRect& srcRect, CompositeOperator op)365 {366 drawImage(image, styleColorSpace, IntRect(dest, srcRect.size()), srcRect, op);367 }368 369 void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, CompositeOperator op, bool useLowQualityScale)370 {371 drawImage(image, styleColorSpace, FloatRect(dest), srcRect, op, useLowQualityScale);372 }373 374 354 #if !OS(WINCE) || (PLATFORM(QT) && !HAVE(QRAWFONT)) 375 355 void GraphicsContext::drawText(const Font& font, const TextRun& run, const FloatPoint& point, int from, int to) … … 432 412 433 413 fillRect(font.selectionRectForText(run, point, h, from, to), backgroundColor, colorSpace); 414 } 415 416 void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntPoint& p, CompositeOperator op) 417 { 418 drawImage(image, styleColorSpace, p, IntRect(0, 0, -1, -1), op); 419 } 420 421 void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntRect& r, CompositeOperator op, bool useLowQualityScale) 422 { 423 drawImage(image, styleColorSpace, r, IntRect(0, 0, -1, -1), op, useLowQualityScale); 424 } 425 426 void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntPoint& dest, const IntRect& srcRect, CompositeOperator op) 427 { 428 drawImage(image, styleColorSpace, IntRect(dest, srcRect.size()), srcRect, op); 429 } 430 431 void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, CompositeOperator op, bool useLowQualityScale) 432 { 433 drawImage(image, styleColorSpace, FloatRect(dest), srcRect, op, useLowQualityScale); 434 434 } 435 435 -
trunk/Source/WebCore/platform/graphics/GraphicsContext.h
r91446 r91496 266 266 void drawPath(const Path&); 267 267 268 void drawNativeImage(NativeImagePtr, const FloatSize& selfSize, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator = CompositeSourceOver); 269 268 270 // Allow font smoothing (LCD antialiasing). Not part of the graphics state. 269 271 void setAllowsFontSmoothing(bool); -
trunk/Source/WebCore/platform/graphics/Image.h
r91446 r91496 142 142 virtual CGImageRef getFirstCGImageRefOfSize(const IntSize&) { return 0; } 143 143 virtual RetainPtr<CFArrayRef> getCGImageArray() { return 0; } 144 static RetainPtr<CGImageRef> imageWithColorSpace(CGImageRef originalImage, ColorSpace); 144 145 #endif 145 146 -
trunk/Source/WebCore/platform/graphics/ImageBuffer.h
r91446 r91496 59 59 Accelerated 60 60 }; 61 62 enum BackingStoreCopy { 63 CopyBackingStore, // Guarantee subsequent draws don't affect the copy. 64 DontCopyBackingStore // Subsequent draws may affect the copy. 65 }; 61 66 62 67 class ImageBuffer { … … 84 89 85 90 bool isAccelerated() const { return m_accelerateRendering; } 86 PassRefPtr<Image> copyImage( ) const; // Return a new image that is a copy of the buffer.91 PassRefPtr<Image> copyImage(BackingStoreCopy = CopyBackingStore) const; 87 92 88 93 PassRefPtr<ByteArray> getUnmultipliedImageData(const IntRect&) const; … … 104 109 105 110 private: 111 #if USE(CG) 112 NativeImagePtr copyNativeImage(BackingStoreCopy = CopyBackingStore) const; 113 #endif 114 106 115 void clip(GraphicsContext*, const FloatRect&) const; 107 116 108 // The draw method draws the contents of the buffer without copying it. 109 void draw(GraphicsContext*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), 110 CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 111 void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, 112 const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); 113 117 void draw(GraphicsContext*, ColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); 118 void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); 119 114 120 inline void genericConvertToLuminanceMask(); 115 121 -
trunk/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
r91446 r91496 87 87 } 88 88 89 PassRefPtr<Image> ImageBuffer::copyImage() const 90 { 89 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const 90 { 91 ASSERT(copyBehavior == CopyBackingStore); 91 92 // BitmapImage will release the passed in surface on destruction 92 93 return BitmapImage::create(copyCairoImageSurface(m_data.m_surface).leakRef()); -
trunk/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
r91446 r91496 153 153 } 154 154 155 void GraphicsContext::drawNativeImage(NativeImagePtr imagePtr, const FloatSize& imageSize, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op) 156 { 157 RetainPtr<CGImageRef> image(imagePtr); 158 159 float currHeight = CGImageGetHeight(image.get()); 160 if (currHeight <= srcRect.y()) 161 return; 162 163 CGContextRef context = platformContext(); 164 CGContextSaveGState(context); 165 166 bool shouldUseSubimage = false; 167 168 // If the source rect is a subportion of the image, then we compute an inflated destination rect that will hold the entire image 169 // and then set a clip to the portion that we want to display. 170 FloatRect adjustedDestRect = destRect; 171 172 if (srcRect.size() != imageSize) { 173 CGInterpolationQuality interpolationQuality = CGContextGetInterpolationQuality(context); 174 // When the image is scaled using high-quality interpolation, we create a temporary CGImage 175 // containing only the portion we want to display. We need to do this because high-quality 176 // interpolation smoothes sharp edges, causing pixels from outside the source rect to bleed 177 // into the destination rect. See <rdar://problem/6112909>. 178 shouldUseSubimage = (interpolationQuality != kCGInterpolationNone) && (srcRect.size() != destRect.size() || !getCTM().isIdentityOrTranslationOrFlipped()); 179 float xScale = srcRect.width() / destRect.width(); 180 float yScale = srcRect.height() / destRect.height(); 181 if (shouldUseSubimage) { 182 FloatRect subimageRect = srcRect; 183 float leftPadding = srcRect.x() - floorf(srcRect.x()); 184 float topPadding = srcRect.y() - floorf(srcRect.y()); 185 186 subimageRect.move(-leftPadding, -topPadding); 187 adjustedDestRect.move(-leftPadding / xScale, -topPadding / yScale); 188 189 subimageRect.setWidth(ceilf(subimageRect.width() + leftPadding)); 190 adjustedDestRect.setWidth(subimageRect.width() / xScale); 191 192 subimageRect.setHeight(ceilf(subimageRect.height() + topPadding)); 193 adjustedDestRect.setHeight(subimageRect.height() / yScale); 194 195 image.adoptCF(CGImageCreateWithImageInRect(image.get(), subimageRect)); 196 if (currHeight < srcRect.maxY()) { 197 ASSERT(CGImageGetHeight(image.get()) == currHeight - CGRectIntegral(srcRect).origin.y); 198 adjustedDestRect.setHeight(CGImageGetHeight(image.get()) / yScale); 199 } 200 } else { 201 adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale)); 202 adjustedDestRect.setSize(FloatSize(imageSize.width() / xScale, imageSize.height() / yScale)); 203 } 204 205 if (!destRect.contains(adjustedDestRect)) 206 CGContextClipToRect(context, destRect); 207 } 208 209 // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly. 210 if (!shouldUseSubimage && currHeight < imageSize.height()) 211 adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / imageSize.height()); 212 213 setPlatformCompositeOperation(op); 214 215 // Flip the coords. 216 CGContextScaleCTM(context, 1, -1); 217 adjustedDestRect.setY(-adjustedDestRect.maxY()); 218 219 // Adjust the color space. 220 image = Image::imageWithColorSpace(image.get(), styleColorSpace); 221 222 // Draw the image. 223 CGContextDrawImage(context, adjustedDestRect, image.get()); 224 225 CGContextRestoreGState(context); 226 } 227 155 228 // Draws a filled rectangle with a stroked border. 156 229 void GraphicsContext::drawRect(const IntRect& rect) -
trunk/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp
r91446 r91496 41 41 #include <wtf/RetainPtr.h> 42 42 #include <wtf/Threading.h> 43 #include <wtf/UnusedParam.h> 43 44 #include <math.h> 44 45 … … 178 179 } 179 180 180 PassRefPtr<Image> ImageBuffer::copyImage() const 181 { 182 // BitmapImage will release the passed in CGImage on destruction 183 CGImageRef ctxImage = 0; 184 if (!m_accelerateRendering) 185 ctxImage = CGBitmapContextCreateImage(context()->platformContext()); 181 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const 182 { 183 RetainPtr<CGImageRef> image = copyNativeImage(copyBehavior); 184 185 if (!image) 186 return 0; 187 188 return BitmapImage::create(image.get()); 189 } 190 191 NativeImagePtr ImageBuffer::copyNativeImage(BackingStoreCopy copyBehavior) const 192 { 193 CGImageRef image = 0; 194 if (!m_accelerateRendering) { 195 switch (copyBehavior) { 196 case DontCopyBackingStore: 197 image = CGImageCreate(m_size.width(), m_size.height(), 8, 32, m_data.m_bytesPerRow, m_data.m_colorSpace, m_data.m_bitmapInfo, m_data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault); 198 break; 199 case CopyBackingStore: 200 image = CGBitmapContextCreateImage(context()->platformContext()); 201 break; 202 default: 203 ASSERT_NOT_REACHED(); 204 break; 205 } 206 } 186 207 #if USE(IOSURFACE_CANVAS_BACKING_STORE) 187 208 else 188 ctxImage = wkIOSurfaceContextCreateImage(context()->platformContext()); 189 #endif 190 return BitmapImage::create(ctxImage); 191 } 192 193 static CGImageRef cgImage(const IntSize& size, const ImageBufferData& data) 194 { 195 return CGImageCreate(size.width(), size.height(), 8, 32, data.m_bytesPerRow, 196 data.m_colorSpace, data.m_bitmapInfo, data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault); 197 } 198 199 void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, 200 CompositeOperator op, bool useLowQualityScale) 209 image = wkIOSurfaceContextCreateImage(context()->platformContext()); 210 #endif 211 212 return image; 213 } 214 215 void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale) 216 { 217 UNUSED_PARAM(useLowQualityScale); 218 ColorSpace colorSpace = (destContext == m_context) ? ColorSpaceDeviceRGB : styleColorSpace; 219 220 RetainPtr<CGImageRef> image; 221 if (destContext == m_context) 222 image.adoptCF(copyNativeImage(CopyBackingStore)); // Drawing into our own buffer, need to deep copy. 223 else 224 image.adoptCF(copyNativeImage(DontCopyBackingStore)); 225 226 destContext->drawNativeImage(image.get(), m_size, colorSpace, destRect, srcRect, op); 227 } 228 229 void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) 201 230 { 202 231 if (!m_accelerateRendering) { 203 if (destContext == context()) { 204 // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. 205 RefPtr<Image> copy = copyImage(); 206 destContext->drawImage(copy.get(), ColorSpaceDeviceRGB, destRect, srcRect, op, useLowQualityScale); 232 if (context == m_context) { 233 RefPtr<Image> copy = copyImage(CopyBackingStore); // Drawing into our own buffer, need to deep copy. 234 copy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 207 235 } else { 208 RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data));209 destContext->drawImage(imageForRendering.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);236 RefPtr<Image> imageForRendering = copyImage(DontCopyBackingStore); 237 imageForRendering->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 210 238 } 211 239 } else { 212 RefPtr<Image> copy = copyImage(); 213 ColorSpace colorSpace = (destContext == context()) ? ColorSpaceDeviceRGB : styleColorSpace; 214 destContext->drawImage(copy.get(), colorSpace, destRect, srcRect, op, useLowQualityScale); 215 } 216 } 217 218 void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform, 219 const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) 220 { 221 if (!m_accelerateRendering) { 222 if (destContext == context()) { 223 // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. 224 RefPtr<Image> copy = copyImage(); 225 copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 226 } else { 227 RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data)); 228 imageForRendering->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 229 } 230 } else { 231 RefPtr<Image> copy = copyImage(); 232 copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 240 RefPtr<Image> copy = copyImage(CopyBackingStore); 241 copy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 233 242 } 234 243 } … … 237 246 { 238 247 CGContextRef platformContextToClip = contextToClip->platformContext(); 239 RetainPtr<CGImageRef> image; 240 if (!m_accelerateRendering) 241 image.adoptCF(cgImage(m_size, m_data)); 242 #if USE(IOSURFACE_CANVAS_BACKING_STORE) 243 else 244 image.adoptCF(wkIOSurfaceContextCreateImage(context()->platformContext())); 245 #endif 248 RetainPtr<CGImageRef> image(AdoptCF, copyNativeImage(DontCopyBackingStore)); 246 249 CGContextTranslateCTM(platformContextToClip, rect.x(), rect.y() + rect.height()); 247 250 CGContextScaleCTM(platformContextToClip, 1, -1); … … 347 350 ASSERT(MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(mimeType)); 348 351 349 RetainPtr<CGImageRef> image; 350 if (!m_accelerateRendering) 351 image.adoptCF(CGBitmapContextCreateImage(context()->platformContext())); 352 #if USE(IOSURFACE_CANVAS_BACKING_STORE) 353 else 354 image.adoptCF(wkIOSurfaceContextCreateImage(context()->platformContext())); 355 #endif 352 RetainPtr<CGImageRef> image(AdoptCF, copyNativeImage(CopyBackingStore)); 356 353 357 354 if (!image) -
trunk/Source/WebCore/platform/graphics/cg/ImageCG.cpp
r91446 r91496 129 129 } 130 130 131 static RetainPtr<CGImageRef>imageWithColorSpace(CGImageRef originalImage, ColorSpace colorSpace)131 RetainPtr<CGImageRef> Image::imageWithColorSpace(CGImageRef originalImage, ColorSpace colorSpace) 132 132 { 133 133 CGColorSpaceRef originalColorSpace = CGImageGetColorSpace(originalImage); … … 196 196 } 197 197 198 float currHeight = CGImageGetHeight(image.get());199 if (currHeight <= srcRect.y())200 return;201 202 CGContextRef context = ctxt->platformContext();203 GraphicsContextStateSaver stateSaver(*ctxt);204 205 bool shouldUseSubimage = false;206 207 // If the source rect is a subportion of the image, then we compute an inflated destination rect that will hold the entire image208 // and then set a clip to the portion that we want to display.209 FloatRect adjustedDestRect = destRect;210 198 FloatSize selfSize = currentFrameSize(); 211 if (srcRect.size() != selfSize) { 212 CGInterpolationQuality interpolationQuality = CGContextGetInterpolationQuality(context); 213 // When the image is scaled using high-quality interpolation, we create a temporary CGImage 214 // containing only the portion we want to display. We need to do this because high-quality 215 // interpolation smoothes sharp edges, causing pixels from outside the source rect to bleed 216 // into the destination rect. See <rdar://problem/6112909>. 217 shouldUseSubimage = (interpolationQuality != kCGInterpolationNone) && (srcRect.size() != destRect.size() || !ctxt->getCTM().isIdentityOrTranslationOrFlipped()); 218 float xScale = srcRect.width() / destRect.width(); 219 float yScale = srcRect.height() / destRect.height(); 220 if (shouldUseSubimage) { 221 FloatRect subimageRect = srcRect; 222 float leftPadding = srcRect.x() - floorf(srcRect.x()); 223 float topPadding = srcRect.y() - floorf(srcRect.y()); 224 225 subimageRect.move(-leftPadding, -topPadding); 226 adjustedDestRect.move(-leftPadding / xScale, -topPadding / yScale); 227 228 subimageRect.setWidth(ceilf(subimageRect.width() + leftPadding)); 229 adjustedDestRect.setWidth(subimageRect.width() / xScale); 230 231 subimageRect.setHeight(ceilf(subimageRect.height() + topPadding)); 232 adjustedDestRect.setHeight(subimageRect.height() / yScale); 233 234 image.adoptCF(CGImageCreateWithImageInRect(image.get(), subimageRect)); 235 if (currHeight < srcRect.maxY()) { 236 ASSERT(CGImageGetHeight(image.get()) == currHeight - CGRectIntegral(srcRect).origin.y); 237 adjustedDestRect.setHeight(CGImageGetHeight(image.get()) / yScale); 238 } 239 } else { 240 adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale)); 241 adjustedDestRect.setSize(FloatSize(selfSize.width() / xScale, selfSize.height() / yScale)); 242 } 243 244 if (!destRect.contains(adjustedDestRect)) 245 CGContextClipToRect(context, destRect); 246 } 247 248 // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly. 249 if (!shouldUseSubimage && currHeight < selfSize.height()) 250 adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height()); 251 252 ctxt->setCompositeOperation(compositeOp); 253 254 // Flip the coords. 255 CGContextScaleCTM(context, 1, -1); 256 adjustedDestRect.setY(-adjustedDestRect.maxY()); 257 258 // Adjust the color space. 259 image = imageWithColorSpace(image.get(), styleColorSpace); 260 261 // Draw the image. 262 CGContextDrawImage(context, adjustedDestRect, image.get()); 263 264 stateSaver.restore(); 199 200 ctxt->drawNativeImage(image.get(), selfSize, styleColorSpace, destRect, srcRect, compositeOp); 265 201 266 202 if (imageObserver()) … … 314 250 315 251 // Adjust the color space. 316 subImage = imageWithColorSpace(subImage.get(), styleColorSpace);252 subImage = Image::imageWithColorSpace(subImage.get(), styleColorSpace); 317 253 318 254 // Leopard has an optimized call for the tiling of image patterns, but we can only use it if the image has been decoded enough that -
trunk/Source/WebCore/platform/graphics/filters/FETile.cpp
r91446 r91496 80 80 tileImageContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, in->absolutePaintRect().location()); 81 81 82 RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage( ), true, true);82 RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(CopyBackingStore), true, true); 83 83 84 84 AffineTransform patternTransform; -
trunk/Source/WebCore/platform/graphics/qt/ImageBufferQt.cpp
r91446 r91496 122 122 } 123 123 124 PassRefPtr<Image> ImageBuffer::copyImage() const 125 { 124 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const 125 { 126 ASSERT(copyBehavior == CopyBackingStore); 126 127 return StillImage::create(m_data.m_pixmap); 127 128 } … … 132 133 if (destContext == context()) { 133 134 // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. 134 RefPtr<Image> copy = copyImage( );135 RefPtr<Image> copy = copyImage(CopyBackingStore); 135 136 destContext->drawImage(copy.get(), ColorSpaceDeviceRGB, destRect, srcRect, op, useLowQualityScale); 136 137 } else … … 143 144 if (destContext == context()) { 144 145 // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. 145 RefPtr<Image> copy = copyImage( );146 RefPtr<Image> copy = copyImage(CopyBackingStore); 146 147 copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 147 148 } else -
trunk/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp
r91446 r91496 98 98 } 99 99 100 PassRefPtr<Image> ImageBuffer::copyImage() const 101 { 100 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const 101 { 102 ASSERT(copyBehavior == CopyBackingStore); 102 103 m_context->platformContext()->makeGrContextCurrent(); 103 104 return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap(), true); -
trunk/Source/WebCore/platform/graphics/wince/ImageBufferWinCE.cpp
r91446 r91496 99 99 } 100 100 101 PassRefPtr<Image> ImageBuffer::copyImage() const 102 { 101 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const 102 { 103 ASSERT(copyBehavior == CopyBackingStore); 103 104 return adoptRef(new BufferedImage(&m_data)); 104 105 } … … 112 113 CompositeOperator op , bool useLowQualityScale) 113 114 { 114 RefPtr<Image> imageCopy = copyImage( );115 RefPtr<Image> imageCopy = copyImage(CopyBackingStore); 115 116 context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); 116 117 } … … 119 120 const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) 120 121 { 121 RefPtr<Image> imageCopy = copyImage( );122 RefPtr<Image> imageCopy = copyImage(CopyBackingStore); 122 123 imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 123 124 } -
trunk/Source/WebCore/platform/graphics/wx/ImageBufferWx.cpp
r91446 r91496 89 89 } 90 90 91 PassRefPtr<Image> ImageBuffer::copyImage( ) const91 PassRefPtr<Image> ImageBuffer::copyImage(BackingStoreCopy copyBehavior) const 92 92 { 93 ASSERT(copyBehavior == CopyBackingStore); 93 94 notImplemented(); 94 95 return 0; … … 103 104 CompositeOperator op, bool useLowQualityScale) 104 105 { 105 RefPtr<Image> imageCopy = copyImage( );106 RefPtr<Image> imageCopy = copyImage(CopyBackingStore); 106 107 context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); 107 108 } … … 110 111 const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) 111 112 { 112 RefPtr<Image> imageCopy = copyImage( );113 RefPtr<Image> imageCopy = copyImage(CopyBackingStore); 113 114 imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); 114 115 } -
trunk/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
r91446 r91496 125 125 return false; 126 126 127 RefPtr<Image> copiedImage = tileImage->copyImage( );127 RefPtr<Image> copiedImage = tileImage->copyImage(CopyBackingStore); 128 128 if (!copiedImage) 129 129 return false; -
trunk/Source/WebCore/svg/SVGFEImageElement.cpp
r91446 r91496 179 179 } 180 180 181 return FEImage::create(filter, m_targetImage ? m_targetImage->copyImage( ) : m_cachedImage->image(), preserveAspectRatio());181 return FEImage::create(filter, m_targetImage ? m_targetImage->copyImage(CopyBackingStore) : m_cachedImage->image(), preserveAspectRatio()); 182 182 } 183 183 -
trunk/Source/WebCore/svg/graphics/SVGImage.cpp
r91446 r91496 228 228 return 0; 229 229 draw(buffer->context(), rect(), rect(), ColorSpaceDeviceRGB, CompositeSourceOver); 230 m_frameCache = buffer->copyImage( );230 m_frameCache = buffer->copyImage(CopyBackingStore); 231 231 } 232 232 return m_frameCache->nativeImageForCurrentFrame();
Note:
See TracChangeset
for help on using the changeset viewer.