1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "ios/chrome/browser/snapshots/snapshot_manager.h"
7 #import <QuartzCore/QuartzCore.h>
9 #include "base/logging.h"
10 #import "ios/chrome/browser/snapshots/snapshot_cache.h"
11 #import "ios/chrome/browser/snapshots/snapshot_overlay.h"
13 @implementation SnapshotManager
15 - (UIImage*)generateSnapshotForView:(UIView*)view
17 overlays:(NSArray*)overlays {
19 CGSize size = rect.size;
20 DCHECK(std::isnormal(size.width) && (size.width > 0))
21 << ": size.width=" << size.width;
22 DCHECK(std::isnormal(size.height) && (size.height > 0))
23 << ": size.height=" << size.height;
24 const CGFloat kScale = [SnapshotCache snapshotScaleForDevice];
25 UIGraphicsBeginImageContextWithOptions(size, YES, kScale);
26 CGContext* context = UIGraphicsGetCurrentContext();
32 CGContextSaveGState(context);
33 CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y);
34 #if defined(ENABLE_WKWEBVIEW)
35 // -drawViewHierarchyInRect:afterScreenUpdates:YES is buggy as of iOS 8.1.1.
36 // Using it afterScreenUpdates:YES creates unexpected GPU glitches, screen
37 // redraws during animations, broken pinch to dismiss on tablet, etc. For now
38 // only using this with ENABLE_WKWEBVIEW, which depends on
39 // -drawViewHierarchyInRect.
40 [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
42 [[view layer] renderInContext:context];
44 if ([overlays count]) {
45 for (SnapshotOverlay* overlay in overlays) {
46 // Render the overlay view at the desired offset. It is achieved
47 // by shifting origin of context because view frame is ignored when
48 // drawing to context.
49 CGContextSaveGState(context);
50 CGContextTranslateCTM(context, 0, overlay.yOffset);
51 #if defined(ENABLE_WKWEBVIEW)
52 CGRect overlayRect = overlay.view.bounds;
53 // TODO(jyquinn): The 0 check is needed for a UIKit crash on iOS 7. This
54 // can be removed once iOS 7 is dropped. crbug.com/421213
55 if (overlayRect.size.width > 0 && overlayRect.size.height > 0) {
56 [overlay.view drawViewHierarchyInRect:overlay.view.bounds
57 afterScreenUpdates:YES];
60 [[overlay.view layer] renderInContext:context];
62 CGContextRestoreGState(context);
65 UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
66 CGContextRestoreGState(context);
67 UIGraphicsEndImageContext();
71 - (void)retrieveImageForSessionID:(NSString*)sessionID
72 callback:(void (^)(UIImage*))callback {
73 [[SnapshotCache sharedInstance] retrieveImageForSessionID:sessionID
77 - (void)retrieveGreyImageForSessionID:(NSString*)sessionID
78 callback:(void (^)(UIImage*))callback {
79 [[SnapshotCache sharedInstance] retrieveGreyImageForSessionID:sessionID
83 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID {
84 [[SnapshotCache sharedInstance] setImage:img withSessionID:sessionID];
87 - (void)removeImageWithSessionID:(NSString*)sessionID {
88 [[SnapshotCache sharedInstance] removeImageWithSessionID:sessionID];
91 - (void)greyImageForSessionID:(NSString*)sessionID
92 callback:(void (^)(UIImage*))callback {
93 [[SnapshotCache sharedInstance] greyImageForSessionID:sessionID