| 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 |