summaryrefslogtreecommitdiffstats
path: root/chromium/cc/tiles/gpu_image_decode_cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/cc/tiles/gpu_image_decode_cache.cc')
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.cc127
1 files changed, 57 insertions, 70 deletions
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc
index 461927bb58f..198f910967d 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache.cc
@@ -30,6 +30,7 @@
#include "gpu/command_buffer/common/sync_token.h"
#include "gpu/config/gpu_finch_features.h"
#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkYUVAIndex.h"
@@ -486,8 +487,7 @@ sk_sp<SkImage> MakeTextureImage(viz::RasterContextProvider* context,
size_t GetUploadedTextureSizeFromSkImage(const sk_sp<SkImage>& plane,
const GrMipMapped mipped) {
- const size_t plane_size = GrContext::ComputeTextureSize(
- plane->colorType(), plane->width(), plane->height(), mipped);
+ const size_t plane_size = GrContext::ComputeImageSize(plane, mipped);
return plane_size;
}
@@ -557,12 +557,15 @@ class GpuImageDecodeTaskImpl : public TileTask {
TRACE_EVENT2("cc", "GpuImageDecodeTaskImpl::RunOnWorkerThread", "mode",
"gpu", "source_prepare_tiles_id",
tracing_info_.prepare_tiles_id);
+
+ const auto* image_metadata = image_.paint_image().GetImageHeaderMetadata();
+ const ImageType image_type =
+ image_metadata ? image_metadata->image_type : ImageType::kInvalid;
devtools_instrumentation::ScopedImageDecodeTask image_decode_task(
&image_.paint_image(),
devtools_instrumentation::ScopedImageDecodeTask::kGpu,
ImageDecodeCache::ToScopedTaskType(tracing_info_.task_type),
- ImageDecodeCache::ToScopedImageType(
- image_.paint_image().GetImageType()));
+ ImageDecodeCache::ToScopedImageType(image_type));
cache_->DecodeImageInTask(image_, tracing_info_.task_type);
}
@@ -589,12 +592,10 @@ class ImageUploadTaskImpl : public TileTask {
ImageUploadTaskImpl(GpuImageDecodeCache* cache,
const DrawImage& draw_image,
scoped_refptr<TileTask> decode_dependency,
- sk_sp<SkData> encoded_data,
const ImageDecodeCache::TracingInfo& tracing_info)
: TileTask(false),
cache_(cache),
image_(draw_image),
- encoded_data_(std::move(encoded_data)),
tracing_info_(tracing_info) {
DCHECK(!SkipImage(draw_image));
// If an image is already decoded and locked, we will not generate a
@@ -610,7 +611,7 @@ class ImageUploadTaskImpl : public TileTask {
void RunOnWorkerThread() override {
TRACE_EVENT2("cc", "ImageUploadTaskImpl::RunOnWorkerThread", "mode", "gpu",
"source_prepare_tiles_id", tracing_info_.prepare_tiles_id);
- cache_->UploadImageInTask(image_, std::move(encoded_data_));
+ cache_->UploadImageInTask(image_);
}
// Overridden from TileTask:
@@ -624,7 +625,6 @@ class ImageUploadTaskImpl : public TileTask {
private:
GpuImageDecodeCache* cache_;
DrawImage image_;
- sk_sp<SkData> encoded_data_;
const ImageDecodeCache::TracingInfo tracing_info_;
};
@@ -961,6 +961,20 @@ GpuImageDecodeCache::GpuImageDecodeCache(
persistent_cache_(PersistentCache::NO_AUTO_EVICT),
max_working_set_bytes_(max_working_set_bytes),
max_working_set_items_(kMaxItemsInWorkingSet) {
+ // Note that to compute |allow_accelerated_jpeg_decodes_| and
+ // |allow_accelerated_webp_decodes_|, the last thing we check is the feature
+ // flag. That's because we want to ensure that we're in OOP-R mode and the
+ // hardware decoder supports the image type so that finch experiments
+ // involving hardware decode acceleration only count users in that
+ // population (both in the 'control' and the 'enabled' groups).
+ allow_accelerated_jpeg_decodes_ =
+ use_transfer_cache &&
+ context_->ContextSupport()->IsJpegDecodeAccelerationSupported() &&
+ base::FeatureList::IsEnabled(features::kVaapiJpegImageDecodeAcceleration);
+ allow_accelerated_webp_decodes_ =
+ use_transfer_cache &&
+ context_->ContextSupport()->IsWebPDecodeAccelerationSupported() &&
+ base::FeatureList::IsEnabled(features::kVaapiWebPImageDecodeAcceleration);
// In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
// Don't register a dump provider in these cases.
if (base::ThreadTaskRunnerHandle::IsSet()) {
@@ -1015,7 +1029,6 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
const InUseCacheKey cache_key = InUseCacheKey::FromDrawImage(draw_image);
ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key);
scoped_refptr<ImageData> new_data;
- sk_sp<SkData> encoded_data;
if (!image_data) {
// We need an ImageData, create one now. Note that hardware decode
// acceleration is allowed only in the DecodeTaskType::kPartOfUploadTask
@@ -1024,8 +1037,7 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
new_data = CreateImageData(
draw_image,
task_type ==
- DecodeTaskType::kPartOfUploadTask /* allow_hardware_decode */,
- &encoded_data);
+ DecodeTaskType::kPartOfUploadTask /* allow_hardware_decode */);
image_data = new_data.get();
} else if (image_data->decode.decode_failure) {
// We have already tried and failed to decode this image, so just return.
@@ -1076,7 +1088,7 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
task = base::MakeRefCounted<ImageUploadTaskImpl>(
this, draw_image,
GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type),
- std::move(encoded_data), tracing_info);
+ tracing_info);
image_data->upload.task = task;
} else {
task = GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type);
@@ -1115,11 +1127,9 @@ DecodedDrawImage GpuImageDecodeCache::GetDecodedImageForDraw(
base::AutoLock lock(lock_);
const InUseCacheKey cache_key = InUseCacheKey::FromDrawImage(draw_image);
ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key);
- sk_sp<SkData> encoded_data;
if (!image_data) {
// We didn't find the image, create a new entry.
- auto data = CreateImageData(draw_image, true /* allow_hardware_decode */,
- &encoded_data);
+ auto data = CreateImageData(draw_image, true /* allow_hardware_decode */);
image_data = data.get();
AddToPersistentCache(draw_image, std::move(data));
}
@@ -1134,7 +1144,7 @@ DecodedDrawImage GpuImageDecodeCache::GetDecodedImageForDraw(
// We may or may not need to decode and upload the image we've found, the
// following functions early-out to if we already decoded.
DecodeImageIfNecessary(draw_image, image_data, TaskType::kInRaster);
- UploadImageIfNecessary(draw_image, image_data, std::move(encoded_data));
+ UploadImageIfNecessary(draw_image, image_data);
// Unref the image decode, but not the image. The image ref will be released
// in DrawWithImageFinished.
UnrefImageDecode(draw_image, cache_key);
@@ -1458,8 +1468,7 @@ void GpuImageDecodeCache::DecodeImageInTask(const DrawImage& draw_image,
DecodeImageIfNecessary(draw_image, image_data, task_type);
}
-void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image,
- sk_sp<SkData> encoded_data) {
+void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"GpuImageDecodeCache::UploadImage");
base::Optional<viz::RasterContextProvider::ScopedRasterContextLock>
@@ -1479,7 +1488,7 @@ void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image,
if (image_data->is_bitmap_backed)
DecodeImageIfNecessary(draw_image, image_data, TaskType::kInRaster);
- UploadImageIfNecessary(draw_image, image_data, std::move(encoded_data));
+ UploadImageIfNecessary(draw_image, image_data);
}
void GpuImageDecodeCache::OnImageDecodeTaskCompleted(
@@ -1935,8 +1944,7 @@ void GpuImageDecodeCache::DecodeImageIfNecessary(const DrawImage& draw_image,
}
void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
- ImageData* image_data,
- sk_sp<SkData> encoded_data) {
+ ImageData* image_data) {
CheckContextLockAcquiredIfNecessary();
lock_.AssertAcquired();
@@ -1998,14 +2006,11 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
DCHECK_EQ(0, image_data->upload_scale_mip_level);
const gfx::Size output_size(draw_image.paint_image().width(),
draw_image.paint_image().height());
- // Try to get the encoded data if we don't have it already: this can
- // happen, e.g., if we create an upload task using a pre-existing
- // ImageData. In that case, we previously decided to do hardware decode
- // acceleration but we didn't cache the encoded data.
- if (!encoded_data) {
- encoded_data = draw_image.paint_image().GetSkImage()->refEncodedData();
- DCHECK(encoded_data);
- }
+
+ // Get the encoded data in a contiguous form.
+ sk_sp<SkData> encoded_data =
+ draw_image.paint_image().GetSkImage()->refEncodedData();
+ DCHECK(encoded_data);
const uint32_t transfer_cache_id =
ClientImageTransferCacheEntry::GetNextId();
const gpu::SyncToken decode_sync_token =
@@ -2202,8 +2207,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
scoped_refptr<GpuImageDecodeCache::ImageData>
GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
- bool allow_hardware_decode,
- sk_sp<SkData>* encoded_data) {
+ bool allow_hardware_decode) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"GpuImageDecodeCache::CreateImageData");
lock_.AssertAcquired();
@@ -2249,24 +2253,12 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
// Figure out if we will do hardware accelerated decoding. The criteria is as
// follows:
//
- // - Either the kVaapiJpegImageDecodeAcceleration or
- // kVaapiWebPImageDecodeAcceleration features are enabled.
// - The caller allows hardware decodes.
// - We are using the transfer cache (OOP-R).
// - The image does not require downscaling for uploading (see TODO below).
- // - All the encoded data was received prior to any decoding work. Otherwise,
- // it means that the software decoder has already started decoding the
- // image, so we just let it finish.
- // - The image's color space is sRGB. This is because we don't currently
- // support detecting embedded color profiles.
+ // - The image does not require subsetting.
// - The image is supported according to the profiles advertised by the GPU
- // service. Checking this involves obtaining the contiguous encoded data
- // which may require a copy if the data is not already contiguous. Because
- // of this, we return a pointer to the contiguous data (as |encoded_data|)
- // so that we can re-use it later (when requesting the image decode).
- //
- // TODO(crbug.com/953363): ideally, we can make the hardware decoder support
- // decision without requiring contiguous data.
+ // service.
//
// TODO(crbug.com/953367): currently, we don't support scaling with hardware
// decode acceleration. Note that it's still okay for the image to be
@@ -2275,33 +2267,28 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
// TODO(crbug.com/981208): |data_size| needs to be set to the size of the
// decoded data, but for accelerated decodes we won't know until the driver
// gives us the result in the GPU process. Figure out what to do.
+ const ImageHeaderMetadata* image_metadata =
+ draw_image.paint_image().GetImageHeaderMetadata();
bool do_hardware_accelerated_decode = false;
- if ((base::FeatureList::IsEnabled(
- features::kVaapiJpegImageDecodeAcceleration) ||
- base::FeatureList::IsEnabled(
- features::kVaapiWebPImageDecodeAcceleration)) &&
- allow_hardware_decode && mode == DecodedDataMode::kTransferCache &&
+ if (allow_hardware_decode && mode == DecodedDataMode::kTransferCache &&
upload_scale_mip_level == 0 &&
- draw_image.paint_image().IsEligibleForAcceleratedDecoding() &&
- draw_image.paint_image().color_space() &&
- draw_image.paint_image().color_space()->isSRGB()) {
- sk_sp<SkData> tmp_encoded_data =
- draw_image.paint_image().GetSkImage()
- ? draw_image.paint_image().GetSkImage()->refEncodedData()
- : nullptr;
- if (tmp_encoded_data &&
- context_->ContextSupport()->CanDecodeWithHardwareAcceleration(
- base::make_span<const uint8_t>(tmp_encoded_data->bytes(),
- tmp_encoded_data->size()))) {
- do_hardware_accelerated_decode = true;
- DCHECK(encoded_data);
- *encoded_data = std::move(tmp_encoded_data);
- }
+ draw_image.paint_image().subset_rect().IsEmpty() &&
+ context_->ContextSupport()->CanDecodeWithHardwareAcceleration(
+ image_metadata)) {
+ DCHECK(image_metadata);
+ DCHECK_EQ(image_metadata->image_size.width(),
+ draw_image.paint_image().width());
+ DCHECK_EQ(image_metadata->image_size.height(),
+ draw_image.paint_image().height());
+
+ const bool is_jpeg = (image_metadata->image_type == ImageType::kJPEG);
+ const bool is_webp = (image_metadata->image_type == ImageType::kWEBP);
+ do_hardware_accelerated_decode =
+ (is_jpeg && allow_accelerated_jpeg_decodes_) ||
+ (is_webp && allow_accelerated_webp_decodes_);
+ DCHECK(!do_hardware_accelerated_decode || !is_bitmap_backed);
}
- // If draw_image.paint_image().IsEligibleForAcceleratedDecoding() returns
- // true, the image should not be backed by a bitmap.
- DCHECK(!do_hardware_accelerated_decode || !is_bitmap_backed);
SkYUVASizeInfo target_yuva_size_info;
// We fill out a default value for |yuv_color_space| but only fill out the
// base::Optional member in ImageData if it is YUV.
@@ -2659,8 +2646,8 @@ bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data,
size_t GpuImageDecodeCache::GetDrawImageSizeForTesting(const DrawImage& image) {
base::AutoLock lock(lock_);
- scoped_refptr<ImageData> data = CreateImageData(
- image, false /* allow_hardware_decode */, nullptr /* encoded_data */);
+ scoped_refptr<ImageData> data =
+ CreateImageData(image, false /* allow_hardware_decode */);
return data->size;
}