| Index: skia/ext/skia_utils_mac.mm
|
| diff --git a/skia/ext/skia_utils_mac.mm b/skia/ext/skia_utils_mac.mm
|
| index 6a624a8e69a0f06352dcd58e37d4e6a6cd8a76e7..2a96d59e4f8cbd017ef9442552295af0eae018b1 100644
|
| --- a/skia/ext/skia_utils_mac.mm
|
| +++ b/skia/ext/skia_utils_mac.mm
|
| @@ -284,11 +284,8 @@ SkiaBitLocker::~SkiaBitLocker() {
|
| void SkiaBitLocker::releaseIfNeeded() {
|
| if (!cgContext_)
|
| return;
|
| - if (useDeviceBits_) {
|
| - bitmap_.unlockPixels();
|
| - } else {
|
| + if (useBitmap_) {
|
| // Find the bits that were drawn to.
|
| - SkAutoLockPixels lockedPixels(bitmap_);
|
| const uint32_t* pixelBase
|
| = reinterpret_cast<uint32_t*>(bitmap_.getPixels());
|
| int rowPixels = bitmap_.rowBytesAsPixels();
|
| @@ -370,55 +367,53 @@ foundRight:
|
| }
|
|
|
| CGContextRef SkiaBitLocker::cgContext() {
|
| - SkBaseDevice* device = canvas_->getTopDevice();
|
| - DCHECK(device);
|
| - if (!device)
|
| - return 0;
|
| releaseIfNeeded(); // This flushes any prior bitmap use
|
| - const SkBitmap& deviceBits = device->accessBitmap(true);
|
| - useDeviceBits_ = deviceBits.getPixels();
|
| - if (useDeviceBits_) {
|
| - bitmap_ = deviceBits;
|
| - bitmap_.lockPixels();
|
| +
|
| + SkIRect clip_bounds;
|
| + const bool clip_is_empty = !canvas_->getClipDeviceBounds(&clip_bounds);
|
| +
|
| + SkImageInfo info;
|
| + size_t row_bytes;
|
| + SkIPoint origin;
|
| + void* top_pixels = canvas_->accessTopLayerPixels(&info, &row_bytes, &origin);
|
| + if (top_pixels && (clip_is_empty || canvas_->isClipRect())) {
|
| + useBitmap_ = false;
|
| } else {
|
| - bitmap_.setConfig(
|
| - SkBitmap::kARGB_8888_Config, deviceBits.width(), deviceBits.height());
|
| - bitmap_.allocPixels();
|
| + useBitmap_ = true;
|
| + info = SkImageInfo::MakeN32Premul(clip_bounds.width(), clip_bounds.height());
|
| + origin.set(clip_bounds.x(), clip_bounds.y());
|
| + CHECK(bitmap_.allocPixels(info));
|
| bitmap_.eraseColor(0);
|
| + top_pixels = bitmap_.getPixels();
|
| }
|
| +
|
| base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace(
|
| CGColorSpaceCreateDeviceRGB());
|
| - cgContext_ = CGBitmapContextCreate(bitmap_.getPixels(), bitmap_.width(),
|
| - bitmap_.height(), 8, bitmap_.rowBytes(), colorSpace,
|
| - kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
|
| + cgContext_ = CGBitmapContextCreate(top_pixels, info.width(),
|
| + info.height(), 8, row_bytes, colorSpace,
|
| + kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
|
|
|
| // Apply device matrix.
|
| CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1);
|
| contentsTransform = CGAffineTransformTranslate(contentsTransform, 0,
|
| - -device->height());
|
| + -info.height());
|
| CGContextConcatCTM(cgContext_, contentsTransform);
|
|
|
| - const SkIPoint& pt = device->getOrigin();
|
| // Skip applying the clip when not writing directly to device.
|
| // They're applied in the offscreen case when the bitmap is drawn.
|
| - if (useDeviceBits_) {
|
| + if (!useBitmap_) {
|
| // Apply clip in device coordinates.
|
| CGMutablePathRef clipPath = CGPathCreateMutable();
|
| - const SkRegion& clipRgn = canvas_->getTotalClip();
|
| - if (clipRgn.isEmpty()) {
|
| + if (clip_is_empty) {
|
| // CoreGraphics does not consider a newly created path to be empty.
|
| // Explicitly set it to empty so the subsequent drawing is clipped out.
|
| // It would be better to make the CGContext hidden if there was a CG
|
| // call that does that.
|
| CGPathAddRect(clipPath, 0, CGRectMake(0, 0, 0, 0));
|
| - }
|
| - SkRegion::Iterator iter(clipRgn);
|
| - const SkIPoint& pt = device->getOrigin();
|
| - for (; !iter.done(); iter.next()) {
|
| - SkIRect skRect = iter.rect();
|
| - skRect.offset(-pt);
|
| - CGRect cgRect = SkIRectToCGRect(skRect);
|
| - CGPathAddRect(clipPath, 0, cgRect);
|
| + } else {
|
| + SkIRect r = clip_bounds;
|
| + r.offset(-origin);
|
| + CGPathAddRect(clipPath, 0, SkIRectToCGRect(r));
|
| }
|
| CGContextAddPath(cgContext_, clipPath);
|
| CGContextClip(cgContext_);
|
| @@ -427,7 +422,7 @@ CGContextRef SkiaBitLocker::cgContext() {
|
|
|
| // Apply content matrix.
|
| SkMatrix skMatrix = canvas_->getTotalMatrix();
|
| - skMatrix.postTranslate(-SkIntToScalar(pt.fX), -SkIntToScalar(pt.fY));
|
| + skMatrix.postTranslate(-SkIntToScalar(origin.fX), -SkIntToScalar(origin.fY));
|
| CGAffineTransform affine = SkMatrixToCGAffineTransform(skMatrix);
|
| CGContextConcatCTM(cgContext_, affine);
|
|
|
|
|