OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(), ¶ms, 1, | 916 *context_threadsafe_proxy_.get(), ¶ms, 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 Loading... |
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(), ¶ms, 1, nullptr); | 1007 *context_threadsafe_proxy_.get(), ¶ms, 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 |
OLD | NEW |