1 /*
2  * Copyright 2018 Google Inc.
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 "tools/gpu/ProxyUtils.h"
9 
10 #include "include/core/SkColor.h"
11 #include "include/gpu/GrBackendSurface.h"
12 #include "include/gpu/GrDirectContext.h"
13 #include "include/private/GrImageContext.h"
14 #include "src/gpu/GrDirectContextPriv.h"
15 #include "src/gpu/GrDrawingManager.h"
16 #include "src/gpu/GrGpu.h"
17 #include "src/gpu/GrImageContextPriv.h"
18 #include "src/gpu/GrPixmap.h"
19 #include "src/gpu/GrProgramInfo.h"
20 #include "src/gpu/GrProxyProvider.h"
21 #include "src/gpu/GrSurfaceContext.h"
22 #include "src/gpu/SkGr.h"
23 #include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
24 #include "src/image/SkImage_Base.h"
25 
26 namespace sk_gpu_test {
27 
GetTextureImageProxy(SkImage * image,GrRecordingContext * rContext)28 GrTextureProxy* GetTextureImageProxy(SkImage* image, GrRecordingContext* rContext) {
29     if (!image->isTextureBacked() || as_IB(image)->isYUVA()) {
30         return nullptr;
31     }
32     if (!rContext) {
33         // If the image is backed by a recording context we'll use that.
34         GrImageContext* iContext = as_IB(image)->context();
35         SkASSERT(iContext);
36         rContext = iContext->priv().asRecordingContext();
37         if (!rContext) {
38             return nullptr;
39         }
40     }
41     auto [view, ct] = as_IB(image)->asView(rContext, GrMipmapped::kNo);
42     if (!view) {
43         // With the above checks we expect this to succeed unless there is a context mismatch.
44         SkASSERT(!image->isValid(rContext));
45         return nullptr;
46     }
47     GrSurfaceProxy* proxy = view.proxy();
48     SkASSERT(proxy->asTextureProxy());
49     return proxy->asTextureProxy();
50 }
51 
MakeTextureProxyViewFromData(GrDirectContext * dContext,GrRenderable renderable,GrSurfaceOrigin origin,GrCPixmap pixmap)52 GrSurfaceProxyView MakeTextureProxyViewFromData(GrDirectContext* dContext,
53                                                 GrRenderable renderable,
54                                                 GrSurfaceOrigin origin,
55                                                 GrCPixmap pixmap) {
56     if (dContext->abandoned()) {
57         return {};
58     }
59 
60     const GrCaps* caps = dContext->priv().caps();
61 
62     const GrBackendFormat format = caps->getDefaultBackendFormat(pixmap.colorType(), renderable);
63     if (!format.isValid()) {
64         return {};
65     }
66     GrSwizzle swizzle = caps->getReadSwizzle(format, pixmap.colorType());
67 
68     sk_sp<GrTextureProxy> proxy;
69     proxy = dContext->priv().proxyProvider()->createProxy(format,
70                                                           pixmap.dimensions(),
71                                                           renderable,
72                                                           /*sample count*/ 1,
73                                                           GrMipmapped::kNo,
74                                                           SkBackingFit::kExact,
75                                                           SkBudgeted::kYes,
76                                                           GrProtected::kNo);
77     if (!proxy) {
78         return {};
79     }
80     GrSurfaceProxyView view(proxy, origin, swizzle);
81     auto sContext = GrSurfaceContext::Make(dContext, std::move(view), pixmap.colorInfo());
82     if (!sContext) {
83         return {};
84     }
85     if (!sContext->writePixels(dContext, pixmap, {0, 0})) {
86         return {};
87     }
88     return sContext->readSurfaceView();
89 }
90 
CreateProgramInfo(const GrCaps * caps,SkArenaAlloc * arena,const GrSurfaceProxyView & writeView,GrAppliedClip && appliedClip,const GrXferProcessor::DstProxyView & dstProxyView,GrGeometryProcessor * geomProc,SkBlendMode blendMode,GrPrimitiveType primitiveType,GrXferBarrierFlags renderPassXferBarriers,GrLoadOp colorLoadOp,GrPipeline::InputFlags flags,const GrUserStencilSettings * stencilSettings)91 GrProgramInfo* CreateProgramInfo(const GrCaps* caps,
92                                  SkArenaAlloc* arena,
93                                  const GrSurfaceProxyView& writeView,
94                                  GrAppliedClip&& appliedClip,
95                                  const GrXferProcessor::DstProxyView& dstProxyView,
96                                  GrGeometryProcessor* geomProc,
97                                  SkBlendMode blendMode,
98                                  GrPrimitiveType primitiveType,
99                                  GrXferBarrierFlags renderPassXferBarriers,
100                                  GrLoadOp colorLoadOp,
101                                  GrPipeline::InputFlags flags,
102                                  const GrUserStencilSettings* stencilSettings) {
103 
104     GrProcessorSet processors = GrProcessorSet(blendMode);
105 
106     SkPMColor4f analysisColor = { 0, 0, 0, 1 }; // opaque black
107 
108     SkDEBUGCODE(auto analysis =) processors.finalize(analysisColor,
109                                                      GrProcessorAnalysisCoverage::kSingleChannel,
110                                                      &appliedClip, stencilSettings, *caps,
111                                                      GrClampType::kAuto, &analysisColor);
112     SkASSERT(!analysis.requiresDstTexture());
113 
114     return GrSimpleMeshDrawOpHelper::CreateProgramInfo(caps, arena, writeView,
115                                                        std::move(appliedClip), dstProxyView,
116                                                        geomProc, std::move(processors),
117                                                        primitiveType, renderPassXferBarriers,
118                                                        colorLoadOp, flags, stencilSettings);
119 }
120 
121 
122 }  // namespace sk_gpu_test
123