Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: skia/ext/cdl_surface.h

Issue 2523673004: [NOT FOR COMMIT] Fully replace SkCanvas uses.
Patch Set: Support Android build. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « skia/ext/cdl_shader.cc ('k') | skia/ext/cdl_surface.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #ifndef SKIA_EXT_CDL_SURFACE_H_
9 #define SKIA_EXT_CDL_SURFACE_H_
10
11 #include "cdl_common.h"
12
13 #if CDL_ENABLED
14
15 #include "third_party/skia/include/core/SkImage.h"
16 #include "third_party/skia/include/core/SkRefCnt.h"
17 #include "third_party/skia/include/core/SkSurface.h"
18 #include "third_party/skia/include/core/SkSurfaceProps.h"
19
20 class GrContext;
21 class GrRenderTarget;
22
23 class SK_API CdlSurface : public SkRefCnt {
24 public:
25 CdlSurface(sk_sp<SkSurface> surface);
26 ~CdlSurface() override;
27
28 /**
29 * Create a new surface, using the specified pixels/rowbytes as its
30 * backend.
31 *
32 * If the requested surface cannot be created, or the request is not a
33 * supported configuration, NULL will be returned.
34 *
35 * Callers are responsible for initialiazing the surface pixels.
36 */
37 static sk_sp<CdlSurface> MakeRasterDirect(const SkImageInfo&,
38 void* pixels,
39 size_t rowBytes,
40 const SkSurfaceProps* = nullptr);
41
42 /**
43 * The same as NewRasterDirect, but also accepts a call-back routine, which
44 * is invoked
45 * when the surface is deleted, and is passed the pixel memory and the
46 * specified context.
47 */
48 static sk_sp<CdlSurface> MakeRasterDirectReleaseProc(
49 const SkImageInfo&,
50 void* pixels,
51 size_t rowBytes,
52 void (*releaseProc)(void* pixels, void* context),
53 void* context,
54 const SkSurfaceProps* = nullptr);
55
56 /**
57 * Return a new surface, with the memory for the pixels automatically
58 * allocated and
59 * zero-initialized, but respecting the specified rowBytes. If rowBytes==0,
60 * then a default
61 * value will be chosen. If a non-zero rowBytes is specified, then any images
62 * snapped off of
63 * this surface (via makeImageSnapshot()) are guaranteed to have the same
64 * rowBytes.
65 *
66 * If the requested surface cannot be created, or the request is not a
67 * supported configuration, NULL will be returned.
68 */
69 static sk_sp<CdlSurface> MakeRaster(const SkImageInfo&,
70 size_t rowBytes,
71 const SkSurfaceProps*);
72
73 /**
74 * Allocate a new surface, automatically computing the rowBytes.
75 */
76 static sk_sp<CdlSurface> MakeRaster(const SkImageInfo& info,
77 const SkSurfaceProps* props = nullptr) {
78 return MakeRaster(info, 0, props);
79 }
80
81 /**
82 * Helper version of NewRaster. It creates a SkImageInfo with the
83 * specified width and height, and populates the rest of info to match
84 * pixels in SkPMColor format.
85 */
86 static sk_sp<CdlSurface> MakeRasterN32Premul(
87 int width,
88 int height,
89 const SkSurfaceProps* props = nullptr) {
90 return MakeRaster(SkImageInfo::MakeN32Premul(width, height), props);
91 }
92
93 /**
94 * Used to wrap a pre-existing backend 3D API texture as a SkSurface. The
95 * kRenderTarget flag
96 * must be set on GrBackendTextureDesc for this to succeed. Skia will not
97 * assume ownership
98 * of the texture and the client must ensure the texture is valid for the
99 * lifetime of the
100 * SkSurface.
101 */
102 static sk_sp<CdlSurface> MakeFromBackendTexture(GrContext*,
103 const GrBackendTextureDesc&,
104 sk_sp<SkColorSpace>,
105 const SkSurfaceProps*);
106
107 /**
108 * Used to wrap a pre-existing 3D API rendering target as a SkSurface. Skia
109 * will not assume
110 * ownership of the render target and the client must ensure the render
111 * target is valid for the
112 * lifetime of the SkSurface.
113 */
114 static sk_sp<CdlSurface> MakeFromBackendRenderTarget(
115 GrContext*,
116 const GrBackendRenderTargetDesc&,
117 sk_sp<SkColorSpace>,
118 const SkSurfaceProps*);
119
120 /**
121 * Used to wrap a pre-existing 3D API texture as a SkSurface. Skia will treat
122 * the texture as
123 * a rendering target only, but unlike NewFromBackendRenderTarget, Skia will
124 * manage and own
125 * the associated render target objects (but not the provided texture). The
126 * kRenderTarget flag
127 * must be set on GrBackendTextureDesc for this to succeed. Skia will not
128 * assume ownership
129 * of the texture and the client must ensure the texture is valid for the
130 * lifetime of the
131 * SkSurface.
132 */
133 static sk_sp<CdlSurface> MakeFromBackendTextureAsRenderTarget(
134 GrContext*,
135 const GrBackendTextureDesc&,
136 sk_sp<SkColorSpace>,
137 const SkSurfaceProps*);
138
139 /**
140 * Legacy versions of the above factories, without color space support. These
141 * create "legacy"
142 * surfaces that operate without gamma correction or color management.
143 */
144 static sk_sp<CdlSurface> MakeFromBackendTexture(
145 GrContext* ctx,
146 const GrBackendTextureDesc& desc,
147 const SkSurfaceProps* props) {
148 return MakeFromBackendTexture(ctx, desc, nullptr, props);
149 }
150
151 static sk_sp<CdlSurface> MakeFromBackendRenderTarget(
152 GrContext* ctx,
153 const GrBackendRenderTargetDesc& desc,
154 const SkSurfaceProps* props) {
155 return MakeFromBackendRenderTarget(ctx, desc, nullptr, props);
156 }
157
158 static sk_sp<CdlSurface> MakeFromBackendTextureAsRenderTarget(
159 GrContext* ctx,
160 const GrBackendTextureDesc& desc,
161 const SkSurfaceProps* props) {
162 return MakeFromBackendTextureAsRenderTarget(ctx, desc, nullptr, props);
163 }
164
165 /**
166 * Return a new surface whose contents will be drawn to an offscreen
167 * render target, allocated by the surface.
168 */
169 static sk_sp<CdlSurface> MakeRenderTarget(GrContext*,
170 SkBudgeted,
171 const SkImageInfo&,
172 int sampleCount,
173 GrSurfaceOrigin,
174 const SkSurfaceProps*);
175
176 static sk_sp<CdlSurface> MakeRenderTarget(GrContext* context,
177 SkBudgeted budgeted,
178 const SkImageInfo& info,
179 int sampleCount,
180 const SkSurfaceProps* props) {
181 return MakeRenderTarget(context, budgeted, info, sampleCount,
182 kBottomLeft_GrSurfaceOrigin, props);
183 }
184
185 static sk_sp<CdlSurface> MakeRenderTarget(GrContext* gr,
186 SkBudgeted b,
187 const SkImageInfo& info) {
188 if (!info.width() || !info.height()) {
189 return nullptr;
190 }
191 return MakeRenderTarget(gr, b, info, 0, kBottomLeft_GrSurfaceOrigin,
192 nullptr);
193 }
194
195 int width() const { return surface_->width(); }
196 int height() const { return surface_->height(); }
197
198 /**
199 * Returns a unique non-zero, unique value identifying the content of this
200 * surface. Each time the content is changed changed, either by drawing
201 * into this surface, or explicitly calling notifyContentChanged()) this
202 * method will return a new value.
203 *
204 * If this surface is empty (i.e. has a zero-dimention), this will return
205 * 0.
206 */
207 uint32_t generationID() { return surface_->generationID(); }
208
209 /**
210 * Call this if the contents are about to change. This will (lazily) force a
211 * new
212 * value to be returned from generationID() when it is called next.
213 *
214 * CAN WE DEPRECATE THIS?
215 */
216 void notifyContentWillChange(SkSurface::ContentChangeMode mode) {
217 surface_->notifyContentWillChange(mode);
218 }
219
220 enum BackendHandleAccess {
221 kFlushRead_BackendHandleAccess, //!< caller may read from the backend
222 //! object
223 kFlushWrite_BackendHandleAccess, //!< caller may write to the backend
224 //! object
225 kDiscardWrite_BackendHandleAccess, //!< caller must over-write the entire
226 //! backend object
227 };
228
229 /*
230 * These are legacy aliases which will be removed soon
231 */
232 static const BackendHandleAccess kFlushRead_TextureHandleAccess =
233 kFlushRead_BackendHandleAccess;
234 static const BackendHandleAccess kFlushWrite_TextureHandleAccess =
235 kFlushWrite_BackendHandleAccess;
236 static const BackendHandleAccess kDiscardWrite_TextureHandleAccess =
237 kDiscardWrite_BackendHandleAccess;
238
239 /**
240 * Retrieves the backend API handle of the texture used by this surface, or 0
241 * if the surface
242 * is not backed by a GPU texture.
243 *
244 * The returned texture-handle is only valid until the next draw-call into
245 * the surface,
246 * or the surface is deleted.
247 */
248 GrBackendObject getTextureHandle(BackendHandleAccess);
249
250 /**
251 * Retrieves the backend API handle of the RenderTarget backing this surface.
252 * Callers must
253 * ensure this function returns 'true' or else the GrBackendObject will be
254 * invalid
255 *
256 * In OpenGL this will return the FramebufferObject ID.
257 */
258 bool getRenderTargetHandle(GrBackendObject*, BackendHandleAccess);
259
260 /**
261 * Return a canvas that will draw into this surface. This will always
262 * return the same canvas for a given surface, and is manged/owned by the
263 * surface. It should not be used when its parent surface has gone out of
264 * scope.
265 */
266 CdlCanvas* getCanvas();
267
268 /**
269 * Return a new surface that is "compatible" with this one, in that it will
270 * efficiently be able to be drawn into this surface. Typical calling
271 * pattern:
272 *
273 * SkSurface* A = SkSurface::New...();
274 * SkCanvas* canvasA = surfaceA->newCanvas();
275 * ...
276 * SkSurface* surfaceB = surfaceA->newSurface(...);
277 * SkCanvas* canvasB = surfaceB->newCanvas();
278 * ... // draw using canvasB
279 * canvasA->drawSurface(surfaceB); // <--- this will always be optimal!
280 */
281 sk_sp<SkSurface> makeSurface(const SkImageInfo&);
282
283 /**
284 * Returns an image of the current state of the surface pixels up to this
285 * point. Subsequent changes to the surface (by drawing into its canvas)
286 * will not be reflected in this image. If a copy must be made the Budgeted
287 * parameter controls whether it counts against the resource budget
288 * (currently for the gpu backend only).
289 */
290 sk_sp<SkImage> makeImageSnapshot(SkBudgeted = SkBudgeted::kYes);
291
292 /**
293 * In rare instances a client may want a unique copy of the SkSurface's
294 * contents in an image
295 * snapshot. This enum can be used to enforce that the image snapshot's
296 * backing store is not
297 * shared with another image snapshot or the surface's backing store. This is
298 * generally more
299 * expensive. This was added for Chromium bug 585250.
300 */
301 enum ForceUnique { kNo_ForceUnique, kYes_ForceUnique };
302 sk_sp<SkImage> makeImageSnapshot(SkBudgeted, ForceUnique);
303
304 /**
305 * Though the caller could get a snapshot image explicitly, and draw that,
306 * it seems that directly drawing a surface into another canvas might be
307 * a common pattern, and that we could possibly be more efficient, since
308 * we'd know that the "snapshot" need only live until we've handed it off
309 * to the canvas.
310 */
311 void draw(CdlCanvas*, SkScalar x, SkScalar y, const CdlPaint*);
312
313 /**
314 * If the surface has direct access to its pixels (i.e. they are in local
315 * RAM) return true, and if not null, set the pixmap parameter to point to
316 * the information
317 * about the surface's pixels. The pixel address in the pixmap is only valid
318 * while
319 * the surface object is in scope, and no API call is made on the surface
320 * or its canvas.
321 *
322 * On failure, returns false and the pixmap parameter is ignored.
323 */
324 bool peekPixels(SkPixmap*);
325
326 /**
327 * Copy the pixels from the surface into the specified buffer (pixels +
328 * rowBytes),
329 * converting them into the requested format (dstInfo). The surface pixels
330 * are read
331 * starting at the specified (srcX,srcY) location.
332 *
333 * The specified ImageInfo and (srcX,srcY) offset specifies a source
334 * rectangle
335 *
336 * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height());
337 *
338 * srcR is intersected with the bounds of the base-layer. If this
339 * intersection is not empty,
340 * then we have two sets of pixels (of equal size). Replace the dst pixels
341 * with the
342 * corresponding src pixels, performing any colortype/alphatype
343 * transformations needed
344 * (in the case where the src and dst have different colortypes or
345 * alphatypes).
346 *
347 * This call can fail, returning false, for several reasons:
348 * - If srcR does not intersect the surface bounds.
349 * - If the requested colortype/alphatype cannot be converted from the
350 * surface's types.
351 */
352 bool readPixels(const SkImageInfo& dstInfo,
353 void* dstPixels,
354 size_t dstRowBytes,
355 int srcX,
356 int srcY);
357
358 const SkSurfaceProps& props() const { return surface_->props(); }
359
360 /**
361 * Issue any pending surface IO to the current backend 3D API and resolve any
362 * surface MSAA.
363 */
364 void prepareForExternalIO();
365
366 private:
367 sk_sp<SkSurface> surface_;
368 std::unique_ptr<CdlCanvas> canvas_;
369 };
370
371 #endif // CDL_ENABLED
372
373 #endif // SKIA_EXT_CDL_SURFACE_H_
OLDNEW
« no previous file with comments | « skia/ext/cdl_shader.cc ('k') | skia/ext/cdl_surface.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698