1 /*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "src/gpu/graphite/ImageUtils.h"
9
10 #include "include/gpu/graphite/ImageProvider.h"
11 #include "include/gpu/graphite/Recorder.h"
12 #include "src/image/SkImage_Base.h"
13
14 namespace {
15
valid_client_provided_image(const SkImage * clientProvided,const SkImage * original,SkImage::RequiredImageProperties requiredProps)16 bool valid_client_provided_image(const SkImage* clientProvided,
17 const SkImage* original,
18 SkImage::RequiredImageProperties requiredProps) {
19 if (!clientProvided ||
20 !as_IB(clientProvided)->isGraphiteBacked() ||
21 original->dimensions() != clientProvided->dimensions() ||
22 original->alphaType() != clientProvided->alphaType()) {
23 return false;
24 }
25
26 uint32_t origChannels = SkColorTypeChannelFlags(original->colorType());
27 uint32_t clientChannels = SkColorTypeChannelFlags(clientProvided->colorType());
28 if (origChannels != clientChannels) {
29 return false;
30 }
31
32 return true;
33 }
34
35 } // anonymous namespace
36
37 namespace skgpu::graphite {
38
GetGraphiteBacked(Recorder * recorder,const SkImage * imageIn,SkSamplingOptions sampling)39 std::pair<sk_sp<SkImage>, SkSamplingOptions> GetGraphiteBacked(Recorder* recorder,
40 const SkImage* imageIn,
41 SkSamplingOptions sampling) {
42 skgpu::Mipmapped mipmapped = (sampling.mipmap != SkMipmapMode::kNone)
43 ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
44
45 if (imageIn->dimensions().area() <= 1 && mipmapped == skgpu::Mipmapped::kYes) {
46 mipmapped = skgpu::Mipmapped::kNo;
47 sampling = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
48 }
49
50 sk_sp<SkImage> result;
51 if (as_IB(imageIn)->isGraphiteBacked()) {
52 result = sk_ref_sp(imageIn);
53
54 // If the preexisting Graphite-backed image doesn't have the required mipmaps we will drop
55 // down the sampling
56 if (mipmapped == skgpu::Mipmapped::kYes && !result->hasMipmaps()) {
57 mipmapped = skgpu::Mipmapped::kNo;
58 sampling = SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone);
59 }
60 } else {
61 auto clientImageProvider = recorder->clientImageProvider();
62 result = clientImageProvider->findOrCreate(recorder, imageIn, { mipmapped });
63
64 if (!valid_client_provided_image(result.get(), imageIn, { mipmapped })) {
65 // The client did not fulfill the ImageProvider contract so drop the image.
66 result = nullptr;
67 }
68 }
69
70 return { result, sampling };
71 }
72
73 } // namespace skgpu::graphite
74