blob: d694fa22e244cb0c44b8dbd6621b1ed9256f6e9c [file] [log] [blame]
robertphillipsb6c65e92016-02-04 10:52:42 -08001/*
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 SkSpecialImage_DEFINED
9#define SkSpecialImage_DEFINED
10
robertphillips3b087f42016-02-18 08:48:03 -080011#include "SkNextID.h"
robertphillipsb6c65e92016-02-04 10:52:42 -080012#include "SkRefCnt.h"
brianosman898235c2016-04-06 07:38:23 -070013#include "SkSurfaceProps.h"
robertphillipsb6c65e92016-02-04 10:52:42 -080014
brianosmaneed6b0e2016-09-23 13:04:05 -070015#include "SkImageFilter.h" // for OutputProperties
16#include "SkImageInfo.h" // for SkAlphaType
robertphillips83c17fa2016-03-18 08:14:27 -070017
18class GrContext;
Robert Phillips8bc06d02016-11-01 17:28:40 -040019class GrTextureProxy;
robertphillipsb6c65e92016-02-04 10:52:42 -080020class SkBitmap;
21class SkCanvas;
22class SkImage;
23struct SkImageInfo;
24class SkPaint;
robertphillips83c17fa2016-03-18 08:14:27 -070025class SkPixmap;
robertphillipsb6c65e92016-02-04 10:52:42 -080026class SkSpecialSurface;
robertphillipsb4bd11e2016-03-21 13:44:18 -070027class SkSurface;
robertphillipsb6c65e92016-02-04 10:52:42 -080028
robertphillips3b087f42016-02-18 08:48:03 -080029enum {
30 kNeedNewImageUniqueID_SpecialImage = 0
31};
32
robertphillipsb6c65e92016-02-04 10:52:42 -080033/**
34 * This is a restricted form of SkImage solely intended for internal use. It
35 * differs from SkImage in that:
36 * - it can only be backed by raster or gpu (no generators)
Robert Phillips2c6d2bf2017-02-21 10:19:29 -050037 * - it can be backed by a GrTextureProxy larger than its nominal bounds
robertphillipsb6c65e92016-02-04 10:52:42 -080038 * - it can't be drawn tiled
39 * - it can't be drawn with MIPMAPs
40 * It is similar to SkImage in that it abstracts how the pixels are stored/represented.
41 *
42 * Note: the contents of the backing storage outside of the subset rect are undefined.
43 */
44class SkSpecialImage : public SkRefCnt {
45public:
robertphillips37bd7c32016-03-17 14:31:39 -070046 typedef void* ReleaseContext;
47 typedef void(*RasterReleaseProc)(void* pixels, ReleaseContext);
48
brianosman898235c2016-04-06 07:38:23 -070049 const SkSurfaceProps& props() const { return fProps; }
50
robertphillipsb6c65e92016-02-04 10:52:42 -080051 int width() const { return fSubset.width(); }
52 int height() const { return fSubset.height(); }
robertphillipsdf7bb472016-02-19 08:19:40 -080053 const SkIRect& subset() const { return fSubset; }
brianosmanafbf71d2016-07-21 07:15:37 -070054 SkColorSpace* getColorSpace() const;
robertphillipsdf7bb472016-02-19 08:19:40 -080055
robertphillips3b087f42016-02-18 08:48:03 -080056 uint32_t uniqueID() const { return fUniqueID; }
brianosman80e96082016-08-16 07:09:47 -070057 virtual SkAlphaType alphaType() const = 0;
robertphillips3b087f42016-02-18 08:48:03 -080058 virtual size_t getSize() const = 0;
robertphillipsb6c65e92016-02-04 10:52:42 -080059
60 /**
robertphillips83c17fa2016-03-18 08:14:27 -070061 * Ensures that a special image is backed by a texture (when GrContext is non-null). If no
62 * transformation is required, the returned image may be the same as this special image.
63 * If this special image is from a different GrContext, this will fail.
64 */
robertphillips3e302272016-04-20 11:48:36 -070065 sk_sp<SkSpecialImage> makeTextureImage(GrContext*);
robertphillips83c17fa2016-03-18 08:14:27 -070066
67 /**
robertphillipsb6c65e92016-02-04 10:52:42 -080068 * Draw this SpecialImage into the canvas.
69 */
robertphillipse8c34972016-02-16 12:09:36 -080070 void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
robertphillipsb6c65e92016-02-04 10:52:42 -080071
robertphillips3e302272016-04-20 11:48:36 -070072 static sk_sp<SkSpecialImage> MakeFromImage(const SkIRect& subset,
brianosman898235c2016-04-06 07:38:23 -070073 sk_sp<SkImage>,
Brian Osman61624f02016-12-09 14:51:59 -050074 SkColorSpace* dstColorSpace,
brianosman898235c2016-04-06 07:38:23 -070075 const SkSurfaceProps* = nullptr);
robertphillips3e302272016-04-20 11:48:36 -070076 static sk_sp<SkSpecialImage> MakeFromRaster(const SkIRect& subset,
brianosman898235c2016-04-06 07:38:23 -070077 const SkBitmap&,
78 const SkSurfaceProps* = nullptr);
robertphillipsc91fd342016-04-25 12:32:54 -070079#if SK_SUPPORT_GPU
Robert Phillips8bc06d02016-11-01 17:28:40 -040080 static sk_sp<SkSpecialImage> MakeDeferredFromGpu(GrContext*,
81 const SkIRect& subset,
82 uint32_t uniqueID,
Robert Phillips63c67462017-02-15 14:19:01 -050083 sk_sp<GrTextureProxy>,
Robert Phillips8bc06d02016-11-01 17:28:40 -040084 sk_sp<SkColorSpace>,
85 const SkSurfaceProps* = nullptr,
86 SkAlphaType at = kPremul_SkAlphaType);
robertphillipsc91fd342016-04-25 12:32:54 -070087#endif
robertphillipsb6c65e92016-02-04 10:52:42 -080088
89 /**
robertphillipsb4bd11e2016-03-21 13:44:18 -070090 * Create a new special surface with a backend that is compatible with this special image.
robertphillipsb6c65e92016-02-04 10:52:42 -080091 */
brianosmaneed6b0e2016-09-23 13:04:05 -070092 sk_sp<SkSpecialSurface> makeSurface(const SkImageFilter::OutputProperties& outProps,
93 const SkISize& size,
94 SkAlphaType at = kPremul_SkAlphaType) const;
robertphillipsb6c65e92016-02-04 10:52:42 -080095
robertphillipsc5035e72016-03-17 06:58:39 -070096 /**
robertphillipsb4bd11e2016-03-21 13:44:18 -070097 * Create a new surface with a backend that is compatible with this special image.
98 * TODO: switch this to makeSurface once we resolved the naming issue
99 */
brianosmaneed6b0e2016-09-23 13:04:05 -0700100 sk_sp<SkSurface> makeTightSurface(const SkImageFilter::OutputProperties& outProps,
101 const SkISize& size,
102 SkAlphaType at = kPremul_SkAlphaType) const;
robertphillipsb4bd11e2016-03-21 13:44:18 -0700103
104 /**
robertphillipsc5035e72016-03-17 06:58:39 -0700105 * Extract a subset of this special image and return it as a special image.
106 * It may or may not point to the same backing memory.
107 */
robertphillips37bd7c32016-03-17 14:31:39 -0700108 sk_sp<SkSpecialImage> makeSubset(const SkIRect& subset) const;
robertphillipsc5035e72016-03-17 06:58:39 -0700109
robertphillipsb4bd11e2016-03-21 13:44:18 -0700110 /**
Robert Phillipsa5fdc972017-02-18 16:58:09 -0500111 * Create an SkImage from the contents of this special image optionally extracting a subset.
robertphillipsb4bd11e2016-03-21 13:44:18 -0700112 * It may or may not point to the same backing memory.
Robert Phillipsa5fdc972017-02-18 16:58:09 -0500113 * Note: when no 'subset' parameter is specified the the entire SkSpecialImage will be
114 * returned - including whatever extra padding may have resulted from a loose fit!
115 * When the 'subset' parameter is specified the returned image will be tight even if that
116 * entails a copy!
robertphillipsb4bd11e2016-03-21 13:44:18 -0700117 */
Robert Phillipsa5fdc972017-02-18 16:58:09 -0500118 sk_sp<SkImage> asImage(const SkIRect* subset = nullptr) const;
robertphillipsb4bd11e2016-03-21 13:44:18 -0700119
robertphillips4418dba2016-03-07 12:45:14 -0800120 /**
robertphillips64612512016-04-08 12:10:42 -0700121 * If the SpecialImage is backed by a gpu texture, return true.
122 */
123 bool isTextureBacked() const;
124
125 /**
126 * Return the GrContext if the SkSpecialImage is GrTexture-backed
127 */
128 GrContext* getContext() const;
129
robertphillipsc91fd342016-04-25 12:32:54 -0700130#if SK_SUPPORT_GPU
robertphillips64612512016-04-08 12:10:42 -0700131 /**
Robert Phillips8e1c4e62017-02-19 12:27:01 -0500132 * Regardless of the underlying backing store, return the contents as a GrTextureProxy.
robertphillips4418dba2016-03-07 12:45:14 -0800133 * The active portion of the texture can be retrieved via 'subset'.
134 */
Robert Phillips8e1c4e62017-02-19 12:27:01 -0500135 sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*) const;
robertphillipsc91fd342016-04-25 12:32:54 -0700136#endif
robertphillips4418dba2016-03-07 12:45:14 -0800137
robertphillipsc5035e72016-03-17 06:58:39 -0700138 /**
robertphillips64612512016-04-08 12:10:42 -0700139 * Regardless of the underlying backing store, return the contents as an SkBitmap
robertphillipsc5035e72016-03-17 06:58:39 -0700140 *
141 * The returned ImageInfo represents the backing memory. Use 'subset'
142 * to get the active portion's dimensions.
robertphillipsc5035e72016-03-17 06:58:39 -0700143 */
robertphillips64612512016-04-08 12:10:42 -0700144 bool getROPixels(SkBitmap*) const;
robertphillipsc5035e72016-03-17 06:58:39 -0700145
robertphillips3b087f42016-02-18 08:48:03 -0800146protected:
robertphillips3e302272016-04-20 11:48:36 -0700147 SkSpecialImage(const SkIRect& subset, uint32_t uniqueID, const SkSurfaceProps*);
robertphillips3b087f42016-02-18 08:48:03 -0800148
robertphillipsb6c65e92016-02-04 10:52:42 -0800149private:
brianosman898235c2016-04-06 07:38:23 -0700150 const SkSurfaceProps fProps;
151 const SkIRect fSubset;
152 const uint32_t fUniqueID;
robertphillips3b087f42016-02-18 08:48:03 -0800153
robertphillipsb6c65e92016-02-04 10:52:42 -0800154 typedef SkRefCnt INHERITED;
155};
156
157#endif