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

Side by Side Diff: cc/tiles/gpu_image_decode_controller.cc

Issue 2101403006: Revert of Add display-resolution caching to GPU IDC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@drt
Patch Set: Fix test expectations to prevent revert from impacting LayoutTests Created 4 years, 5 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "cc/tiles/gpu_image_decode_controller.h" 5 #include "cc/tiles/gpu_image_decode_controller.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 8
9 #include "base/memory/discardable_memory_allocator.h" 9 #include "base/memory/discardable_memory_allocator.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/numerics/safe_math.h" 12 #include "base/numerics/safe_math.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/threading/thread_task_runner_handle.h" 14 #include "base/threading/thread_task_runner_handle.h"
15 #include "cc/debug/devtools_instrumentation.h" 15 #include "cc/debug/devtools_instrumentation.h"
16 #include "cc/output/context_provider.h" 16 #include "cc/output/context_provider.h"
17 #include "cc/raster/tile_task.h" 17 #include "cc/raster/tile_task.h"
18 #include "cc/resources/resource_format_utils.h" 18 #include "cc/resources/resource_format_utils.h"
19 #include "cc/tiles/mipmap_util.h"
20 #include "gpu/command_buffer/client/context_support.h" 19 #include "gpu/command_buffer/client/context_support.h"
21 #include "gpu/command_buffer/client/gles2_interface.h" 20 #include "gpu/command_buffer/client/gles2_interface.h"
22 #include "gpu_image_decode_controller.h" 21 #include "gpu_image_decode_controller.h"
23 #include "skia/ext/texture_handle.h" 22 #include "skia/ext/texture_handle.h"
24 #include "third_party/skia/include/core/SkCanvas.h" 23 #include "third_party/skia/include/core/SkCanvas.h"
25 #include "third_party/skia/include/core/SkRefCnt.h" 24 #include "third_party/skia/include/core/SkRefCnt.h"
26 #include "third_party/skia/include/core/SkSurface.h" 25 #include "third_party/skia/include/core/SkSurface.h"
27 #include "third_party/skia/include/gpu/GrContext.h" 26 #include "third_party/skia/include/gpu/GrContext.h"
28 #include "third_party/skia/include/gpu/GrTexture.h" 27 #include "third_party/skia/include/gpu/GrTexture.h"
29 #include "ui/gfx/skia_util.h" 28 #include "ui/gfx/skia_util.h"
(...skipping 11 matching lines...) Expand all
41 return true; 40 return true;
42 if (std::abs(draw_image.scale().width()) < 41 if (std::abs(draw_image.scale().width()) <
43 std::numeric_limits<float>::epsilon() || 42 std::numeric_limits<float>::epsilon() ||
44 std::abs(draw_image.scale().height()) < 43 std::abs(draw_image.scale().height()) <
45 std::numeric_limits<float>::epsilon()) { 44 std::numeric_limits<float>::epsilon()) {
46 return true; 45 return true;
47 } 46 }
48 return false; 47 return false;
49 } 48 }
50 49
51 // Returns the filter quality to use for scaling the image to upload scale. For
52 // GPU raster, medium and high filter quality are identical for downscales.
53 // Upload scaling is always a downscale, so cap our filter quality to medium.
54 SkFilterQuality CalculateUploadScaleFilterQuality(const DrawImage& draw_image) {
55 return std::min(kMedium_SkFilterQuality, draw_image.filter_quality());
56 }
57
58 SkImage::DeferredTextureImageUsageParams ParamsFromDrawImage( 50 SkImage::DeferredTextureImageUsageParams ParamsFromDrawImage(
59 const DrawImage& draw_image, 51 const DrawImage& draw_image) {
60 int upload_scale_mip_level) {
61 SkImage::DeferredTextureImageUsageParams params; 52 SkImage::DeferredTextureImageUsageParams params;
62 params.fMatrix = draw_image.matrix(); 53 params.fMatrix = draw_image.matrix();
63 params.fQuality = draw_image.filter_quality(); 54 params.fQuality = draw_image.filter_quality();
64 params.fPreScaleMipLevel = upload_scale_mip_level;
65 55
66 return params; 56 return params;
67 } 57 }
68 58
69 // Calculate the mip level to upload-scale the image to before uploading. We use
70 // mip levels rather than exact scales to increase re-use of scaled images.
71 int CalculateUploadScaleMipLevel(const DrawImage& draw_image) {
72 // Images which are being clipped will have color-bleeding if scaled.
73 // TODO(ericrk): Investigate uploading clipped images to handle this case and
74 // provide further optimization. crbug.com/620899
75 if (draw_image.src_rect() != draw_image.image()->bounds())
76 return 0;
77
78 gfx::Size base_size(draw_image.image()->width(),
79 draw_image.image()->height());
80 // Ceil our scaled size so that the mip map generated is guaranteed to be
81 // larger. Take the abs of the scale, as mipmap functions don't handle
82 // (and aren't impacted by) negative image dimensions.
83 gfx::Size scaled_size =
84 gfx::ScaleToCeiledSize(base_size, std::abs(draw_image.scale().width()),
85 std::abs(draw_image.scale().height()));
86
87 return MipMapUtil::GetLevelForSize(base_size, scaled_size);
88 }
89
90 // Calculates the scale factor which can be used to scale an image to a given
91 // mip level.
92 SkSize CalculateScaleFactorForMipLevel(const DrawImage& draw_image,
93 int mip_level) {
94 gfx::Size base_size(draw_image.image()->width(),
95 draw_image.image()->height());
96 return MipMapUtil::GetScaleAdjustmentForLevel(base_size, mip_level);
97 }
98
99 // Generates a uint64_t which uniquely identifies a DrawImage for the purposes
100 // of the |in_use_cache_|. The key is generated as follows:
101 // ╔══════════════════════╤═══════════╤═══════════╗
102 // ║ image_id │ mip_level │ quality ║
103 // ╚════════32═bits═══════╧══16═bits══╧══16═bits══╝
104 uint64_t GenerateInUseCacheKey(const DrawImage& draw_image) {
105 static_assert(
106 kLast_SkFilterQuality <= std::numeric_limits<uint16_t>::max(),
107 "InUseCacheKey depends on SkFilterQuality fitting in a uint16_t.");
108
109 SkFilterQuality filter_quality =
110 CalculateUploadScaleFilterQuality(draw_image);
111 DCHECK_LE(filter_quality, kLast_SkFilterQuality);
112
113 // An image has at most log_2(max(width, height)) mip levels, so given our
114 // usage of 32-bit sizes for images, key.mip_level is at most 31.
115 int32_t mip_level = CalculateUploadScaleMipLevel(draw_image);
116 DCHECK_LT(mip_level, 32);
117
118 return (static_cast<uint64_t>(draw_image.image()->uniqueID()) << 32) |
119 (mip_level << 16) | filter_quality;
120 }
121
122 } // namespace 59 } // namespace
123 60
124 GpuImageDecodeController::InUseCacheEntry::InUseCacheEntry(
125 scoped_refptr<ImageData> image_data)
126 : image_data(std::move(image_data)) {}
127 GpuImageDecodeController::InUseCacheEntry::InUseCacheEntry(
128 const InUseCacheEntry&) = default;
129 GpuImageDecodeController::InUseCacheEntry::InUseCacheEntry(InUseCacheEntry&&) =
130 default;
131 GpuImageDecodeController::InUseCacheEntry::~InUseCacheEntry() = default;
132
133 // Task which decodes an image and stores the result in discardable memory. 61 // Task which decodes an image and stores the result in discardable memory.
134 // This task does not use GPU resources and can be run on any thread. 62 // This task does not use GPU resources and can be run on any thread.
135 class ImageDecodeTaskImpl : public TileTask { 63 class ImageDecodeTaskImpl : public TileTask {
136 public: 64 public:
137 ImageDecodeTaskImpl(GpuImageDecodeController* controller, 65 ImageDecodeTaskImpl(GpuImageDecodeController* controller,
138 const DrawImage& draw_image, 66 const DrawImage& draw_image,
139 const ImageDecodeController::TracingInfo& tracing_info) 67 const ImageDecodeController::TracingInfo& tracing_info)
140 : TileTask(true), 68 : TileTask(true),
141 controller_(controller), 69 controller_(controller),
142 image_(draw_image), 70 image_(draw_image),
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 170
243 void GpuImageDecodeController::DecodedImageData::ResetData() { 171 void GpuImageDecodeController::DecodedImageData::ResetData() {
244 DCHECK(!is_locked_); 172 DCHECK(!is_locked_);
245 if (data_) 173 if (data_)
246 ReportUsageStats(); 174 ReportUsageStats();
247 data_ = nullptr; 175 data_ = nullptr;
248 usage_stats_ = UsageStats(); 176 usage_stats_ = UsageStats();
249 } 177 }
250 178
251 void GpuImageDecodeController::DecodedImageData::ReportUsageStats() const { 179 void GpuImageDecodeController::DecodedImageData::ReportUsageStats() const {
252 // lock_count used result state 180 // lock_count | used | result state
253 // ═══════════╪═══════╪══════════════════ 181 // ===========+=======+==================
254 // 1 false WASTED_ONCE 182 // 1 | false | WASTED_ONCE
255 // 1 true USED_ONCE 183 // 1 | true | USED_ONCE
256 // >1 false WASTED_RELOCKED 184 // >1 | false | WASTED_RELOCKED
257 // >1 true USED_RELOCKED 185 // >1 | true | USED_RELOCKED
258 // Note that it's important not to reorder the following enums, since the 186 // Note that it's important not to reorder the following enums, since the
259 // numerical values are used in the histogram code. 187 // numerical values are used in the histogram code.
260 enum State : int { 188 enum State : int {
261 DECODED_IMAGE_STATE_WASTED_ONCE, 189 DECODED_IMAGE_STATE_WASTED_ONCE,
262 DECODED_IMAGE_STATE_USED_ONCE, 190 DECODED_IMAGE_STATE_USED_ONCE,
263 DECODED_IMAGE_STATE_WASTED_RELOCKED, 191 DECODED_IMAGE_STATE_WASTED_RELOCKED,
264 DECODED_IMAGE_STATE_USED_RELOCKED, 192 DECODED_IMAGE_STATE_USED_RELOCKED,
265 DECODED_IMAGE_STATE_COUNT 193 DECODED_IMAGE_STATE_COUNT
266 } state = DECODED_IMAGE_STATE_WASTED_ONCE; 194 } state = DECODED_IMAGE_STATE_WASTED_ONCE;
267 195
(...skipping 30 matching lines...) Expand all
298 image_ = std::move(image); 226 image_ = std::move(image);
299 } 227 }
300 228
301 void GpuImageDecodeController::UploadedImageData::ReportUsageStats() const { 229 void GpuImageDecodeController::UploadedImageData::ReportUsageStats() const {
302 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.Used", 230 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.Used",
303 usage_stats_.used); 231 usage_stats_.used);
304 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.FirstRefWasted", 232 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.FirstRefWasted",
305 usage_stats_.first_ref_wasted); 233 usage_stats_.first_ref_wasted);
306 } 234 }
307 235
308 GpuImageDecodeController::ImageData::ImageData( 236 GpuImageDecodeController::ImageData::ImageData(DecodedDataMode mode,
309 DecodedDataMode mode, 237 size_t size)
310 size_t size, 238 : mode(mode), size(size) {}
311 int upload_scale_mip_level,
312 SkFilterQuality upload_scale_filter_quality)
313 : mode(mode),
314 size(size),
315 upload_scale_mip_level(upload_scale_mip_level),
316 upload_scale_filter_quality(upload_scale_filter_quality) {}
317 239
318 GpuImageDecodeController::ImageData::~ImageData() { 240 GpuImageDecodeController::ImageData::~ImageData() = default;
319 // We should never delete ImageData while it is in use or before it has been
320 // cleaned up.
321 DCHECK_EQ(0u, upload.ref_count);
322 DCHECK_EQ(0u, decode.ref_count);
323 DCHECK_EQ(false, decode.is_locked());
324 // This should always be cleaned up before deleting the image, as it needs to
325 // be freed with the GL context lock held.
326 DCHECK(!upload.image());
327 }
328 241
329 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, 242 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context,
330 ResourceFormat decode_format, 243 ResourceFormat decode_format,
331 size_t max_gpu_image_bytes) 244 size_t max_gpu_image_bytes)
332 : format_(decode_format), 245 : format_(decode_format),
333 context_(context), 246 context_(context),
334 persistent_cache_(PersistentCache::NO_AUTO_EVICT), 247 image_data_(ImageDataMRUCache::NO_AUTO_EVICT),
335 cached_items_limit_(kMaxDiscardableItems), 248 cached_items_limit_(kMaxDiscardableItems),
336 cached_bytes_limit_(max_gpu_image_bytes), 249 cached_bytes_limit_(max_gpu_image_bytes),
337 bytes_used_(0), 250 bytes_used_(0),
338 max_gpu_image_bytes_(max_gpu_image_bytes) { 251 max_gpu_image_bytes_(max_gpu_image_bytes) {
339 // Acquire the context_lock so that we can safely retrieve the 252 // Acquire the context_lock so that we can safely retrieve the
340 // GrContextThreadSafeProxy. This proxy can then be used with no lock held. 253 // GrContextThreadSafeProxy. This proxy can then be used with no lock held.
341 { 254 {
342 ContextProvider::ScopedContextLock context_lock(context_); 255 ContextProvider::ScopedContextLock context_lock(context_);
343 context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>( 256 context_threadsafe_proxy_ = sk_sp<GrContextThreadSafeProxy>(
344 context->GrContext()->threadSafeProxy()); 257 context->GrContext()->threadSafeProxy());
(...skipping 22 matching lines...) Expand all
367 const DrawImage& draw_image, 280 const DrawImage& draw_image,
368 const TracingInfo& tracing_info, 281 const TracingInfo& tracing_info,
369 scoped_refptr<TileTask>* task) { 282 scoped_refptr<TileTask>* task) {
370 if (SkipImage(draw_image)) { 283 if (SkipImage(draw_image)) {
371 *task = nullptr; 284 *task = nullptr;
372 return false; 285 return false;
373 } 286 }
374 287
375 base::AutoLock lock(lock_); 288 base::AutoLock lock(lock_);
376 const auto image_id = draw_image.image()->uniqueID(); 289 const auto image_id = draw_image.image()->uniqueID();
377 ImageData* image_data = GetImageDataForDrawImage(draw_image); 290
378 scoped_refptr<ImageData> new_data; 291 auto found = image_data_.Get(image_id);
379 if (!image_data) { 292 if (found != image_data_.end()) {
380 // We need an ImageData, create one now. 293 ImageData* image_data = found->second.get();
381 new_data = CreateImageData(draw_image); 294 if (image_data->is_at_raster) {
382 image_data = new_data.get(); 295 // Image is at-raster, just return, this usage will be at-raster as well.
383 } else if (image_data->is_at_raster) { 296 *task = nullptr;
384 // Image is at-raster, just return, this usage will be at-raster as well. 297 return false;
385 *task = nullptr; 298 }
386 return false; 299
387 } else if (image_data->decode.decode_failure) { 300 if (image_data->decode.decode_failure) {
388 // We have already tried and failed to decode this image, so just return. 301 // We have already tried and failed to decode this image, so just return.
389 *task = nullptr; 302 *task = nullptr;
390 return false; 303 return false;
391 } else if (image_data->upload.image()) { 304 }
392 // The image is already uploaded, ref and return. 305
393 RefImage(draw_image); 306 if (image_data->upload.image()) {
394 *task = nullptr; 307 // The image is already uploaded, ref and return.
395 return true; 308 RefImage(draw_image);
396 } else if (image_data->upload.task) { 309 *task = nullptr;
310 return true;
311 }
312 }
313
314 // We didn't have a pre-uploaded image, so we need an upload task. Try to find
315 // an existing one.
316 scoped_refptr<TileTask>& existing_task =
317 pending_image_upload_tasks_[image_id];
318 if (existing_task) {
397 // We had an existing upload task, ref the image and return the task. 319 // We had an existing upload task, ref the image and return the task.
398 RefImage(draw_image); 320 RefImage(draw_image);
399 *task = image_data->upload.task; 321 *task = existing_task;
400 return true; 322 return true;
401 } 323 }
402 324
325 // We will be creating a new upload task. If necessary, create a placeholder
326 // ImageData to hold the result.
327 std::unique_ptr<ImageData> new_data;
328 ImageData* data;
329 if (found == image_data_.end()) {
330 new_data = CreateImageData(draw_image);
331 data = new_data.get();
332 } else {
333 data = found->second.get();
334 }
335
403 // Ensure that the image we're about to decode/upload will fit in memory. 336 // Ensure that the image we're about to decode/upload will fit in memory.
404 if (!EnsureCapacity(image_data->size)) { 337 if (!EnsureCapacity(data->size)) {
405 // Image will not fit, do an at-raster decode. 338 // Image will not fit, do an at-raster decode.
406 *task = nullptr; 339 *task = nullptr;
407 return false; 340 return false;
408 } 341 }
409 342
410 // If we had to create new image data, add it to our map now that we know it 343 // If we had to create new image data, add it to our map now that we know it
411 // will fit. 344 // will fit.
412 if (new_data) 345 if (new_data)
413 persistent_cache_.Put(image_id, std::move(new_data)); 346 found = image_data_.Put(image_id, std::move(new_data));
414 347
415 // Ref image and create a upload and decode tasks. We will release this ref 348 // Ref image and create a upload and decode tasks. We will release this ref
416 // in UploadTaskCompleted. 349 // in UploadTaskCompleted.
417 RefImage(draw_image); 350 RefImage(draw_image);
418 *task = make_scoped_refptr(new ImageUploadTaskImpl( 351 existing_task = make_scoped_refptr(new ImageUploadTaskImpl(
419 this, draw_image, GetImageDecodeTaskAndRef(draw_image, tracing_info), 352 this, draw_image, GetImageDecodeTaskAndRef(draw_image, tracing_info),
420 tracing_info)); 353 tracing_info));
421 image_data->upload.task = *task;
422 354
423 // Ref the image again - this ref is owned by the caller, and it is their 355 // Ref the image again - this ref is owned by the caller, and it is their
424 // responsibility to release it by calling UnrefImage. 356 // responsibility to release it by calling UnrefImage.
425 RefImage(draw_image); 357 RefImage(draw_image);
358 *task = existing_task;
426 return true; 359 return true;
427 } 360 }
428 361
429 void GpuImageDecodeController::UnrefImage(const DrawImage& draw_image) { 362 void GpuImageDecodeController::UnrefImage(const DrawImage& draw_image) {
430 base::AutoLock lock(lock_); 363 base::AutoLock lock(lock_);
431 UnrefImageInternal(draw_image); 364 UnrefImageInternal(draw_image);
432 } 365 }
433 366
434 DecodedDrawImage GpuImageDecodeController::GetDecodedImageForDraw( 367 DecodedDrawImage GpuImageDecodeController::GetDecodedImageForDraw(
435 const DrawImage& draw_image) { 368 const DrawImage& draw_image) {
436 TRACE_EVENT0("cc", "GpuImageDecodeController::GetDecodedImageForDraw");
437
438 // We are being called during raster. The context lock must already be 369 // We are being called during raster. The context lock must already be
439 // acquired by the caller. 370 // acquired by the caller.
440 context_->GetLock()->AssertAcquired(); 371 context_->GetLock()->AssertAcquired();
441 372
442 if (SkipImage(draw_image)) 373 if (SkipImage(draw_image))
443 return DecodedDrawImage(nullptr, draw_image.filter_quality()); 374 return DecodedDrawImage(nullptr, draw_image.filter_quality());
444 375
376 TRACE_EVENT0("cc", "GpuImageDecodeController::GetDecodedImageForDraw");
377
445 base::AutoLock lock(lock_); 378 base::AutoLock lock(lock_);
446 ImageData* image_data = GetImageDataForDrawImage(draw_image); 379 const uint32_t unique_id = draw_image.image()->uniqueID();
447 if (!image_data) { 380 auto found = image_data_.Peek(unique_id);
381 if (found == image_data_.end()) {
448 // We didn't find the image, create a new entry. 382 // We didn't find the image, create a new entry.
449 auto data = CreateImageData(draw_image); 383 auto data = CreateImageData(draw_image);
450 image_data = data.get(); 384 found = image_data_.Put(unique_id, std::move(data));
451 persistent_cache_.Put(draw_image.image()->uniqueID(), std::move(data));
452 } 385 }
453 386
387 ImageData* image_data = found->second.get();
388
454 if (!image_data->upload.budgeted) { 389 if (!image_data->upload.budgeted) {
455 // If image data is not budgeted by this point, it is at-raster. 390 // If image data is not budgeted by this point, it is at-raster.
456 image_data->is_at_raster = true; 391 image_data->is_at_raster = true;
457 } 392 }
458 393
459 // Ref the image and decode so that they stay alive while we are 394 // Ref the image and decode so that they stay alive while we are
460 // decoding/uploading. 395 // decoding/uploading.
461 RefImage(draw_image); 396 RefImage(draw_image);
462 RefImageDecode(draw_image); 397 RefImageDecode(draw_image);
463 398
464 // We may or may not need to decode and upload the image we've found, the 399 // We may or may not need to decode and upload the image we've found, the
465 // following functions early-out to if we already decoded. 400 // following functions early-out to if we already decoded.
466 DecodeImageIfNecessary(draw_image, image_data); 401 DecodeImageIfNecessary(draw_image, image_data);
467 UploadImageIfNecessary(draw_image, image_data); 402 UploadImageIfNecessary(draw_image, image_data);
468 // Unref the image decode, but not the image. The image ref will be released 403 // Unref the image decode, but not the image. The image ref will be released
469 // in DrawWithImageFinished. 404 // in DrawWithImageFinished.
470 UnrefImageDecode(draw_image); 405 UnrefImageDecode(draw_image);
471 406
472 sk_sp<SkImage> image = image_data->upload.image(); 407 sk_sp<SkImage> image = image_data->upload.image();
473 image_data->upload.mark_used(); 408 image_data->upload.mark_used();
474 DCHECK(image || image_data->decode.decode_failure); 409 DCHECK(image || image_data->decode.decode_failure);
475 410
476 SkSize scale_factor = CalculateScaleFactorForMipLevel( 411 DecodedDrawImage decoded_draw_image(std::move(image),
477 draw_image, image_data->upload_scale_mip_level);
478 DecodedDrawImage decoded_draw_image(std::move(image), SkSize(), scale_factor,
479 draw_image.filter_quality()); 412 draw_image.filter_quality());
480 decoded_draw_image.set_at_raster_decode(image_data->is_at_raster); 413 decoded_draw_image.set_at_raster_decode(image_data->is_at_raster);
481 return decoded_draw_image; 414 return decoded_draw_image;
482 } 415 }
483 416
484 void GpuImageDecodeController::DrawWithImageFinished( 417 void GpuImageDecodeController::DrawWithImageFinished(
485 const DrawImage& draw_image, 418 const DrawImage& draw_image,
486 const DecodedDrawImage& decoded_draw_image) { 419 const DecodedDrawImage& decoded_draw_image) {
487 TRACE_EVENT0("cc", "GpuImageDecodeController::DrawWithImageFinished");
488
489 // We are being called during raster. The context lock must already be 420 // We are being called during raster. The context lock must already be
490 // acquired by the caller. 421 // acquired by the caller.
491 context_->GetLock()->AssertAcquired(); 422 context_->GetLock()->AssertAcquired();
492 423
493 if (SkipImage(draw_image)) 424 if (SkipImage(draw_image))
494 return; 425 return;
495 426
496 base::AutoLock lock(lock_); 427 base::AutoLock lock(lock_);
497 UnrefImageInternal(draw_image); 428 UnrefImageInternal(draw_image);
498 429
(...skipping 23 matching lines...) Expand all
522 DeletePendingImages(); 453 DeletePendingImages();
523 } else { 454 } else {
524 base::AutoLock lock(lock_); 455 base::AutoLock lock(lock_);
525 cached_bytes_limit_ = max_gpu_image_bytes_; 456 cached_bytes_limit_ = max_gpu_image_bytes_;
526 } 457 }
527 } 458 }
528 459
529 bool GpuImageDecodeController::OnMemoryDump( 460 bool GpuImageDecodeController::OnMemoryDump(
530 const base::trace_event::MemoryDumpArgs& args, 461 const base::trace_event::MemoryDumpArgs& args,
531 base::trace_event::ProcessMemoryDump* pmd) { 462 base::trace_event::ProcessMemoryDump* pmd) {
532 for (const auto& image_pair : persistent_cache_) { 463 for (const auto& image_pair : image_data_) {
533 const ImageData* image_data = image_pair.second.get(); 464 const ImageData* image_data = image_pair.second.get();
534 const uint32_t image_id = image_pair.first; 465 const uint32_t image_id = image_pair.first;
535 466
536 // If we have discardable decoded data, dump this here. 467 // If we have discardable decoded data, dump this here.
537 if (image_data->decode.data()) { 468 if (image_data->decode.data()) {
538 std::string discardable_dump_name = base::StringPrintf( 469 std::string discardable_dump_name = base::StringPrintf(
539 "cc/image_memory/controller_0x%" PRIXPTR "/discardable/image_%d", 470 "cc/image_memory/controller_0x%" PRIXPTR "/discardable/image_%d",
540 reinterpret_cast<uintptr_t>(this), image_id); 471 reinterpret_cast<uintptr_t>(this), image_id);
541 base::trace_event::MemoryAllocatorDump* dump = 472 base::trace_event::MemoryAllocatorDump* dump =
542 image_data->decode.data()->CreateMemoryAllocatorDump( 473 image_data->decode.data()->CreateMemoryAllocatorDump(
543 discardable_dump_name.c_str(), pmd); 474 discardable_dump_name.c_str(), pmd);
475
544 // If our image is locked, dump the "locked_size" as an additional column. 476 // If our image is locked, dump the "locked_size" as an additional column.
545 // This lets us see the amount of discardable which is contributing to 477 // This lets us see the amount of discardable which is contributing to
546 // memory pressure. 478 // memory pressure.
547 if (image_data->decode.is_locked()) { 479 if (image_data->decode.is_locked()) {
548 dump->AddScalar("locked_size", 480 dump->AddScalar("locked_size",
549 base::trace_event::MemoryAllocatorDump::kUnitsBytes, 481 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
550 image_data->size); 482 image_data->size);
551 } 483 }
552 } 484 }
553 485
(...skipping 27 matching lines...) Expand all
581 pmd->CreateSharedGlobalAllocatorDump(guid); 513 pmd->CreateSharedGlobalAllocatorDump(guid);
582 pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); 514 pmd->AddOwnershipEdge(dump->guid(), guid, kImportance);
583 } 515 }
584 } 516 }
585 517
586 return true; 518 return true;
587 } 519 }
588 520
589 void GpuImageDecodeController::DecodeImage(const DrawImage& draw_image) { 521 void GpuImageDecodeController::DecodeImage(const DrawImage& draw_image) {
590 base::AutoLock lock(lock_); 522 base::AutoLock lock(lock_);
591 ImageData* image_data = GetImageDataForDrawImage(draw_image); 523 auto found = image_data_.Peek(draw_image.image()->uniqueID());
592 DCHECK(image_data); 524 DCHECK(found != image_data_.end());
593 DCHECK(!image_data->is_at_raster); 525 DCHECK(!found->second->is_at_raster);
594 DecodeImageIfNecessary(draw_image, image_data); 526 DecodeImageIfNecessary(draw_image, found->second.get());
595 } 527 }
596 528
597 void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) { 529 void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) {
598 ContextProvider::ScopedContextLock context_lock(context_); 530 ContextProvider::ScopedContextLock context_lock(context_);
599 base::AutoLock lock(lock_); 531 base::AutoLock lock(lock_);
600 ImageData* image_data = GetImageDataForDrawImage(draw_image); 532 auto found = image_data_.Peek(draw_image.image()->uniqueID());
601 DCHECK(image_data); 533 DCHECK(found != image_data_.end());
602 DCHECK(!image_data->is_at_raster); 534 DCHECK(!found->second->is_at_raster);
603 UploadImageIfNecessary(draw_image, image_data); 535 UploadImageIfNecessary(draw_image, found->second.get());
604 } 536 }
605 537
606 void GpuImageDecodeController::OnImageDecodeTaskCompleted( 538 void GpuImageDecodeController::OnImageDecodeTaskCompleted(
607 const DrawImage& draw_image) { 539 const DrawImage& draw_image) {
608 base::AutoLock lock(lock_); 540 base::AutoLock lock(lock_);
609 // Decode task is complete, remove our reference to it. 541 // Decode task is complete, remove it from our list of pending tasks.
610 ImageData* image_data = GetImageDataForDrawImage(draw_image); 542 pending_image_decode_tasks_.erase(draw_image.image()->uniqueID());
611 DCHECK(image_data);
612 DCHECK(image_data->decode.task);
613 image_data->decode.task = nullptr;
614 543
615 // While the decode task is active, we keep a ref on the decoded data. 544 // While the decode task is active, we keep a ref on the decoded data.
616 // Release that ref now. 545 // Release that ref now.
617 UnrefImageDecode(draw_image); 546 UnrefImageDecode(draw_image);
618 } 547 }
619 548
620 void GpuImageDecodeController::OnImageUploadTaskCompleted( 549 void GpuImageDecodeController::OnImageUploadTaskCompleted(
621 const DrawImage& draw_image) { 550 const DrawImage& draw_image) {
622 base::AutoLock lock(lock_); 551 base::AutoLock lock(lock_);
623 // Upload task is complete, remove our reference to it. 552 // Upload task is complete, remove it from our list of pending tasks.
624 ImageData* image_data = GetImageDataForDrawImage(draw_image); 553 pending_image_upload_tasks_.erase(draw_image.image()->uniqueID());
625 DCHECK(image_data);
626 DCHECK(image_data->upload.task);
627 image_data->upload.task = nullptr;
628 554
629 // While the upload task is active, we keep a ref on both the image it will be 555 // While the upload task is active, we keep a ref on both the image it will be
630 // populating, as well as the decode it needs to populate it. Release these 556 // populating, as well as the decode it needs to populate it. Release these
631 // refs now. 557 // refs now.
632 UnrefImageDecode(draw_image); 558 UnrefImageDecode(draw_image);
633 UnrefImageInternal(draw_image); 559 UnrefImageInternal(draw_image);
634 } 560 }
635 561
636 // Checks if an existing image decode exists. If not, returns a task to produce 562 // Checks if an existing image decode exists. If not, returns a task to produce
637 // the requested decode. 563 // the requested decode.
638 scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef( 564 scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef(
639 const DrawImage& draw_image, 565 const DrawImage& draw_image,
640 const TracingInfo& tracing_info) { 566 const TracingInfo& tracing_info) {
641 lock_.AssertAcquired(); 567 lock_.AssertAcquired();
642 568
569 const uint32_t image_id = draw_image.image()->uniqueID();
570
643 // This ref is kept alive while an upload task may need this decode. We 571 // This ref is kept alive while an upload task may need this decode. We
644 // release this ref in UploadTaskCompleted. 572 // release this ref in UploadTaskCompleted.
645 RefImageDecode(draw_image); 573 RefImageDecode(draw_image);
646 574
647 ImageData* image_data = GetImageDataForDrawImage(draw_image); 575 auto found = image_data_.Peek(image_id);
648 DCHECK(image_data); 576 if (found != image_data_.end() && found->second->decode.is_locked()) {
649 if (image_data->decode.is_locked()) {
650 // We should never be creating a decode task for an at raster image. 577 // We should never be creating a decode task for an at raster image.
651 DCHECK(!image_data->is_at_raster); 578 DCHECK(!found->second->is_at_raster);
652 // We should never be creating a decode for an already-uploaded image. 579 // We should never be creating a decode for an already-uploaded image.
653 DCHECK(!image_data->upload.image()); 580 DCHECK(!found->second->upload.image());
654 return nullptr; 581 return nullptr;
655 } 582 }
656 583
657 // We didn't have an existing locked image, create a task to lock or decode. 584 // We didn't have an existing locked image, create a task to lock or decode.
658 scoped_refptr<TileTask>& existing_task = image_data->decode.task; 585 scoped_refptr<TileTask>& existing_task =
586 pending_image_decode_tasks_[image_id];
659 if (!existing_task) { 587 if (!existing_task) {
660 // Ref image decode and create a decode task. This ref will be released in 588 // Ref image decode and create a decode task. This ref will be released in
661 // DecodeTaskCompleted. 589 // DecodeTaskCompleted.
662 RefImageDecode(draw_image); 590 RefImageDecode(draw_image);
663 existing_task = make_scoped_refptr( 591 existing_task = make_scoped_refptr(
664 new ImageDecodeTaskImpl(this, draw_image, tracing_info)); 592 new ImageDecodeTaskImpl(this, draw_image, tracing_info));
665 } 593 }
666 return existing_task; 594 return existing_task;
667 } 595 }
668 596
669 void GpuImageDecodeController::RefImageDecode(const DrawImage& draw_image) { 597 void GpuImageDecodeController::RefImageDecode(const DrawImage& draw_image) {
670 lock_.AssertAcquired(); 598 lock_.AssertAcquired();
671 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); 599 auto found = image_data_.Peek(draw_image.image()->uniqueID());
672 DCHECK(found != in_use_cache_.end()); 600 DCHECK(found != image_data_.end());
673 ++found->second.ref_count; 601 ++found->second->decode.ref_count;
674 ++found->second.image_data->decode.ref_count; 602 RefCountChanged(found->second.get());
675 OwnershipChanged(found->second.image_data.get());
676 } 603 }
677 604
678 void GpuImageDecodeController::UnrefImageDecode(const DrawImage& draw_image) { 605 void GpuImageDecodeController::UnrefImageDecode(const DrawImage& draw_image) {
679 lock_.AssertAcquired(); 606 lock_.AssertAcquired();
680 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); 607 auto found = image_data_.Peek(draw_image.image()->uniqueID());
681 DCHECK(found != in_use_cache_.end()); 608 DCHECK(found != image_data_.end());
682 DCHECK_GT(found->second.image_data->decode.ref_count, 0u); 609 DCHECK_GT(found->second->decode.ref_count, 0u);
683 DCHECK_GT(found->second.ref_count, 0u); 610 --found->second->decode.ref_count;
684 --found->second.ref_count; 611 RefCountChanged(found->second.get());
685 --found->second.image_data->decode.ref_count;
686 OwnershipChanged(found->second.image_data.get());
687 if (found->second.ref_count == 0u) {
688 in_use_cache_.erase(found);
689 }
690 } 612 }
691 613
692 void GpuImageDecodeController::RefImage(const DrawImage& draw_image) { 614 void GpuImageDecodeController::RefImage(const DrawImage& draw_image) {
693 lock_.AssertAcquired(); 615 lock_.AssertAcquired();
694 InUseCacheKey key = GenerateInUseCacheKey(draw_image); 616 auto found = image_data_.Peek(draw_image.image()->uniqueID());
695 auto found = in_use_cache_.find(key); 617 DCHECK(found != image_data_.end());
696 618 ++found->second->upload.ref_count;
697 // If no secondary cache entry was found for the given |draw_image|, then 619 RefCountChanged(found->second.get());
698 // the draw_image only exists in the |persistent_cache_|. Create an in-use
699 // cache entry now.
700 if (found == in_use_cache_.end()) {
701 auto found_image = persistent_cache_.Peek(draw_image.image()->uniqueID());
702 DCHECK(found_image != persistent_cache_.end());
703 DCHECK(found_image->second->upload_scale_mip_level <=
704 CalculateUploadScaleMipLevel(draw_image));
705 found = in_use_cache_
706 .insert(InUseCache::value_type(
707 key, InUseCacheEntry(found_image->second)))
708 .first;
709 }
710
711 DCHECK(found != in_use_cache_.end());
712 ++found->second.ref_count;
713 ++found->second.image_data->upload.ref_count;
714 OwnershipChanged(found->second.image_data.get());
715 } 620 }
716 621
717 void GpuImageDecodeController::UnrefImageInternal(const DrawImage& draw_image) { 622 void GpuImageDecodeController::UnrefImageInternal(const DrawImage& draw_image) {
718 lock_.AssertAcquired(); 623 lock_.AssertAcquired();
719 auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); 624 auto found = image_data_.Peek(draw_image.image()->uniqueID());
720 DCHECK(found != in_use_cache_.end()); 625 DCHECK(found != image_data_.end());
721 DCHECK_GT(found->second.image_data->upload.ref_count, 0u); 626 DCHECK_GT(found->second->upload.ref_count, 0u);
722 DCHECK_GT(found->second.ref_count, 0u); 627 --found->second->upload.ref_count;
723 --found->second.ref_count; 628 if (found->second->upload.ref_count == 0)
724 --found->second.image_data->upload.ref_count; 629 found->second->upload.notify_ref_reached_zero();
725 OwnershipChanged(found->second.image_data.get()); 630 RefCountChanged(found->second.get());
726 if (found->second.ref_count == 0u) {
727 in_use_cache_.erase(found);
728 }
729 } 631 }
730 632
731 // Called any time an image or decode ref count changes. Takes care of any 633 // Called any time an image or decode ref count changes. Takes care of any
732 // necessary memory budget book-keeping and cleanup. 634 // necessary memory budget book-keeping and cleanup.
733 void GpuImageDecodeController::OwnershipChanged(ImageData* image_data) { 635 void GpuImageDecodeController::RefCountChanged(ImageData* image_data) {
734 lock_.AssertAcquired(); 636 lock_.AssertAcquired();
735 637
736 bool has_any_refs = 638 bool has_any_refs =
737 image_data->upload.ref_count > 0 || image_data->decode.ref_count > 0; 639 image_data->upload.ref_count > 0 || image_data->decode.ref_count > 0;
738 640
739 // Don't keep around orphaned images.
740 if (image_data->is_orphaned && !has_any_refs) {
741 images_pending_deletion_.push_back(std::move(image_data->upload.image()));
742 image_data->upload.SetImage(nullptr);
743 }
744
745 // Don't keep CPU images if they are unused, these images can be recreated by 641 // Don't keep CPU images if they are unused, these images can be recreated by
746 // re-locking discardable (rather than requiring a full upload like GPU 642 // re-locking discardable (rather than requiring a full upload like GPU
747 // images). 643 // images).
748 if (image_data->mode == DecodedDataMode::CPU && !has_any_refs) { 644 if (image_data->mode == DecodedDataMode::CPU && !has_any_refs) {
749 images_pending_deletion_.push_back(image_data->upload.image()); 645 images_pending_deletion_.push_back(image_data->upload.image());
750 image_data->upload.SetImage(nullptr); 646 image_data->upload.SetImage(nullptr);
751 } 647 }
752 648
753 if (image_data->is_at_raster && !has_any_refs) { 649 if (image_data->is_at_raster && !has_any_refs) {
754 // We have an at-raster image which has reached zero refs. If it won't fit 650 // We have an at-raster image which has reached zero refs. If it won't fit
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 lock_.AssertAcquired(); 716 lock_.AssertAcquired();
821 717
822 if (CanFitSize(required_size) && !ExceedsPreferredCount()) 718 if (CanFitSize(required_size) && !ExceedsPreferredCount())
823 return true; 719 return true;
824 720
825 // While we are over memory or preferred item capacity, we iterate through 721 // While we are over memory or preferred item capacity, we iterate through
826 // our set of cached image data in LRU order. For each image, we can do two 722 // our set of cached image data in LRU order. For each image, we can do two
827 // things: 1) We can free the uploaded image, reducing the memory usage of 723 // things: 1) We can free the uploaded image, reducing the memory usage of
828 // the cache and 2) we can remove the entry entirely, reducing the count of 724 // the cache and 2) we can remove the entry entirely, reducing the count of
829 // elements in the cache. 725 // elements in the cache.
830 for (auto it = persistent_cache_.rbegin(); it != persistent_cache_.rend();) { 726 for (auto it = image_data_.rbegin(); it != image_data_.rend();) {
831 if (it->second->decode.ref_count != 0 || 727 if (it->second->decode.ref_count != 0 ||
832 it->second->upload.ref_count != 0) { 728 it->second->upload.ref_count != 0) {
833 ++it; 729 ++it;
834 continue; 730 continue;
835 } 731 }
836 732
837 // Current entry has no refs. Ensure it is not locked. 733 // Current entry has no refs. Ensure it is not locked.
838 DCHECK(!it->second->decode.is_locked()); 734 DCHECK(!it->second->decode.is_locked());
839 735
840 // If an image without refs is budgeted, it must have an associated image 736 // If an image without refs is budgeted, it must have an associated image
841 // upload. 737 // upload.
842 DCHECK(!it->second->upload.budgeted || it->second->upload.image()); 738 DCHECK(!it->second->upload.budgeted || it->second->upload.image());
843 739
844 // Free the uploaded image if possible. 740 // Free the uploaded image if possible.
845 if (it->second->upload.image()) { 741 if (it->second->upload.image()) {
846 DCHECK(it->second->upload.budgeted); 742 DCHECK(it->second->upload.budgeted);
847 DCHECK_GE(bytes_used_, it->second->size); 743 DCHECK_GE(bytes_used_, it->second->size);
848 bytes_used_ -= it->second->size; 744 bytes_used_ -= it->second->size;
849 images_pending_deletion_.push_back(it->second->upload.image()); 745 images_pending_deletion_.push_back(it->second->upload.image());
850 it->second->upload.SetImage(nullptr); 746 it->second->upload.SetImage(nullptr);
851 it->second->upload.budgeted = false; 747 it->second->upload.budgeted = false;
852 } 748 }
853 749
854 // Free the entire entry if necessary. 750 // Free the entire entry if necessary.
855 if (ExceedsPreferredCount()) { 751 if (ExceedsPreferredCount()) {
856 it = persistent_cache_.Erase(it); 752 it = image_data_.Erase(it);
857 } else { 753 } else {
858 ++it; 754 ++it;
859 } 755 }
860 756
861 if (CanFitSize(required_size) && !ExceedsPreferredCount()) 757 if (CanFitSize(required_size) && !ExceedsPreferredCount())
862 return true; 758 return true;
863 } 759 }
864 760
865 // Preferred count is only used as a guideline when triming the cache. Allow 761 // Preferred count is only used as a guideline when triming the cache. Allow
866 // new elements to be added as long as we are below our size limit. 762 // new elements to be added as long as we are below our size limit.
867 return CanFitSize(required_size); 763 return CanFitSize(required_size);
868 } 764 }
869 765
870 bool GpuImageDecodeController::CanFitSize(size_t size) const { 766 bool GpuImageDecodeController::CanFitSize(size_t size) const {
871 lock_.AssertAcquired(); 767 lock_.AssertAcquired();
872 768
873 base::CheckedNumeric<uint32_t> new_size(bytes_used_); 769 base::CheckedNumeric<uint32_t> new_size(bytes_used_);
874 new_size += size; 770 new_size += size;
875 return new_size.IsValid() && new_size.ValueOrDie() <= cached_bytes_limit_; 771 return new_size.IsValid() && new_size.ValueOrDie() <= cached_bytes_limit_;
876 } 772 }
877 773
878 bool GpuImageDecodeController::ExceedsPreferredCount() const { 774 bool GpuImageDecodeController::ExceedsPreferredCount() const {
879 lock_.AssertAcquired(); 775 lock_.AssertAcquired();
880 776
881 return persistent_cache_.size() > cached_items_limit_; 777 return image_data_.size() > cached_items_limit_;
882 } 778 }
883 779
884 void GpuImageDecodeController::DecodeImageIfNecessary( 780 void GpuImageDecodeController::DecodeImageIfNecessary(
885 const DrawImage& draw_image, 781 const DrawImage& draw_image,
886 ImageData* image_data) { 782 ImageData* image_data) {
887 lock_.AssertAcquired(); 783 lock_.AssertAcquired();
888 784
889 DCHECK_GT(image_data->decode.ref_count, 0u); 785 DCHECK_GT(image_data->decode.ref_count, 0u);
890 786
891 if (image_data->decode.decode_failure) { 787 if (image_data->decode.decode_failure) {
(...skipping 16 matching lines...) Expand all
908 804
909 image_data->decode.ResetData(); 805 image_data->decode.ResetData();
910 std::unique_ptr<base::DiscardableMemory> backing_memory; 806 std::unique_ptr<base::DiscardableMemory> backing_memory;
911 { 807 {
912 base::AutoUnlock unlock(lock_); 808 base::AutoUnlock unlock(lock_);
913 switch (image_data->mode) { 809 switch (image_data->mode) {
914 case DecodedDataMode::CPU: { 810 case DecodedDataMode::CPU: {
915 backing_memory = 811 backing_memory =
916 base::DiscardableMemoryAllocator::GetInstance() 812 base::DiscardableMemoryAllocator::GetInstance()
917 ->AllocateLockedDiscardableMemory(image_data->size); 813 ->AllocateLockedDiscardableMemory(image_data->size);
918 SkImageInfo image_info = CreateImageInfoForDrawImage( 814 SkImageInfo image_info = CreateImageInfoForDrawImage(draw_image);
919 draw_image, image_data->upload_scale_mip_level); 815 if (!draw_image.image()->readPixels(image_info, backing_memory->data(),
920 // In order to match GPU scaling quality (which uses mip-maps at high 816 image_info.minRowBytes(), 0, 0,
921 // quality), we want to use at most medium filter quality for the 817 SkImage::kDisallow_CachingHint)) {
922 // scale.
923 SkPixmap image_pixmap(image_info, backing_memory->data(),
924 image_info.minRowBytes());
925 // Note that scalePixels falls back to readPixels if the sale is 1x, so
926 // no need to special case that as an optimization.
927 if (!draw_image.image()->scalePixels(
928 image_pixmap, CalculateUploadScaleFilterQuality(draw_image),
929 SkImage::kDisallow_CachingHint)) {
930 backing_memory.reset(); 818 backing_memory.reset();
931 } 819 }
932 break; 820 break;
933 } 821 }
934 case DecodedDataMode::GPU: { 822 case DecodedDataMode::GPU: {
935 backing_memory = 823 backing_memory =
936 base::DiscardableMemoryAllocator::GetInstance() 824 base::DiscardableMemoryAllocator::GetInstance()
937 ->AllocateLockedDiscardableMemory(image_data->size); 825 ->AllocateLockedDiscardableMemory(image_data->size);
938 auto params = 826 auto params = ParamsFromDrawImage(draw_image);
939 ParamsFromDrawImage(draw_image, image_data->upload_scale_mip_level);
940 if (!draw_image.image()->getDeferredTextureImageData( 827 if (!draw_image.image()->getDeferredTextureImageData(
941 *context_threadsafe_proxy_.get(), &params, 1, 828 *context_threadsafe_proxy_.get(), &params, 1,
942 backing_memory->data())) { 829 backing_memory->data())) {
943 backing_memory.reset(); 830 backing_memory.reset();
944 } 831 }
945 break; 832 break;
946 } 833 }
947 } 834 }
948 } 835 }
949 836
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
985 // We are about to upload a new image and are holding the context lock. 872 // We are about to upload a new image and are holding the context lock.
986 // Ensure that any images which have been marked for deletion are actually 873 // Ensure that any images which have been marked for deletion are actually
987 // cleaned up so we don't exceed our memory limit during this upload. 874 // cleaned up so we don't exceed our memory limit during this upload.
988 DeletePendingImages(); 875 DeletePendingImages();
989 876
990 sk_sp<SkImage> uploaded_image; 877 sk_sp<SkImage> uploaded_image;
991 { 878 {
992 base::AutoUnlock unlock(lock_); 879 base::AutoUnlock unlock(lock_);
993 switch (image_data->mode) { 880 switch (image_data->mode) {
994 case DecodedDataMode::CPU: { 881 case DecodedDataMode::CPU: {
995 SkImageInfo image_info = CreateImageInfoForDrawImage( 882 SkImageInfo image_info = CreateImageInfoForDrawImage(draw_image);
996 draw_image, image_data->upload_scale_mip_level);
997 SkPixmap pixmap(image_info, image_data->decode.data()->data(), 883 SkPixmap pixmap(image_info, image_data->decode.data()->data(),
998 image_info.minRowBytes()); 884 image_info.minRowBytes());
999 uploaded_image = 885 uploaded_image =
1000 SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr); 886 SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr);
1001 break; 887 break;
1002 } 888 }
1003 case DecodedDataMode::GPU: { 889 case DecodedDataMode::GPU: {
1004 uploaded_image = SkImage::MakeFromDeferredTextureImageData( 890 uploaded_image = SkImage::MakeFromDeferredTextureImageData(
1005 context_->GrContext(), image_data->decode.data()->data(), 891 context_->GrContext(), image_data->decode.data()->data(),
1006 SkBudgeted::kNo); 892 SkBudgeted::kNo);
1007 break; 893 break;
1008 } 894 }
1009 } 895 }
1010 } 896 }
1011 image_data->decode.mark_used(); 897 image_data->decode.mark_used();
1012 DCHECK(uploaded_image); 898 DCHECK(uploaded_image);
1013 899
1014 // At-raster may have decoded this while we were unlocked. If so, ignore our 900 // At-raster may have decoded this while we were unlocked. If so, ignore our
1015 // result. 901 // result.
1016 if (!image_data->upload.image()) 902 if (!image_data->upload.image())
1017 image_data->upload.SetImage(std::move(uploaded_image)); 903 image_data->upload.SetImage(std::move(uploaded_image));
1018 } 904 }
1019 905
1020 scoped_refptr<GpuImageDecodeController::ImageData> 906 std::unique_ptr<GpuImageDecodeController::ImageData>
1021 GpuImageDecodeController::CreateImageData(const DrawImage& draw_image) { 907 GpuImageDecodeController::CreateImageData(const DrawImage& draw_image) {
1022 lock_.AssertAcquired(); 908 lock_.AssertAcquired();
1023 909
1024 DecodedDataMode mode; 910 DecodedDataMode mode;
1025 int upload_scale_mip_level = CalculateUploadScaleMipLevel(draw_image); 911 SkImageInfo info = CreateImageInfoForDrawImage(draw_image);
1026 SkImage::DeferredTextureImageUsageParams params = 912 SkImage::DeferredTextureImageUsageParams params =
1027 ParamsFromDrawImage(draw_image, upload_scale_mip_level); 913 ParamsFromDrawImage(draw_image);
1028 size_t data_size = draw_image.image()->getDeferredTextureImageData( 914 size_t data_size = draw_image.image()->getDeferredTextureImageData(
1029 *context_threadsafe_proxy_.get(), &params, 1, nullptr); 915 *context_threadsafe_proxy_.get(), &params, 1, nullptr);
1030 916
1031 if (data_size == 0) { 917 if (data_size == 0) {
1032 // Can't upload image, too large or other failure. Try to use SW fallback. 918 // Can't upload image, too large or other failure. Try to use SW fallback.
1033 SkImageInfo image_info = 919 data_size = info.getSafeSize(info.minRowBytes());
1034 CreateImageInfoForDrawImage(draw_image, upload_scale_mip_level);
1035 data_size = image_info.getSafeSize(image_info.minRowBytes());
1036 mode = DecodedDataMode::CPU; 920 mode = DecodedDataMode::CPU;
1037 } else { 921 } else {
1038 mode = DecodedDataMode::GPU; 922 mode = DecodedDataMode::GPU;
1039 } 923 }
1040 924
1041 return make_scoped_refptr( 925 return base::WrapUnique(new ImageData(mode, data_size));
1042 new ImageData(mode, data_size, upload_scale_mip_level,
1043 CalculateUploadScaleFilterQuality(draw_image)));
1044 } 926 }
1045 927
1046 void GpuImageDecodeController::DeletePendingImages() { 928 void GpuImageDecodeController::DeletePendingImages() {
1047 context_->GetLock()->AssertAcquired(); 929 context_->GetLock()->AssertAcquired();
1048 lock_.AssertAcquired(); 930 lock_.AssertAcquired();
1049 images_pending_deletion_.clear(); 931 images_pending_deletion_.clear();
1050 } 932 }
1051 933
1052 SkImageInfo GpuImageDecodeController::CreateImageInfoForDrawImage( 934 SkImageInfo GpuImageDecodeController::CreateImageInfoForDrawImage(
1053 const DrawImage& draw_image, 935 const DrawImage& draw_image) const {
1054 int upload_scale_mip_level) const {
1055 DrawImage scaled_draw_image = draw_image.ApplyScale(
1056 CalculateScaleFactorForMipLevel(draw_image, upload_scale_mip_level));
1057 return SkImageInfo::Make( 936 return SkImageInfo::Make(
1058 scaled_draw_image.image()->width() * scaled_draw_image.scale().width(), 937 draw_image.image()->width(), draw_image.image()->height(),
1059 scaled_draw_image.image()->height() * scaled_draw_image.scale().height(),
1060 ResourceFormatToClosestSkColorType(format_), kPremul_SkAlphaType); 938 ResourceFormatToClosestSkColorType(format_), kPremul_SkAlphaType);
1061 } 939 }
1062 940
1063 // Tries to find an ImageData that can be used to draw the provided
1064 // |draw_image|. First looks for an exact entry in our |in_use_cache_|. If one
1065 // cannot be found, it looks for a compatible entry in our |persistent_cache_|.
1066 GpuImageDecodeController::ImageData*
1067 GpuImageDecodeController::GetImageDataForDrawImage(
1068 const DrawImage& draw_image) {
1069 lock_.AssertAcquired();
1070 auto found_in_use = in_use_cache_.find(GenerateInUseCacheKey(draw_image));
1071 if (found_in_use != in_use_cache_.end())
1072 return found_in_use->second.image_data.get();
1073
1074 auto found_persistent = persistent_cache_.Get(draw_image.image()->uniqueID());
1075 if (found_persistent != persistent_cache_.end()) {
1076 ImageData* image_data = found_persistent->second.get();
1077 if (IsCompatible(image_data, draw_image)) {
1078 return image_data;
1079 } else {
1080 found_persistent->second->is_orphaned = true;
1081 // Call OwnershipChanged before erasing the orphaned task from the
1082 // persistent cache. This ensures that if the orphaned task has 0
1083 // references, it is cleaned up safely before it is deleted.
1084 OwnershipChanged(image_data);
1085 persistent_cache_.Erase(found_persistent);
1086 }
1087 }
1088
1089 return nullptr;
1090 }
1091
1092 // Determines if we can draw the provided |draw_image| using the provided
1093 // |image_data|. This is true if the |image_data| is not scaled, or if it
1094 // is scaled at an equal or larger scale and equal or larger quality to
1095 // the provided |draw_image|.
1096 bool GpuImageDecodeController::IsCompatible(const ImageData* image_data,
1097 const DrawImage& draw_image) const {
1098 bool is_scaled = image_data->upload_scale_mip_level != 0;
1099 bool scale_is_compatible = CalculateUploadScaleMipLevel(draw_image) >=
1100 image_data->upload_scale_mip_level;
1101 bool quality_is_compatible = CalculateUploadScaleFilterQuality(draw_image) <=
1102 image_data->upload_scale_filter_quality;
1103 return !is_scaled || (scale_is_compatible && quality_is_compatible);
1104 }
1105
1106 size_t GpuImageDecodeController::GetDrawImageSizeForTesting(
1107 const DrawImage& image) {
1108 base::AutoLock lock(lock_);
1109 scoped_refptr<ImageData> data = CreateImageData(image);
1110 return data->size;
1111 }
1112
1113 void GpuImageDecodeController::SetImageDecodingFailedForTesting( 941 void GpuImageDecodeController::SetImageDecodingFailedForTesting(
1114 const DrawImage& image) { 942 const DrawImage& image) {
1115 base::AutoLock lock(lock_); 943 base::AutoLock lock(lock_);
1116 auto found = persistent_cache_.Peek(image.image()->uniqueID()); 944 auto found = image_data_.Peek(image.image()->uniqueID());
1117 DCHECK(found != persistent_cache_.end()); 945 DCHECK(found != image_data_.end());
1118 ImageData* image_data = found->second.get(); 946 ImageData* image_data = found->second.get();
1119 image_data->decode.decode_failure = true; 947 image_data->decode.decode_failure = true;
1120 } 948 }
1121 949
1122 bool GpuImageDecodeController::DiscardableIsLockedForTesting( 950 bool GpuImageDecodeController::DiscardableIsLockedForTesting(
1123 const DrawImage& image) { 951 const DrawImage& image) {
1124 base::AutoLock lock(lock_); 952 base::AutoLock lock(lock_);
1125 auto found = persistent_cache_.Peek(image.image()->uniqueID()); 953 auto found = image_data_.Peek(image.image()->uniqueID());
1126 DCHECK(found != persistent_cache_.end()); 954 DCHECK(found != image_data_.end());
1127 ImageData* image_data = found->second.get(); 955 ImageData* image_data = found->second.get();
1128 return image_data->decode.is_locked(); 956 return image_data->decode.is_locked();
1129 } 957 }
1130 958
1131 } // namespace cc 959 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/gpu_image_decode_controller.h ('k') | cc/tiles/gpu_image_decode_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698