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

Side by Side Diff: skia/ext/skia_utils_mac.mm

Issue 2705723002: Convert SkiaBitLocker to use PaintCanvas (Closed)
Patch Set: Remove rogue cc:: Created 3 years, 10 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
« no previous file with comments | « skia/ext/skia_utils_mac.h ('k') | skia/ext/skia_utils_mac_unittest.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "skia/ext/skia_utils_mac.h" 5 #include "skia/ext/skia_utils_mac.h"
6 6
7 #import <AppKit/AppKit.h> 7 #import <AppKit/AppKit.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <memory> 10 #include <memory>
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 [image setSize:NSMakeSize(skiaBitmap.width(), skiaBitmap.height())]; 234 [image setSize:NSMakeSize(skiaBitmap.width(), skiaBitmap.height())];
235 return [image.release() autorelease]; 235 return [image.release() autorelease];
236 } 236 }
237 237
238 NSImage* SkBitmapToNSImage(const SkBitmap& skiaBitmap) { 238 NSImage* SkBitmapToNSImage(const SkBitmap& skiaBitmap) {
239 base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace( 239 base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace(
240 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB)); 240 CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB));
241 return SkBitmapToNSImageWithColorSpace(skiaBitmap, colorSpace.get()); 241 return SkBitmapToNSImageWithColorSpace(skiaBitmap, colorSpace.get());
242 } 242 }
243 243
244 SkiaBitLocker::SkiaBitLocker(SkCanvas* canvas,
245 const SkIRect& userClipRect,
246 SkScalar bitmapScaleFactor)
247 : canvas_(canvas),
248 cgContext_(0),
249 bitmapScaleFactor_(bitmapScaleFactor),
250 useDeviceBits_(false),
251 bitmapIsDummy_(false) {
252 canvas_->save();
253 canvas_->clipRect(SkRect::MakeFromIRect(userClipRect));
254 }
255
256 SkiaBitLocker::~SkiaBitLocker() {
257 releaseIfNeeded();
258 canvas_->restore();
259 }
260
261 SkIRect SkiaBitLocker::computeDirtyRect() {
262 // If the user specified a clip region, assume that it was tight and that the
263 // dirty rect is approximately the whole bitmap.
264 return SkIRect::MakeWH(offscreen_.width(), offscreen_.height());
265 }
266
267 // This must be called to balance calls to cgContext
268 void SkiaBitLocker::releaseIfNeeded() {
269 if (!cgContext_)
270 return;
271 if (!useDeviceBits_ && !bitmapIsDummy_) {
272 // Find the bits that were drawn to.
273 SkIRect bounds = computeDirtyRect();
274 SkBitmap subset;
275 if (!offscreen_.extractSubset(&subset, bounds)) {
276 return;
277 }
278 subset.setImmutable(); // Prevents a defensive copy inside Skia.
279 canvas_->save();
280 canvas_->setMatrix(SkMatrix::I()); // Reset back to device space.
281 canvas_->translate(bounds.x() + bitmapOffset_.x(),
282 bounds.y() + bitmapOffset_.y());
283 canvas_->scale(1.f / bitmapScaleFactor_, 1.f / bitmapScaleFactor_);
284 canvas_->drawBitmap(subset, 0, 0);
285 canvas_->restore();
286 }
287 CGContextRelease(cgContext_);
288 cgContext_ = 0;
289 useDeviceBits_ = false;
290 bitmapIsDummy_ = false;
291 }
292
293 CGContextRef SkiaBitLocker::cgContext() {
294 releaseIfNeeded(); // This flushes any prior bitmap use
295
296 SkIRect clip_bounds;
297 if (!canvas_->getDeviceClipBounds(&clip_bounds)) {
298 // If the clip is empty, then there is nothing to draw. The caller may
299 // attempt to draw (to-be-clipped) results, so ensure there is a dummy
300 // non-NULL CGContext to use.
301 bitmapIsDummy_ = true;
302 clip_bounds = SkIRect::MakeXYWH(0, 0, 1, 1);
303 }
304
305 // remember the top/left, in case we need to compose this later
306 bitmapOffset_.set(clip_bounds.x(), clip_bounds.y());
307
308 // Now make clip_bounds be relative to the current layer/device
309 if (!bitmapIsDummy_) {
310 canvas_->temporary_internal_describeTopLayer(nullptr, &clip_bounds);
311 }
312
313 SkPixmap devicePixels;
314 skia::GetWritablePixels(canvas_, &devicePixels);
315
316 // Only draw directly if we have pixels, and we're only rect-clipped.
317 // If not, we allocate an offscreen and draw into that, relying on the
318 // compositing step to apply skia's clip.
319 useDeviceBits_ = devicePixels.addr() &&
320 canvas_->isClipRect() &&
321 !bitmapIsDummy_;
322 base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace(
323 CGColorSpaceCreateDeviceRGB());
324
325 int displayHeight;
326 if (useDeviceBits_) {
327 SkPixmap subset;
328 bool result = devicePixels.extractSubset(&subset, clip_bounds);
329 DCHECK(result);
330 if (!result)
331 return 0;
332 displayHeight = subset.height();
333 cgContext_ = CGBitmapContextCreate(subset.writable_addr(), subset.width(),
334 subset.height(), 8, subset.rowBytes(), colorSpace,
335 kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
336 } else {
337 bool result = offscreen_.tryAllocN32Pixels(
338 SkScalarCeilToInt(bitmapScaleFactor_ * clip_bounds.width()),
339 SkScalarCeilToInt(bitmapScaleFactor_ * clip_bounds.height()));
340 DCHECK(result);
341 if (!result)
342 return 0;
343 offscreen_.eraseColor(0);
344 displayHeight = offscreen_.height();
345 cgContext_ = CGBitmapContextCreate(offscreen_.getPixels(),
346 offscreen_.width(), offscreen_.height(), 8, offscreen_.rowBytes(),
347 colorSpace, kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst);
348 }
349 DCHECK(cgContext_);
350
351 SkMatrix matrix = canvas_->getTotalMatrix();
352 matrix.postTranslate(-SkIntToScalar(bitmapOffset_.x()),
353 -SkIntToScalar(bitmapOffset_.y()));
354 matrix.postScale(bitmapScaleFactor_, -bitmapScaleFactor_);
355 matrix.postTranslate(0, SkIntToScalar(displayHeight));
356
357 CGContextConcatCTM(cgContext_, SkMatrixToCGAffineTransform(matrix));
358
359 return cgContext_;
360 }
361
362 bool SkiaBitLocker::hasEmptyClipRegion() const {
363 return canvas_->isClipEmpty();
364 }
365
366 } // namespace skia 244 } // namespace skia
OLDNEW
« no previous file with comments | « skia/ext/skia_utils_mac.h ('k') | skia/ext/skia_utils_mac_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698