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

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

Issue 2042133002: Add display-resolution caching to GPU IDC (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@drt
Patch Set: comments Created 4 years, 6 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 "base/debug/stack_trace.h"
7 #include "base/memory/discardable_memory_allocator.h" 8 #include "base/memory/discardable_memory_allocator.h"
8 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
9 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
10 #include "base/numerics/safe_math.h" 11 #include "base/numerics/safe_math.h"
11 #include "base/strings/stringprintf.h" 12 #include "base/strings/stringprintf.h"
12 #include "base/threading/thread_task_runner_handle.h" 13 #include "base/threading/thread_task_runner_handle.h"
13 #include "cc/debug/devtools_instrumentation.h" 14 #include "cc/debug/devtools_instrumentation.h"
14 #include "cc/output/context_provider.h" 15 #include "cc/output/context_provider.h"
15 #include "cc/raster/tile_task.h" 16 #include "cc/raster/tile_task.h"
16 #include "cc/resources/resource_format_utils.h" 17 #include "cc/resources/resource_format_utils.h"
18 #include "cc/tiles/mipmap_util.h"
17 #include "gpu/command_buffer/client/context_support.h" 19 #include "gpu/command_buffer/client/context_support.h"
18 #include "gpu/command_buffer/client/gles2_interface.h" 20 #include "gpu/command_buffer/client/gles2_interface.h"
19 #include "gpu_image_decode_controller.h" 21 #include "gpu_image_decode_controller.h"
20 #include "skia/ext/texture_handle.h" 22 #include "skia/ext/texture_handle.h"
21 #include "third_party/skia/include/core/SkCanvas.h" 23 #include "third_party/skia/include/core/SkCanvas.h"
22 #include "third_party/skia/include/core/SkRefCnt.h" 24 #include "third_party/skia/include/core/SkRefCnt.h"
23 #include "third_party/skia/include/core/SkSurface.h" 25 #include "third_party/skia/include/core/SkSurface.h"
24 #include "third_party/skia/include/gpu/GrContext.h" 26 #include "third_party/skia/include/gpu/GrContext.h"
25 #include "third_party/skia/include/gpu/GrTexture.h" 27 #include "third_party/skia/include/gpu/GrTexture.h"
26 #include "ui/gfx/skia_util.h" 28 #include "ui/gfx/skia_util.h"
(...skipping 12 matching lines...) Expand all
39 if (std::abs(draw_image.scale().width()) < 41 if (std::abs(draw_image.scale().width()) <
40 std::numeric_limits<float>::epsilon() || 42 std::numeric_limits<float>::epsilon() ||
41 std::abs(draw_image.scale().height()) < 43 std::abs(draw_image.scale().height()) <
42 std::numeric_limits<float>::epsilon()) { 44 std::numeric_limits<float>::epsilon()) {
43 return true; 45 return true;
44 } 46 }
45 return false; 47 return false;
46 } 48 }
47 49
48 SkImage::DeferredTextureImageUsageParams ParamsFromDrawImage( 50 SkImage::DeferredTextureImageUsageParams ParamsFromDrawImage(
49 const DrawImage& draw_image) { 51 const DrawImage& draw_image,
52 int pre_scale_mip_level) {
50 SkImage::DeferredTextureImageUsageParams params; 53 SkImage::DeferredTextureImageUsageParams params;
51 params.fMatrix = draw_image.matrix(); 54 params.fMatrix = draw_image.matrix();
52 params.fQuality = draw_image.filter_quality(); 55 params.fQuality = draw_image.filter_quality();
56 params.fPreScaleMipLevel = pre_scale_mip_level;
53 57
54 return params; 58 return params;
55 } 59 }
56 60
61 // Calculate the mp level to pre-scale the image to before uploading. We use mip
62 // levels rather than exact scales to increase re-use of scaled images.
63 int CalculatePreScaleMipLevel(const DrawImage& draw_image) {
64 gfx::Size base_size(draw_image.image()->width(),
65 draw_image.image()->height());
66 // Ceil our scaled size so that the mip map generated is guaranteed to be
67 // larger.
68 gfx::Size scaled_size = gfx::ScaleToCeiledSize(
69 base_size, draw_image.scale().width(), draw_image.scale().height());
70
71 return MipMapUtil::GetLevelForSize(base_size, scaled_size);
72 }
73
74 SkSize CalculatePreScaleFactor(const DrawImage& draw_image, int mip_level) {
75 gfx::Size base_size(draw_image.image()->width(),
76 draw_image.image()->height());
77 return MipMapUtil::GetScaleAdjustmentForLevel(base_size, mip_level);
78 }
79
57 } // namespace 80 } // namespace
58 81
82 GpuImageDecodeController::ImageDataForDrawImageEntry::
83 ImageDataForDrawImageEntry(const scoped_refptr<ImageData>& image_data)
84 : image_data(image_data) {}
85 GpuImageDecodeController::ImageDataForDrawImageEntry::
86 ImageDataForDrawImageEntry(const ImageDataForDrawImageEntry&) = default;
87 GpuImageDecodeController::ImageDataForDrawImageEntry::
88 ImageDataForDrawImageEntry(ImageDataForDrawImageEntry&&) = default;
89 GpuImageDecodeController::ImageDataForDrawImageEntry::
90 ~ImageDataForDrawImageEntry() = default;
91
59 // Task which decodes an image and stores the result in discardable memory. 92 // Task which decodes an image and stores the result in discardable memory.
60 // This task does not use GPU resources and can be run on any thread. 93 // This task does not use GPU resources and can be run on any thread.
61 class ImageDecodeTaskImpl : public TileTask { 94 class ImageDecodeTaskImpl : public TileTask {
62 public: 95 public:
63 ImageDecodeTaskImpl(GpuImageDecodeController* controller, 96 ImageDecodeTaskImpl(GpuImageDecodeController* controller,
64 const DrawImage& draw_image, 97 const DrawImage& draw_image,
65 const ImageDecodeController::TracingInfo& tracing_info) 98 const ImageDecodeController::TracingInfo& tracing_info)
66 : TileTask(true), 99 : TileTask(true),
67 controller_(controller), 100 controller_(controller),
68 image_(draw_image), 101 image_(draw_image),
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 image_ = std::move(image); 257 image_ = std::move(image);
225 } 258 }
226 259
227 void GpuImageDecodeController::UploadedImageData::ReportUsageStats() const { 260 void GpuImageDecodeController::UploadedImageData::ReportUsageStats() const {
228 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.Used", 261 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.Used",
229 usage_stats_.used); 262 usage_stats_.used);
230 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.FirstRefWasted", 263 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuImageUploadState.FirstRefWasted",
231 usage_stats_.first_ref_wasted); 264 usage_stats_.first_ref_wasted);
232 } 265 }
233 266
234 GpuImageDecodeController::ImageData::ImageData(DecodedDataMode mode, 267 GpuImageDecodeController::ImageData::ImageData(
235 size_t size) 268 DecodedDataMode mode,
236 : mode(mode), size(size) {} 269 size_t size,
270 int pre_scale_mip_level,
271 SkFilterQuality pre_scale_filter_quality)
272 : mode(mode),
273 size(size),
274 pre_scale_mip_level(pre_scale_mip_level),
275 pre_scale_filter_quality(pre_scale_filter_quality) {}
237 276
238 GpuImageDecodeController::ImageData::~ImageData() = default; 277 GpuImageDecodeController::ImageData::~ImageData() {
278 // We should never delete ImageData while it is in use or before it has been
279 // cleaned up.
280 DCHECK_EQ(0u, upload.ref_count);
281 DCHECK_EQ(0u, decode.ref_count);
282 DCHECK_EQ(false, decode.is_locked());
283 // This should always be cleaned up before deleting the image, as it needs to
284 // be freed with the GL context lock held.
285 DCHECK(!upload.image());
286 }
239 287
240 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context, 288 GpuImageDecodeController::GpuImageDecodeController(ContextProvider* context,
241 ResourceFormat decode_format, 289 ResourceFormat decode_format,
242 size_t max_gpu_image_bytes) 290 size_t max_gpu_image_bytes)
243 : format_(decode_format), 291 : format_(decode_format),
244 context_(context), 292 context_(context),
245 image_data_(ImageDataMRUCache::NO_AUTO_EVICT), 293 image_data_(ImageDataMRUCache::NO_AUTO_EVICT),
246 cached_items_limit_(kMaxDiscardableItems), 294 cached_items_limit_(kMaxDiscardableItems),
247 cached_bytes_limit_(max_gpu_image_bytes), 295 cached_bytes_limit_(max_gpu_image_bytes),
248 bytes_used_(0), 296 bytes_used_(0),
(...skipping 29 matching lines...) Expand all
278 const DrawImage& draw_image, 326 const DrawImage& draw_image,
279 const TracingInfo& tracing_info, 327 const TracingInfo& tracing_info,
280 scoped_refptr<TileTask>* task) { 328 scoped_refptr<TileTask>* task) {
281 if (SkipImage(draw_image)) { 329 if (SkipImage(draw_image)) {
282 *task = nullptr; 330 *task = nullptr;
283 return false; 331 return false;
284 } 332 }
285 333
286 base::AutoLock lock(lock_); 334 base::AutoLock lock(lock_);
287 const auto image_id = draw_image.image()->uniqueID(); 335 const auto image_id = draw_image.image()->uniqueID();
288 336 ImageData* image_data = GetImageDataForDrawImage(draw_image);
289 auto found = image_data_.Get(image_id); 337 if (image_data) {
290 if (found != image_data_.end()) {
291 ImageData* image_data = found->second.get();
292 if (image_data->is_at_raster) { 338 if (image_data->is_at_raster) {
293 // Image is at-raster, just return, this usage will be at-raster as well. 339 // Image is at-raster, just return, this usage will be at-raster as well.
294 *task = nullptr; 340 *task = nullptr;
295 return false; 341 return false;
296 } 342 }
297 343
298 if (image_data->decode.decode_failure) { 344 if (image_data->decode.decode_failure) {
299 // We have already tried and failed to decode this image, so just return. 345 // We have already tried and failed to decode this image, so just return.
300 *task = nullptr; 346 *task = nullptr;
301 return false; 347 return false;
302 } 348 }
303 349
304 if (image_data->upload.image()) { 350 if (image_data->upload.image()) {
305 // The image is already uploaded, ref and return. 351 // The image is already uploaded, ref and return.
306 RefImage(draw_image); 352 RefImage(draw_image);
307 *task = nullptr; 353 *task = nullptr;
308 return true; 354 return true;
309 } 355 }
310 }
311 356
312 // We didn't have a pre-uploaded image, so we need an upload task. Try to find 357 // We didn't have a pre-uploaded image, so we need an upload task. Try to
313 // an existing one. 358 // find an existing one.
314 scoped_refptr<TileTask>& existing_task = 359 auto existing_task = pending_image_upload_tasks_.find(
315 pending_image_upload_tasks_[image_id]; 360 GenerateTaskKeyForDrawImage(draw_image));
316 if (existing_task) { 361 if (existing_task != pending_image_upload_tasks_.end()) {
317 // We had an existing upload task, ref the image and return the task. 362 // We had an existing upload task, ref the image and return the task.
318 RefImage(draw_image); 363 RefImage(draw_image);
319 *task = existing_task; 364 *task = existing_task->second;
320 return true; 365 return true;
366 } else {
367 }
321 } 368 }
322 369
323 // We will be creating a new upload task. If necessary, create a placeholder 370 // We will be creating a new upload task. If necessary, create a placeholder
324 // ImageData to hold the result. 371 // ImageData to hold the result.
325 std::unique_ptr<ImageData> new_data; 372 scoped_refptr<ImageData> new_data;
326 ImageData* data; 373 if (!image_data) {
327 if (found == image_data_.end()) {
328 new_data = CreateImageData(draw_image); 374 new_data = CreateImageData(draw_image);
329 data = new_data.get(); 375 image_data = new_data.get();
330 } else {
331 data = found->second.get();
332 } 376 }
333 377
334 // Ensure that the image we're about to decode/upload will fit in memory. 378 // Ensure that the image we're about to decode/upload will fit in memory.
335 if (!EnsureCapacity(data->size)) { 379 if (!EnsureCapacity(image_data->size)) {
336 // Image will not fit, do an at-raster decode. 380 // Image will not fit, do an at-raster decode.
337 *task = nullptr; 381 *task = nullptr;
338 return false; 382 return false;
339 } 383 }
340 384
341 // If we had to create new image data, add it to our map now that we know it 385 // If we had to create new image data, add it to our map now that we know it
342 // will fit. 386 // will fit.
343 if (new_data) 387 if (new_data)
344 found = image_data_.Put(image_id, std::move(new_data)); 388 image_data_.Put(image_id, std::move(new_data));
345 389
346 // Ref image and create a upload and decode tasks. We will release this ref 390 // Ref image and create a upload and decode tasks. We will release this ref
347 // in UploadTaskCompleted. 391 // in UploadTaskCompleted.
348 RefImage(draw_image); 392 RefImage(draw_image);
349 existing_task = make_scoped_refptr(new ImageUploadTaskImpl( 393 *task = make_scoped_refptr(new ImageUploadTaskImpl(
350 this, draw_image, GetImageDecodeTaskAndRef(draw_image, tracing_info), 394 this, draw_image, GetImageDecodeTaskAndRef(draw_image, tracing_info),
351 tracing_info)); 395 tracing_info));
396 pending_image_upload_tasks_.insert(
397 std::make_pair(GenerateTaskKeyForDrawImage(draw_image), *task));
352 398
353 // Ref the image again - this ref is owned by the caller, and it is their 399 // Ref the image again - this ref is owned by the caller, and it is their
354 // responsibility to release it by calling UnrefImage. 400 // responsibility to release it by calling UnrefImage.
355 RefImage(draw_image); 401 RefImage(draw_image);
356 *task = existing_task;
357 return true; 402 return true;
358 } 403 }
359 404
360 void GpuImageDecodeController::UnrefImage(const DrawImage& draw_image) { 405 void GpuImageDecodeController::UnrefImage(const DrawImage& draw_image) {
361 base::AutoLock lock(lock_); 406 base::AutoLock lock(lock_);
362 UnrefImageInternal(draw_image); 407 UnrefImageInternal(draw_image);
363 } 408 }
364 409
365 DecodedDrawImage GpuImageDecodeController::GetDecodedImageForDraw( 410 DecodedDrawImage GpuImageDecodeController::GetDecodedImageForDraw(
366 const DrawImage& draw_image) { 411 const DrawImage& draw_image) {
367 // We are being called during raster. The context lock must already be 412 // We are being called during raster. The context lock must already be
368 // acquired by the caller. 413 // acquired by the caller.
369 context_->GetLock()->AssertAcquired(); 414 context_->GetLock()->AssertAcquired();
370 415
371 if (SkipImage(draw_image)) 416 if (SkipImage(draw_image))
372 return DecodedDrawImage(nullptr, draw_image.filter_quality()); 417 return DecodedDrawImage(nullptr, draw_image.filter_quality());
373 418
374 TRACE_EVENT0("cc", "GpuImageDecodeController::GetDecodedImageForDraw"); 419 TRACE_EVENT0("cc", "GpuImageDecodeController::GetDecodedImageForDraw");
375 420
376 base::AutoLock lock(lock_); 421 base::AutoLock lock(lock_);
377 const uint32_t unique_id = draw_image.image()->uniqueID(); 422 ImageData* image_data = GetImageDataForDrawImage(draw_image);
378 auto found = image_data_.Peek(unique_id); 423 if (!image_data) {
379 if (found == image_data_.end()) {
380 // We didn't find the image, create a new entry. 424 // We didn't find the image, create a new entry.
381 auto data = CreateImageData(draw_image); 425 auto data = CreateImageData(draw_image);
382 found = image_data_.Put(unique_id, std::move(data)); 426 image_data = data.get();
427 image_data_.Put(draw_image.image()->uniqueID(), std::move(data));
383 } 428 }
384 429
385 ImageData* image_data = found->second.get();
386
387 if (!image_data->upload.budgeted) { 430 if (!image_data->upload.budgeted) {
388 // If image data is not budgeted by this point, it is at-raster. 431 // If image data is not budgeted by this point, it is at-raster.
389 image_data->is_at_raster = true; 432 image_data->is_at_raster = true;
390 } 433 }
391 434
392 // Ref the image and decode so that they stay alive while we are 435 // Ref the image and decode so that they stay alive while we are
393 // decoding/uploading. 436 // decoding/uploading.
394 RefImage(draw_image); 437 RefImage(draw_image);
395 RefImageDecode(draw_image); 438 RefImageDecode(draw_image);
396 439
397 // We may or may not need to decode and upload the image we've found, the 440 // We may or may not need to decode and upload the image we've found, the
398 // following functions early-out to if we already decoded. 441 // following functions early-out to if we already decoded.
399 DecodeImageIfNecessary(draw_image, image_data); 442 DecodeImageIfNecessary(draw_image, image_data);
400 UploadImageIfNecessary(draw_image, image_data); 443 UploadImageIfNecessary(draw_image, image_data);
401 // Unref the image decode, but not the image. The image ref will be released 444 // Unref the image decode, but not the image. The image ref will be released
402 // in DrawWithImageFinished. 445 // in DrawWithImageFinished.
403 UnrefImageDecode(draw_image); 446 UnrefImageDecode(draw_image);
404 447
405 sk_sp<SkImage> image = image_data->upload.image(); 448 sk_sp<SkImage> image = image_data->upload.image();
406 image_data->upload.mark_used(); 449 image_data->upload.mark_used();
407 DCHECK(image || image_data->decode.decode_failure); 450 DCHECK(image || image_data->decode.decode_failure);
408 451
409 DecodedDrawImage decoded_draw_image(std::move(image), 452 SkSize scale_factor =
453 CalculatePreScaleFactor(draw_image, image_data->pre_scale_mip_level);
454 DecodedDrawImage decoded_draw_image(std::move(image), SkSize(), scale_factor,
410 draw_image.filter_quality()); 455 draw_image.filter_quality());
411 decoded_draw_image.set_at_raster_decode(image_data->is_at_raster); 456 decoded_draw_image.set_at_raster_decode(image_data->is_at_raster);
412 return decoded_draw_image; 457 return decoded_draw_image;
413 } 458 }
414 459
415 void GpuImageDecodeController::DrawWithImageFinished( 460 void GpuImageDecodeController::DrawWithImageFinished(
416 const DrawImage& draw_image, 461 const DrawImage& draw_image,
417 const DecodedDrawImage& decoded_draw_image) { 462 const DecodedDrawImage& decoded_draw_image) {
418 // We are being called during raster. The context lock must already be 463 // We are being called during raster. The context lock must already be
419 // acquired by the caller. 464 // acquired by the caller.
420 context_->GetLock()->AssertAcquired(); 465 context_->GetLock()->AssertAcquired();
421 466
422 if (SkipImage(draw_image)) 467 if (SkipImage(draw_image))
423 return; 468 return;
424 469
425 base::AutoLock lock(lock_); 470 base::AutoLock lock(lock_);
471 TRACE_EVENT0("cc", "GpuImageDecodeController::DrawWithImageFinished");
426 UnrefImageInternal(draw_image); 472 UnrefImageInternal(draw_image);
427 473
428 // We are mid-draw and holding the context lock, ensure we clean up any 474 // We are mid-draw and holding the context lock, ensure we clean up any
429 // textures (especially at-raster), which may have just been marked for 475 // textures (especially at-raster), which may have just been marked for
430 // deletion by UnrefImage. 476 // deletion by UnrefImage.
431 DeletePendingImages(); 477 DeletePendingImages();
432 } 478 }
433 479
434 void GpuImageDecodeController::ReduceCacheUsage() { 480 void GpuImageDecodeController::ReduceCacheUsage() {
435 base::AutoLock lock(lock_); 481 base::AutoLock lock(lock_);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 pmd->CreateSharedGlobalAllocatorDump(guid); 555 pmd->CreateSharedGlobalAllocatorDump(guid);
510 pmd->AddOwnershipEdge(dump->guid(), guid, kImportance); 556 pmd->AddOwnershipEdge(dump->guid(), guid, kImportance);
511 } 557 }
512 } 558 }
513 559
514 return true; 560 return true;
515 } 561 }
516 562
517 void GpuImageDecodeController::DecodeImage(const DrawImage& draw_image) { 563 void GpuImageDecodeController::DecodeImage(const DrawImage& draw_image) {
518 base::AutoLock lock(lock_); 564 base::AutoLock lock(lock_);
519 auto found = image_data_.Peek(draw_image.image()->uniqueID()); 565 ImageData* image_data = GetImageDataForDrawImage(draw_image);
520 DCHECK(found != image_data_.end()); 566 DCHECK(image_data);
521 DCHECK(!found->second->is_at_raster); 567 DCHECK(!image_data->is_at_raster);
522 DecodeImageIfNecessary(draw_image, found->second.get()); 568 DecodeImageIfNecessary(draw_image, image_data);
523 } 569 }
524 570
525 void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) { 571 void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) {
526 ContextProvider::ScopedContextLock context_lock(context_); 572 ContextProvider::ScopedContextLock context_lock(context_);
527 base::AutoLock lock(lock_); 573 base::AutoLock lock(lock_);
528 auto found = image_data_.Peek(draw_image.image()->uniqueID()); 574 ImageData* image_data = GetImageDataForDrawImage(draw_image);
529 DCHECK(found != image_data_.end()); 575 DCHECK(image_data);
530 DCHECK(!found->second->is_at_raster); 576 DCHECK(!image_data->is_at_raster);
531 UploadImageIfNecessary(draw_image, found->second.get()); 577 UploadImageIfNecessary(draw_image, image_data);
532 } 578 }
533 579
534 void GpuImageDecodeController::OnImageDecodeTaskCompleted( 580 void GpuImageDecodeController::OnImageDecodeTaskCompleted(
535 const DrawImage& draw_image) { 581 const DrawImage& draw_image) {
536 base::AutoLock lock(lock_); 582 base::AutoLock lock(lock_);
537 // Decode task is complete, remove it from our list of pending tasks. 583 // Decode task is complete, remove it from our list of pending tasks.
538 pending_image_decode_tasks_.erase(draw_image.image()->uniqueID()); 584 pending_image_decode_tasks_.erase(GenerateTaskKeyForDrawImage(draw_image));
539 585
540 // While the decode task is active, we keep a ref on the decoded data. 586 // While the decode task is active, we keep a ref on the decoded data.
541 // Release that ref now. 587 // Release that ref now.
542 UnrefImageDecode(draw_image); 588 UnrefImageDecode(draw_image);
543 } 589 }
544 590
545 void GpuImageDecodeController::OnImageUploadTaskCompleted( 591 void GpuImageDecodeController::OnImageUploadTaskCompleted(
546 const DrawImage& draw_image) { 592 const DrawImage& draw_image) {
547 base::AutoLock lock(lock_); 593 base::AutoLock lock(lock_);
548 // Upload task is complete, remove it from our list of pending tasks. 594 // Upload task is complete, remove it from our list of pending tasks.
549 pending_image_upload_tasks_.erase(draw_image.image()->uniqueID()); 595 pending_image_upload_tasks_.erase(GenerateTaskKeyForDrawImage(draw_image));
550 596
551 // While the upload task is active, we keep a ref on both the image it will be 597 // While the upload task is active, we keep a ref on both the image it will be
552 // populating, as well as the decode it needs to populate it. Release these 598 // populating, as well as the decode it needs to populate it. Release these
553 // refs now. 599 // refs now.
554 UnrefImageDecode(draw_image); 600 UnrefImageDecode(draw_image);
555 UnrefImageInternal(draw_image); 601 UnrefImageInternal(draw_image);
556 } 602 }
557 603
558 // Checks if an existing image decode exists. If not, returns a task to produce 604 // Checks if an existing image decode exists. If not, returns a task to produce
559 // the requested decode. 605 // the requested decode.
560 scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef( 606 scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef(
561 const DrawImage& draw_image, 607 const DrawImage& draw_image,
562 const TracingInfo& tracing_info) { 608 const TracingInfo& tracing_info) {
563 lock_.AssertAcquired(); 609 lock_.AssertAcquired();
564 610
565 const uint32_t image_id = draw_image.image()->uniqueID();
566
567 // This ref is kept alive while an upload task may need this decode. We 611 // This ref is kept alive while an upload task may need this decode. We
568 // release this ref in UploadTaskCompleted. 612 // release this ref in UploadTaskCompleted.
569 RefImageDecode(draw_image); 613 RefImageDecode(draw_image);
570 614
571 auto found = image_data_.Peek(image_id); 615 ImageData* image_data = GetImageDataForDrawImage(draw_image);
572 if (found != image_data_.end() && found->second->decode.is_locked()) { 616 if (image_data && image_data->decode.is_locked()) {
573 // We should never be creating a decode task for an at raster image. 617 // We should never be creating a decode task for an at raster image.
574 DCHECK(!found->second->is_at_raster); 618 DCHECK(!image_data->is_at_raster);
575 // We should never be creating a decode for an already-uploaded image. 619 // We should never be creating a decode for an already-uploaded image.
576 DCHECK(!found->second->upload.image()); 620 DCHECK(!image_data->upload.image());
577 return nullptr; 621 return nullptr;
578 } 622 }
579 623
580 // We didn't have an existing locked image, create a task to lock or decode. 624 // We didn't have an existing locked image, create a task to lock or decode.
581 scoped_refptr<TileTask>& existing_task = 625 scoped_refptr<TileTask>& existing_task =
582 pending_image_decode_tasks_[image_id]; 626 pending_image_decode_tasks_[GenerateTaskKeyForDrawImage(draw_image)];
583 if (!existing_task) { 627 if (!existing_task) {
584 // Ref image decode and create a decode task. This ref will be released in 628 // Ref image decode and create a decode task. This ref will be released in
585 // DecodeTaskCompleted. 629 // DecodeTaskCompleted.
586 RefImageDecode(draw_image); 630 RefImageDecode(draw_image);
587 existing_task = make_scoped_refptr( 631 existing_task = make_scoped_refptr(
588 new ImageDecodeTaskImpl(this, draw_image, tracing_info)); 632 new ImageDecodeTaskImpl(this, draw_image, tracing_info));
589 } 633 }
590 return existing_task; 634 return existing_task;
591 } 635 }
592 636
593 void GpuImageDecodeController::RefImageDecode(const DrawImage& draw_image) { 637 void GpuImageDecodeController::RefImageDecode(const DrawImage& draw_image) {
594 lock_.AssertAcquired(); 638 lock_.AssertAcquired();
595 auto found = image_data_.Peek(draw_image.image()->uniqueID()); 639 auto found =
596 DCHECK(found != image_data_.end()); 640 image_data_for_draw_image_.find(GenerateDrawImageKey(draw_image));
597 ++found->second->decode.ref_count; 641 DCHECK(found != image_data_for_draw_image_.end());
598 RefCountChanged(found->second.get()); 642 ++found->second.ref_count;
643 ++found->second.image_data->decode.ref_count;
644 RefCountChanged(found->second.image_data.get());
599 } 645 }
600 646
601 void GpuImageDecodeController::UnrefImageDecode(const DrawImage& draw_image) { 647 void GpuImageDecodeController::UnrefImageDecode(const DrawImage& draw_image) {
602 lock_.AssertAcquired(); 648 lock_.AssertAcquired();
603 auto found = image_data_.Peek(draw_image.image()->uniqueID()); 649 auto found =
604 DCHECK(found != image_data_.end()); 650 image_data_for_draw_image_.find(GenerateDrawImageKey(draw_image));
605 DCHECK_GT(found->second->decode.ref_count, 0u); 651 DCHECK(found != image_data_for_draw_image_.end());
606 --found->second->decode.ref_count; 652 DCHECK_GT(found->second.image_data->decode.ref_count, 0u);
607 RefCountChanged(found->second.get()); 653 DCHECK_GT(found->second.ref_count, 0u);
654 --found->second.ref_count;
655 --found->second.image_data->decode.ref_count;
656 RefCountChanged(found->second.image_data.get());
657 if (found->second.ref_count == 0u) {
658 image_data_for_draw_image_.erase(found);
659 }
608 } 660 }
609 661
610 void GpuImageDecodeController::RefImage(const DrawImage& draw_image) { 662 void GpuImageDecodeController::RefImage(const DrawImage& draw_image) {
611 lock_.AssertAcquired(); 663 lock_.AssertAcquired();
612 auto found = image_data_.Peek(draw_image.image()->uniqueID()); 664 auto found =
613 DCHECK(found != image_data_.end()); 665 image_data_for_draw_image_.find(GenerateDrawImageKey(draw_image));
614 ++found->second->upload.ref_count; 666
615 RefCountChanged(found->second.get()); 667 // If no secondary cache entry was found for the given |draw_image|, then
668 // the draw_image only exists in the primary cache. Create a secondary
669 // cache entry now.
670 if (found == image_data_for_draw_image_.end()) {
671 auto found_image = image_data_.Peek(draw_image.image()->uniqueID());
672 DCHECK(found_image != image_data_.end());
673 DCHECK(found_image->second->pre_scale_mip_level <=
674 CalculatePreScaleMipLevel(draw_image));
675 found = image_data_for_draw_image_
676 .insert(std::make_pair(
677 GenerateDrawImageKey(draw_image),
678 ImageDataForDrawImageEntry(found_image->second)))
679 .first;
680 }
681
682 DCHECK(found != image_data_for_draw_image_.end());
683 ++found->second.ref_count;
684 ++found->second.image_data->upload.ref_count;
685 RefCountChanged(found->second.image_data.get());
616 } 686 }
617 687
618 void GpuImageDecodeController::UnrefImageInternal(const DrawImage& draw_image) { 688 void GpuImageDecodeController::UnrefImageInternal(const DrawImage& draw_image) {
619 lock_.AssertAcquired(); 689 lock_.AssertAcquired();
620 auto found = image_data_.Peek(draw_image.image()->uniqueID()); 690 auto found =
621 DCHECK(found != image_data_.end()); 691 image_data_for_draw_image_.find(GenerateDrawImageKey(draw_image));
622 DCHECK_GT(found->second->upload.ref_count, 0u); 692 DCHECK(found != image_data_for_draw_image_.end());
623 --found->second->upload.ref_count; 693 DCHECK_GT(found->second.image_data->upload.ref_count, 0u);
624 if (found->second->upload.ref_count == 0) 694 DCHECK_GT(found->second.ref_count, 0u);
625 found->second->upload.notify_ref_reached_zero(); 695 --found->second.ref_count;
626 RefCountChanged(found->second.get()); 696 --found->second.image_data->upload.ref_count;
697 RefCountChanged(found->second.image_data.get());
698 if (found->second.ref_count == 0u) {
699 image_data_for_draw_image_.erase(found);
700 }
627 } 701 }
628 702
629 // Called any time an image or decode ref count changes. Takes care of any 703 // Called any time an image or decode ref count changes. Takes care of any
630 // necessary memory budget book-keeping and cleanup. 704 // necessary memory budget book-keeping and cleanup.
631 void GpuImageDecodeController::RefCountChanged(ImageData* image_data) { 705 void GpuImageDecodeController::RefCountChanged(ImageData* image_data) {
632 lock_.AssertAcquired(); 706 lock_.AssertAcquired();
633 707
634 bool has_any_refs = 708 bool has_any_refs =
635 image_data->upload.ref_count > 0 || image_data->decode.ref_count > 0; 709 image_data->upload.ref_count > 0 || image_data->decode.ref_count > 0;
636 710
711 // Don't keep around orphaned images.
712 if (image_data->is_orphaned && !has_any_refs) {
713 images_pending_deletion_.push_back(std::move(image_data->upload.image()));
714 image_data->upload.SetImage(nullptr);
715 }
716
637 // Don't keep CPU images if they are unused, these images can be recreated by 717 // Don't keep CPU images if they are unused, these images can be recreated by
638 // re-locking discardable (rather than requiring a full upload like GPU 718 // re-locking discardable (rather than requiring a full upload like GPU
639 // images). 719 // images).
640 if (image_data->mode == DecodedDataMode::CPU && !has_any_refs) { 720 if (image_data->mode == DecodedDataMode::CPU && !has_any_refs) {
641 images_pending_deletion_.push_back(image_data->upload.image()); 721 images_pending_deletion_.push_back(image_data->upload.image());
642 image_data->upload.SetImage(nullptr); 722 image_data->upload.SetImage(nullptr);
643 } 723 }
644 724
645 if (image_data->is_at_raster && !has_any_refs) { 725 if (image_data->is_at_raster && !has_any_refs) {
646 // We have an at-raster image which has reached zero refs. If it won't fit 726 // We have an at-raster image which has reached zero refs. If it won't fit
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 880
801 image_data->decode.ResetData(); 881 image_data->decode.ResetData();
802 std::unique_ptr<base::DiscardableMemory> backing_memory; 882 std::unique_ptr<base::DiscardableMemory> backing_memory;
803 { 883 {
804 base::AutoUnlock unlock(lock_); 884 base::AutoUnlock unlock(lock_);
805 switch (image_data->mode) { 885 switch (image_data->mode) {
806 case DecodedDataMode::CPU: { 886 case DecodedDataMode::CPU: {
807 backing_memory = 887 backing_memory =
808 base::DiscardableMemoryAllocator::GetInstance() 888 base::DiscardableMemoryAllocator::GetInstance()
809 ->AllocateLockedDiscardableMemory(image_data->size); 889 ->AllocateLockedDiscardableMemory(image_data->size);
810 SkImageInfo image_info = CreateImageInfoForDrawImage(draw_image); 890 DrawImage scaled_draw_image =
811 if (!draw_image.image()->readPixels(image_info, backing_memory->data(), 891 draw_image.ApplyScale(CalculatePreScaleFactor(
812 image_info.minRowBytes(), 0, 0, 892 draw_image, image_data->pre_scale_mip_level));
813 SkImage::kDisallow_CachingHint)) { 893 SkImageInfo scaled_image_info =
894 CreateImageInfoForDrawImage(scaled_draw_image);
895 // We are doing a software scale of the image before handing off to the
896 // GPU. In order to match GPU scaling quality (which uses mip-maps at
897 // high quality), we want to use at most medium filter quality for the
898 // scale.
899 SkFilterQuality scale_quality =
900 std::max(kMedium_SkFilterQuality, draw_image.filter_quality());
901 SkPixmap full_image_pixmap(scaled_image_info, backing_memory->data(),
902 scaled_image_info.minRowBytes());
903 if (!draw_image.image()->scalePixels(full_image_pixmap, scale_quality,
904 SkImage::kDisallow_CachingHint)) {
814 backing_memory.reset(); 905 backing_memory.reset();
815 } 906 }
816 break; 907 break;
817 } 908 }
818 case DecodedDataMode::GPU: { 909 case DecodedDataMode::GPU: {
819 backing_memory = 910 backing_memory =
820 base::DiscardableMemoryAllocator::GetInstance() 911 base::DiscardableMemoryAllocator::GetInstance()
821 ->AllocateLockedDiscardableMemory(image_data->size); 912 ->AllocateLockedDiscardableMemory(image_data->size);
822 auto params = ParamsFromDrawImage(draw_image); 913 auto params =
914 ParamsFromDrawImage(draw_image, image_data->pre_scale_mip_level);
823 if (!draw_image.image()->getDeferredTextureImageData( 915 if (!draw_image.image()->getDeferredTextureImageData(
824 *context_threadsafe_proxy_.get(), &params, 1, 916 *context_threadsafe_proxy_.get(), &params, 1,
825 backing_memory->data())) { 917 backing_memory->data())) {
826 backing_memory.reset(); 918 backing_memory.reset();
827 } 919 }
828 break; 920 break;
829 } 921 }
830 } 922 }
831 } 923 }
832 924
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
868 // We are about to upload a new image and are holding the context lock. 960 // We are about to upload a new image and are holding the context lock.
869 // Ensure that any images which have been marked for deletion are actually 961 // Ensure that any images which have been marked for deletion are actually
870 // cleaned up so we don't exceed our memory limit during this upload. 962 // cleaned up so we don't exceed our memory limit during this upload.
871 DeletePendingImages(); 963 DeletePendingImages();
872 964
873 sk_sp<SkImage> uploaded_image; 965 sk_sp<SkImage> uploaded_image;
874 { 966 {
875 base::AutoUnlock unlock(lock_); 967 base::AutoUnlock unlock(lock_);
876 switch (image_data->mode) { 968 switch (image_data->mode) {
877 case DecodedDataMode::CPU: { 969 case DecodedDataMode::CPU: {
878 SkImageInfo image_info = CreateImageInfoForDrawImage(draw_image); 970 DrawImage scaled_draw_image =
879 SkPixmap pixmap(image_info, image_data->decode.data()->data(), 971 draw_image.ApplyScale(CalculatePreScaleFactor(
880 image_info.minRowBytes()); 972 draw_image, image_data->pre_scale_mip_level));
973 SkImageInfo scaled_image_info =
974 CreateImageInfoForDrawImage(scaled_draw_image);
975 SkPixmap pixmap(scaled_image_info, image_data->decode.data()->data(),
976 scaled_image_info.minRowBytes());
881 uploaded_image = 977 uploaded_image =
882 SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr); 978 SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr);
883 break; 979 break;
884 } 980 }
885 case DecodedDataMode::GPU: { 981 case DecodedDataMode::GPU: {
886 uploaded_image = SkImage::MakeFromDeferredTextureImageData( 982 uploaded_image = SkImage::MakeFromDeferredTextureImageData(
887 context_->GrContext(), image_data->decode.data()->data(), 983 context_->GrContext(), image_data->decode.data()->data(),
888 SkBudgeted::kNo); 984 SkBudgeted::kNo);
889 break; 985 break;
890 } 986 }
891 } 987 }
892 } 988 }
893 image_data->decode.mark_used(); 989 image_data->decode.mark_used();
894 DCHECK(uploaded_image); 990 DCHECK(uploaded_image);
895 991
896 // At-raster may have decoded this while we were unlocked. If so, ignore our 992 // At-raster may have decoded this while we were unlocked. If so, ignore our
897 // result. 993 // result.
898 if (!image_data->upload.image()) 994 if (!image_data->upload.image())
899 image_data->upload.SetImage(std::move(uploaded_image)); 995 image_data->upload.SetImage(std::move(uploaded_image));
900 } 996 }
901 997
902 std::unique_ptr<GpuImageDecodeController::ImageData> 998 scoped_refptr<GpuImageDecodeController::ImageData>
903 GpuImageDecodeController::CreateImageData(const DrawImage& draw_image) { 999 GpuImageDecodeController::CreateImageData(const DrawImage& draw_image) {
904 lock_.AssertAcquired(); 1000 lock_.AssertAcquired();
905 1001
906 DecodedDataMode mode; 1002 DecodedDataMode mode;
907 SkImageInfo info = CreateImageInfoForDrawImage(draw_image); 1003 int pre_scale_mip_level = CalculatePreScaleMipLevel(draw_image);
908 SkImage::DeferredTextureImageUsageParams params = 1004 SkImage::DeferredTextureImageUsageParams params =
909 ParamsFromDrawImage(draw_image); 1005 ParamsFromDrawImage(draw_image, pre_scale_mip_level);
910 size_t data_size = draw_image.image()->getDeferredTextureImageData( 1006 size_t data_size = draw_image.image()->getDeferredTextureImageData(
911 *context_threadsafe_proxy_.get(), &params, 1, nullptr); 1007 *context_threadsafe_proxy_.get(), &params, 1, nullptr);
912 1008
913 if (data_size == 0) { 1009 if (data_size == 0) {
914 // Can't upload image, too large or other failure. Try to use SW fallback. 1010 // Can't upload image, too large or other failure. Try to use SW fallback.
915 data_size = info.getSafeSize(info.minRowBytes()); 1011 DrawImage scaled_draw_image = draw_image.ApplyScale(
1012 CalculatePreScaleFactor(draw_image, pre_scale_mip_level));
1013 SkImageInfo scaled_image_info =
1014 CreateImageInfoForDrawImage(scaled_draw_image);
1015 data_size = scaled_image_info.getSafeSize(scaled_image_info.minRowBytes());
916 mode = DecodedDataMode::CPU; 1016 mode = DecodedDataMode::CPU;
917 } else { 1017 } else {
918 mode = DecodedDataMode::GPU; 1018 mode = DecodedDataMode::GPU;
919 } 1019 }
920 1020
921 return base::WrapUnique(new ImageData(mode, data_size)); 1021 return make_scoped_refptr(new ImageData(mode, data_size, pre_scale_mip_level,
1022 draw_image.filter_quality()));
922 } 1023 }
923 1024
924 void GpuImageDecodeController::DeletePendingImages() { 1025 void GpuImageDecodeController::DeletePendingImages() {
925 context_->GetLock()->AssertAcquired(); 1026 context_->GetLock()->AssertAcquired();
926 lock_.AssertAcquired(); 1027 lock_.AssertAcquired();
927 images_pending_deletion_.clear(); 1028 images_pending_deletion_.clear();
928 } 1029 }
929 1030
930 SkImageInfo GpuImageDecodeController::CreateImageInfoForDrawImage( 1031 SkImageInfo GpuImageDecodeController::CreateImageInfoForDrawImage(
931 const DrawImage& draw_image) const { 1032 const DrawImage& draw_image) const {
932 return SkImageInfo::Make( 1033 return SkImageInfo::Make(
933 draw_image.image()->width(), draw_image.image()->height(), 1034 draw_image.image()->width() * draw_image.scale().width(),
1035 draw_image.image()->height() * draw_image.scale().height(),
934 ResourceFormatToClosestSkColorType(format_), kPremul_SkAlphaType); 1036 ResourceFormatToClosestSkColorType(format_), kPremul_SkAlphaType);
935 } 1037 }
936 1038
1039 GpuImageDecodeController::ImageData*
1040 GpuImageDecodeController::GetImageDataForDrawImage(
1041 const DrawImage& draw_image) {
1042 lock_.AssertAcquired();
1043 {
1044 auto found =
1045 image_data_for_draw_image_.find(GenerateDrawImageKey(draw_image));
1046 if (found != image_data_for_draw_image_.end()) {
1047 return found->second.image_data.get();
1048 }
1049 }
1050 {
1051 auto found = image_data_.Get(draw_image.image()->uniqueID());
1052 if (found != image_data_.end()) {
1053 if (IsCompatibleWithDrawImage(found->second.get(), draw_image)) {
1054 return found->second.get();
1055 } else {
1056 found->second->is_orphaned = true;
1057 // Call RefCountChanged before erasing the orphaned task to ensure
1058 // that we clean up any SkImage safely.
1059 RefCountChanged(found->second.get());
1060 image_data_.Erase(found);
1061 }
1062 }
1063 }
1064
1065 return nullptr;
1066 }
1067
1068 bool GpuImageDecodeController::IsCompatibleWithDrawImage(
1069 const ImageData* image_data,
1070 const DrawImage& draw_image) const {
1071 bool not_scaled = image_data->pre_scale_mip_level == 0;
1072 bool scale_is_compatible =
1073 CalculatePreScaleMipLevel(draw_image) >=
1074 image_data->pre_scale_mip_level &&
1075 draw_image.filter_quality() <= image_data->pre_scale_filter_quality;
1076 return not_scaled || scale_is_compatible;
1077 }
1078
1079 GpuImageDecodeController::DrawImageKey
1080 GpuImageDecodeController::GenerateDrawImageKey(
1081 const DrawImage& draw_image) const {
1082 DrawImageKey key;
1083 key.image_id = draw_image.image()->uniqueID();
1084 key.mip_level = CalculatePreScaleMipLevel(draw_image);
1085 key.quality = draw_image.filter_quality();
1086 return key;
1087 }
1088
1089 GpuImageDecodeController::DrawImageKey
1090 GpuImageDecodeController::GenerateTaskKeyForDrawImage(
1091 const DrawImage& draw_image) {
1092 lock_.AssertAcquired();
1093 ImageData* image_data = GetImageDataForDrawImage(draw_image);
1094 DDCHECK(image_data);
1095 DrawImageKey key;
1096 key.image_id = draw_image.image()->uniqueID();
1097 key.mip_level = image_data->pre_scale_mip_level;
1098 key.quality = image_data->pre_scale_filter_quality;
1099 return key;
1100 }
1101
1102 size_t GpuImageDecodeController::GetDrawImageSizeForTesting(
1103 const DrawImage& image) {
1104 base::AutoLock lock(lock_);
1105 scoped_refptr<ImageData> data = CreateImageData(image);
1106 return data->size;
1107 }
1108
937 void GpuImageDecodeController::SetImageDecodingFailedForTesting( 1109 void GpuImageDecodeController::SetImageDecodingFailedForTesting(
938 const DrawImage& image) { 1110 const DrawImage& image) {
939 base::AutoLock lock(lock_); 1111 base::AutoLock lock(lock_);
940 auto found = image_data_.Peek(image.image()->uniqueID()); 1112 auto found = image_data_.Peek(image.image()->uniqueID());
941 DCHECK(found != image_data_.end()); 1113 DCHECK(found != image_data_.end());
942 ImageData* image_data = found->second.get(); 1114 ImageData* image_data = found->second.get();
943 image_data->decode.decode_failure = true; 1115 image_data->decode.decode_failure = true;
944 } 1116 }
945 1117
946 bool GpuImageDecodeController::DiscardableIsLockedForTesting( 1118 bool GpuImageDecodeController::DiscardableIsLockedForTesting(
947 const DrawImage& image) { 1119 const DrawImage& image) {
948 base::AutoLock lock(lock_); 1120 base::AutoLock lock(lock_);
949 auto found = image_data_.Peek(image.image()->uniqueID()); 1121 auto found = image_data_.Peek(image.image()->uniqueID());
950 DCHECK(found != image_data_.end()); 1122 DCHECK(found != image_data_.end());
951 ImageData* image_data = found->second.get(); 1123 ImageData* image_data = found->second.get();
952 return image_data->decode.is_locked(); 1124 return image_data->decode.is_locked();
953 } 1125 }
954 1126
955 } // namespace cc 1127 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698