• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 "src/core/SkSpecialSurface.h"
9 
10 #include <memory>
11 
12 #include "include/core/SkCanvas.h"
13 #include "include/core/SkColorSpace.h"
14 #include "include/core/SkMallocPixelRef.h"
15 #include "src/core/SkBitmapDevice.h"
16 #include "src/core/SkCanvasPriv.h"
17 #include "src/core/SkDevice.h"
18 #include "src/core/SkSpecialImage.h"
19 #include "src/core/SkSurfacePriv.h"
20 
SkSpecialSurface(sk_sp<SkBaseDevice> device,const SkIRect & subset)21 SkSpecialSurface::SkSpecialSurface(sk_sp<SkBaseDevice> device, const SkIRect& subset)
22         : fSubset(subset) {
23     SkASSERT(fSubset.width() > 0);
24     SkASSERT(fSubset.height() > 0);
25 
26     fCanvas = std::make_unique<SkCanvas>(std::move(device));
27     fCanvas->clipRect(SkRect::Make(subset));
28 #ifdef SK_IS_BOT
29     fCanvas->clear(SK_ColorRED);  // catch any imageFilter sloppiness
30 #endif
31 }
32 
makeImageSnapshot()33 sk_sp<SkSpecialImage> SkSpecialSurface::makeImageSnapshot() {
34     fCanvas->restoreToCount(0);
35 
36     // Because of the above 'restoreToCount(0)' we know we're getting the base device here.
37     SkBaseDevice* baseDevice = SkCanvasPriv::TopDevice(fCanvas.get());
38     if (!baseDevice) {
39         return nullptr;
40     }
41 
42     sk_sp<SkSpecialImage> image = baseDevice->snapSpecial(this->subset());
43 
44     fCanvas.reset();
45     return image;
46 }
47 
48 ///////////////////////////////////////////////////////////////////////////////
MakeRaster(const SkImageInfo & info,const SkSurfaceProps & props)49 sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRaster(const SkImageInfo& info,
50                                                      const SkSurfaceProps& props) {
51     if (!SkSurfaceValidateRasterInfo(info)) {
52         return nullptr;
53     }
54 
55     sk_sp<SkPixelRef> pr = SkMallocPixelRef::MakeAllocate(info, 0);
56     if (!pr) {
57         return nullptr;
58     }
59 
60     SkBitmap bitmap;
61     bitmap.setInfo(info, info.minRowBytes());
62     bitmap.setPixelRef(std::move(pr), 0, 0);
63 
64     sk_sp<SkBaseDevice> device(new SkBitmapDevice(bitmap,
65                                                   { props.flags(), kUnknown_SkPixelGeometry }));
66     if (!device) {
67         return nullptr;
68     }
69 
70     const SkIRect subset = SkIRect::MakeSize(info.dimensions());
71 
72     return sk_make_sp<SkSpecialSurface>(std::move(device), subset);
73 }
74 
75 ///////////////////////////////////////////////////////////////////////////////
76 #if defined(SK_GANESH)
77 #include "include/gpu/GrRecordingContext.h"
78 #include "src/gpu/SkBackingFit.h"
79 #include "src/gpu/ganesh/GrColorInfo.h"
80 #include "src/gpu/ganesh/GrRecordingContextPriv.h"
81 
MakeRenderTarget(GrRecordingContext * rContext,const SkImageInfo & ii,const SkSurfaceProps & props,GrSurfaceOrigin surfaceOrigin)82 sk_sp<SkSpecialSurface> SkSpecialSurface::MakeRenderTarget(GrRecordingContext* rContext,
83                                                            const SkImageInfo& ii,
84                                                            const SkSurfaceProps& props,
85                                                            GrSurfaceOrigin surfaceOrigin) {
86     if (!rContext) {
87         return nullptr;
88     }
89 
90     auto device = rContext->priv().createDevice(skgpu::Budgeted::kYes,
91                                                 ii,
92                                                 SkBackingFit::kApprox,
93                                                 1,
94                                                 GrMipmapped::kNo,
95                                                 GrProtected::kNo,
96                                                 surfaceOrigin,
97                                                 {props.flags(), kUnknown_SkPixelGeometry},
98                                                 skgpu::v1::Device::InitContents::kUninit);
99     if (!device) {
100         return nullptr;
101     }
102 
103     const SkIRect subset = SkIRect::MakeSize(ii.dimensions());
104 
105     return sk_make_sp<SkSpecialSurface>(std::move(device), subset);
106 }
107 
108 #endif // defined(SK_GANESH)
109 
110 ///////////////////////////////////////////////////////////////////////////////
111 #if SK_GRAPHITE
112 #include "src/gpu/graphite/Device.h"
113 
MakeGraphite(skgpu::graphite::Recorder * recorder,const SkImageInfo & ii,const SkSurfaceProps & props)114 sk_sp<SkSpecialSurface> SkSpecialSurface::MakeGraphite(skgpu::graphite::Recorder* recorder,
115                                                        const SkImageInfo& ii,
116                                                        const SkSurfaceProps& props) {
117     using namespace skgpu::graphite;
118 
119     if (!recorder) {
120         return nullptr;
121     }
122 
123     sk_sp<Device> device = Device::Make(recorder,
124                                         ii,
125                                         skgpu::Budgeted::kYes,
126                                         skgpu::Mipmapped::kNo,
127                                         {props.flags(), kUnknown_SkPixelGeometry},
128                                         /* addInitialClear= */ false);
129     if (!device) {
130         return nullptr;
131     }
132 
133     const SkIRect subset = SkIRect::MakeSize(ii.dimensions());
134 
135     return sk_make_sp<SkSpecialSurface>(std::move(device), subset);
136 }
137 
138 #endif // SK_GRAPHITE
139