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

Side by Side Diff: ios/chrome/browser/snapshots/snapshot_cache.mm

Issue 1587663002: Enable the snapshot cache on iPad when the tab switcher is enabled. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 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 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 #import "ios/chrome/browser/snapshots/snapshot_cache.h" 5 #import "ios/chrome/browser/snapshots/snapshot_cache.h"
6 6
7 #import <UIKit/UIKit.h> 7 #import <UIKit/UIKit.h>
8 8
9 #include "base/critical_closure.h" 9 #include "base/critical_closure.h"
10 #include "base/files/file_enumerator.h" 10 #include "base/files/file_enumerator.h"
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 + (SnapshotCache*)sharedInstance { 137 + (SnapshotCache*)sharedInstance {
138 static SnapshotCache* instance = [[SnapshotCache alloc] init]; 138 static SnapshotCache* instance = [[SnapshotCache alloc] init];
139 return instance; 139 return instance;
140 } 140 }
141 141
142 - (id)init { 142 - (id)init {
143 if ((self = [super init])) { 143 if ((self = [super init])) {
144 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 144 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
145 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]); 145 propertyReleaser_SnapshotCache_.Init(self, [SnapshotCache class]);
146 146
147 if (!IsIPadIdiom()) { 147 // Always use the LRUCache when the tab switcher is enabled.
148 if (experimental_flags::IsLRUSnapshotCacheEnabled()) { 148 if (experimental_flags::IsTabSwitcherEnabled() ||
msarda 2016/01/13 16:25:27 As discussed offline, this will potentially exclud
jbbegue (google) 2016/01/14 12:38:24 This is what we want. The iPad should only use the
149 lruCache_.reset( 149 experimental_flags::IsLRUSnapshotCacheEnabled()) {
150 [[LRUCache alloc] initWithCacheSize:kLRUCacheMaxCapacity]); 150 lruCache_.reset(
151 } else { 151 [[LRUCache alloc] initWithCacheSize:kLRUCacheMaxCapacity]);
152 imageDictionary_.reset([[NSMutableDictionary alloc] 152 } else {
153 initWithCapacity:kCacheInitialCapacity]); 153 imageDictionary_.reset(
154 } 154 [[NSMutableDictionary alloc] initWithCapacity:kCacheInitialCapacity]);
155 }
155 156
157 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) {
156 [[NSNotificationCenter defaultCenter] 158 [[NSNotificationCenter defaultCenter]
157 addObserver:self 159 addObserver:self
158 selector:@selector(handleLowMemory) 160 selector:@selector(handleLowMemory)
159 name:UIApplicationDidReceiveMemoryWarningNotification 161 name:UIApplicationDidReceiveMemoryWarningNotification
160 object:nil]; 162 object:nil];
161 [[NSNotificationCenter defaultCenter] 163 [[NSNotificationCenter defaultCenter]
162 addObserver:self 164 addObserver:self
163 selector:@selector(handleEnterBackground) 165 selector:@selector(handleEnterBackground)
164 name:UIApplicationDidEnterBackgroundNotification 166 name:UIApplicationDidEnterBackgroundNotification
165 object:nil]; 167 object:nil];
166 [[NSNotificationCenter defaultCenter] 168 [[NSNotificationCenter defaultCenter]
167 addObserver:self 169 addObserver:self
168 selector:@selector(handleBecomeActive) 170 selector:@selector(handleBecomeActive)
169 name:UIApplicationDidBecomeActiveNotification 171 name:UIApplicationDidBecomeActiveNotification
170 object:nil]; 172 object:nil];
171 } 173 }
172 } 174 }
173 return self; 175 return self;
174 } 176 }
175 177
176 - (void)dealloc { 178 - (void)dealloc {
177 if (!IsIPadIdiom()) { 179 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) {
178 [[NSNotificationCenter defaultCenter] 180 [[NSNotificationCenter defaultCenter]
179 removeObserver:self 181 removeObserver:self
180 name:UIApplicationDidReceiveMemoryWarningNotification 182 name:UIApplicationDidReceiveMemoryWarningNotification
181 object:nil]; 183 object:nil];
182 [[NSNotificationCenter defaultCenter] 184 [[NSNotificationCenter defaultCenter]
183 removeObserver:self 185 removeObserver:self
184 name:UIApplicationDidEnterBackgroundNotification 186 name:UIApplicationDidEnterBackgroundNotification
185 object:nil]; 187 object:nil];
186 [[NSNotificationCenter defaultCenter] 188 [[NSNotificationCenter defaultCenter]
187 removeObserver:self 189 removeObserver:self
(...skipping 12 matching lines...) Expand all
200 return 1.0; 202 return 1.0;
201 } 203 }
202 // Cap snapshot resolution to 2x to reduce the amount of memory they use. 204 // Cap snapshot resolution to 2x to reduce the amount of memory they use.
203 return MIN([UIScreen mainScreen].scale, 2.0); 205 return MIN([UIScreen mainScreen].scale, 2.0);
204 } 206 }
205 207
206 - (void)retrieveImageForSessionID:(NSString*)sessionID 208 - (void)retrieveImageForSessionID:(NSString*)sessionID
207 callback:(void (^)(UIImage*))callback { 209 callback:(void (^)(UIImage*))callback {
208 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 210 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
209 DCHECK(sessionID); 211 DCHECK(sessionID);
210 // iPad does not cache images, so if there is no callback we can avoid an 212
211 // expensive read from storage. 213 // Cache on iPad is enabled only when the tab switcher is enabled.
212 if (IsIPadIdiom() && !callback) 214 if (IsIPadIdiom() && !experimental_flags::IsTabSwitcherEnabled())
msarda 2016/01/13 16:25:27 Optional: Consider adding a function IsCacheEnable
jbbegue (google) 2016/01/14 12:38:24 You are right I'll do that in another CL.
215 return;
216
217 if (!callback)
213 return; 218 return;
214 219
215 UIImage* img = nil; 220 UIImage* img = nil;
216 if (lruCache_) 221 if (lruCache_)
217 img = [lruCache_ objectForKey:sessionID]; 222 img = [lruCache_ objectForKey:sessionID];
218 else 223 else
219 img = [imageDictionary_ objectForKey:sessionID]; 224 img = [imageDictionary_ objectForKey:sessionID];
220 225
221 if (img) { 226 if (img) {
222 if (callback) 227 if (callback)
223 callback(img); 228 callback(img);
224 return; 229 return;
225 } 230 }
226 231
227 base::PostTaskAndReplyWithResult( 232 base::PostTaskAndReplyWithResult(
228 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE_USER_BLOCKING) 233 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE_USER_BLOCKING)
229 .get(), 234 .get(),
230 FROM_HERE, base::BindBlock(^base::scoped_nsobject<UIImage>() { 235 FROM_HERE, base::BindBlock(^base::scoped_nsobject<UIImage>() {
231 // Retrieve the image on a high priority thread. 236 // Retrieve the image on a high priority thread.
232 return base::scoped_nsobject<UIImage>([ReadImageFromDisk( 237 return base::scoped_nsobject<UIImage>([ReadImageFromDisk(
233 [SnapshotCache imagePathForSessionID:sessionID]) retain]); 238 [SnapshotCache imagePathForSessionID:sessionID]) retain]);
234 }), 239 }),
235 base::BindBlock(^(base::scoped_nsobject<UIImage> image) { 240 base::BindBlock(^(base::scoped_nsobject<UIImage> image) {
236 // The iPad tab switcher is currently using its own memory cache so the 241 // Cache on iPad is enabled only when the tab switcher is enabled.
237 // image is not stored in memory here if running on iPad. 242 if ((!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) &&
238 // The same logic is used on image writes (code below). 243 image) {
239 if (!IsIPadIdiom() && image) {
240 if (lruCache_) 244 if (lruCache_)
241 [lruCache_ setObject:image forKey:sessionID]; 245 [lruCache_ setObject:image forKey:sessionID];
242 else 246 else
243 [imageDictionary_ setObject:image forKey:sessionID]; 247 [imageDictionary_ setObject:image forKey:sessionID];
244 } 248 }
245 if (callback) 249 if (callback)
246 callback(image); 250 callback(image);
247 })); 251 }));
248 } 252 }
249 253
250 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID { 254 - (void)setImage:(UIImage*)img withSessionID:(NSString*)sessionID {
251 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 255 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
252 if (!img || !sessionID) 256 if (!img || !sessionID)
253 return; 257 return;
254 258
255 // The iPad tab switcher is currently using its own memory cache so the image 259 // Cache on iPad is enabled only when the tab switcher is enabled.
256 // is not stored in memory here if running on iPad. 260 if (!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled()) {
257 // The same logic is used on image reads (code above).
258 if (!IsIPadIdiom()) {
259 if (lruCache_) 261 if (lruCache_)
260 [lruCache_ setObject:img forKey:sessionID]; 262 [lruCache_ setObject:img forKey:sessionID];
261 else 263 else
262 [imageDictionary_ setObject:img forKey:sessionID]; 264 [imageDictionary_ setObject:img forKey:sessionID];
263 } 265 }
264 // Save the image to disk. 266 // Save the image to disk.
265 web::WebThread::PostBlockingPoolSequencedTask( 267 web::WebThread::PostBlockingPoolSequencedTask(
266 kSequenceToken, FROM_HERE, 268 kSequenceToken, FROM_HERE,
267 base::BindBlock(^{ 269 base::BindBlock(^{
268 base::scoped_nsobject<UIImage> image([img retain]); 270 base::scoped_nsobject<UIImage> image([img retain]);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 backgroundingImageSessionId_.reset([sessionID copy]); 382 backgroundingImageSessionId_.reset([sessionID copy]);
381 if (lruCache_) { 383 if (lruCache_) {
382 backgroundingColorImage_.reset([[lruCache_ objectForKey:sessionID] retain]); 384 backgroundingColorImage_.reset([[lruCache_ objectForKey:sessionID] retain]);
383 } else { 385 } else {
384 backgroundingColorImage_.reset( 386 backgroundingColorImage_.reset(
385 [[imageDictionary_ objectForKey:sessionID] retain]); 387 [[imageDictionary_ objectForKey:sessionID] retain]);
386 } 388 }
387 } 389 }
388 390
389 - (void)handleLowMemory { 391 - (void)handleLowMemory {
390 DCHECK(!IsIPadIdiom()); 392 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled());
391 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 393 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
392 NSMutableDictionary* dictionary = 394 NSMutableDictionary* dictionary =
393 [[NSMutableDictionary alloc] initWithCapacity:2]; 395 [[NSMutableDictionary alloc] initWithCapacity:2];
394 for (NSString* sessionID in pinnedIDs_) { 396 for (NSString* sessionID in pinnedIDs_) {
395 UIImage* image = nil; 397 UIImage* image = nil;
396 if (lruCache_) 398 if (lruCache_)
397 image = [lruCache_ objectForKey:sessionID]; 399 image = [lruCache_ objectForKey:sessionID];
398 else 400 else
399 image = [imageDictionary_ objectForKey:sessionID]; 401 image = [imageDictionary_ objectForKey:sessionID];
400 if (image) 402 if (image)
401 [dictionary setObject:image forKey:sessionID]; 403 [dictionary setObject:image forKey:sessionID];
402 } 404 }
403 if (lruCache_) { 405 if (lruCache_) {
404 [lruCache_ removeAllObjects]; 406 [lruCache_ removeAllObjects];
405 for (NSString* sessionID in pinnedIDs_) 407 for (NSString* sessionID in pinnedIDs_)
406 [lruCache_ setObject:dictionary[sessionID] forKey:sessionID]; 408 [lruCache_ setObject:dictionary[sessionID] forKey:sessionID];
407 } else { 409 } else {
408 imageDictionary_.reset(dictionary); 410 imageDictionary_.reset(dictionary);
409 } 411 }
410 } 412 }
411 413
412 - (void)handleEnterBackground { 414 - (void)handleEnterBackground {
413 DCHECK(!IsIPadIdiom()); 415 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled());
414 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 416 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
415 [imageDictionary_ removeAllObjects]; 417 [imageDictionary_ removeAllObjects];
416 [lruCache_ removeAllObjects]; 418 [lruCache_ removeAllObjects];
417 } 419 }
418 420
419 - (void)handleBecomeActive { 421 - (void)handleBecomeActive {
420 DCHECK(!IsIPadIdiom()); 422 DCHECK(!IsIPadIdiom() || experimental_flags::IsTabSwitcherEnabled());
421 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 423 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
422 for (NSString* sessionID in pinnedIDs_) 424 for (NSString* sessionID in pinnedIDs_)
423 [self retrieveImageForSessionID:sessionID callback:nil]; 425 [self retrieveImageForSessionID:sessionID callback:nil];
424 } 426 }
425 427
426 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID { 428 - (void)saveGreyImage:(UIImage*)greyImage forKey:(NSString*)sessionID {
427 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI); 429 DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
428 if (greyImage) 430 if (greyImage)
429 [greyImageDictionary_ setObject:greyImage forKey:sessionID]; 431 [greyImageDictionary_ setObject:greyImage forKey:sessionID];
430 if ([sessionID isEqualToString:mostRecentGreySessionId_]) { 432 if ([sessionID isEqualToString:mostRecentGreySessionId_]) {
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 } 577 }
576 - (BOOL)hasGreyImageInMemory:(NSString*)sessionID { 578 - (BOOL)hasGreyImageInMemory:(NSString*)sessionID {
577 return [greyImageDictionary_ objectForKey:sessionID] != nil; 579 return [greyImageDictionary_ objectForKey:sessionID] != nil;
578 } 580 }
579 581
580 - (NSUInteger)lruCacheMaxSize { 582 - (NSUInteger)lruCacheMaxSize {
581 return [lruCache_ maxCacheSize]; 583 return [lruCache_ maxCacheSize];
582 } 584 }
583 585
584 @end 586 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698