gfx/skia/trunk/include/core/SkShader.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2006 The Android Open Source Project
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8
michael@0 9 #ifndef SkShader_DEFINED
michael@0 10 #define SkShader_DEFINED
michael@0 11
michael@0 12 #include "SkBitmap.h"
michael@0 13 #include "SkFlattenable.h"
michael@0 14 #include "SkMask.h"
michael@0 15 #include "SkMatrix.h"
michael@0 16 #include "SkPaint.h"
michael@0 17
michael@0 18 class SkPath;
michael@0 19 class GrContext;
michael@0 20 class GrEffectRef;
michael@0 21
michael@0 22 /** \class SkShader
michael@0 23 *
michael@0 24 * Shaders specify the source color(s) for what is being drawn. If a paint
michael@0 25 * has no shader, then the paint's color is used. If the paint has a
michael@0 26 * shader, then the shader's color(s) are use instead, but they are
michael@0 27 * modulated by the paint's alpha. This makes it easy to create a shader
michael@0 28 * once (e.g. bitmap tiling or gradient) and then change its transparency
michael@0 29 * w/o having to modify the original shader... only the paint's alpha needs
michael@0 30 * to be modified.
michael@0 31 */
michael@0 32 class SK_API SkShader : public SkFlattenable {
michael@0 33 public:
michael@0 34 SK_DECLARE_INST_COUNT(SkShader)
michael@0 35
michael@0 36 SkShader();
michael@0 37 virtual ~SkShader();
michael@0 38
michael@0 39 /**
michael@0 40 * Returns true if the local matrix is not an identity matrix.
michael@0 41 */
michael@0 42 bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); }
michael@0 43
michael@0 44 /**
michael@0 45 * Returns the local matrix.
michael@0 46 */
michael@0 47 const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
michael@0 48
michael@0 49 /**
michael@0 50 * Set the shader's local matrix.
michael@0 51 * @param localM The shader's new local matrix.
michael@0 52 */
michael@0 53 void setLocalMatrix(const SkMatrix& localM) { fLocalMatrix = localM; }
michael@0 54
michael@0 55 /**
michael@0 56 * Reset the shader's local matrix to identity.
michael@0 57 */
michael@0 58 void resetLocalMatrix() { fLocalMatrix.reset(); }
michael@0 59
michael@0 60 enum TileMode {
michael@0 61 /** replicate the edge color if the shader draws outside of its
michael@0 62 * original bounds
michael@0 63 */
michael@0 64 kClamp_TileMode,
michael@0 65
michael@0 66 /** repeat the shader's image horizontally and vertically */
michael@0 67 kRepeat_TileMode,
michael@0 68
michael@0 69 /** repeat the shader's image horizontally and vertically, alternating
michael@0 70 * mirror images so that adjacent images always seam
michael@0 71 */
michael@0 72 kMirror_TileMode,
michael@0 73
michael@0 74 #if 0
michael@0 75 /** only draw within the original domain, return 0 everywhere else */
michael@0 76 kDecal_TileMode,
michael@0 77 #endif
michael@0 78
michael@0 79 kTileModeCount
michael@0 80 };
michael@0 81
michael@0 82 // override these in your subclass
michael@0 83
michael@0 84 enum Flags {
michael@0 85 //!< set if all of the colors will be opaque
michael@0 86 kOpaqueAlpha_Flag = 0x01,
michael@0 87
michael@0 88 //! set if this shader's shadeSpan16() method can be called
michael@0 89 kHasSpan16_Flag = 0x02,
michael@0 90
michael@0 91 /** Set this bit if the shader's native data type is instrinsically 16
michael@0 92 bit, meaning that calling the 32bit shadeSpan() entry point will
michael@0 93 mean the the impl has to up-sample 16bit data into 32bit. Used as a
michael@0 94 a means of clearing a dither request if the it will have no effect
michael@0 95 */
michael@0 96 kIntrinsicly16_Flag = 0x04,
michael@0 97
michael@0 98 /** set (after setContext) if the spans only vary in X (const in Y).
michael@0 99 e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
michael@0 100 that varies from left-to-right. This flag specifies this for
michael@0 101 shadeSpan().
michael@0 102 */
michael@0 103 kConstInY32_Flag = 0x08,
michael@0 104
michael@0 105 /** same as kConstInY32_Flag, but is set if this is true for shadeSpan16
michael@0 106 which may not always be the case, since shadeSpan16 may be
michael@0 107 predithered, which would mean it was not const in Y, even though
michael@0 108 the 32bit shadeSpan() would be const.
michael@0 109 */
michael@0 110 kConstInY16_Flag = 0x10
michael@0 111 };
michael@0 112
michael@0 113 /**
michael@0 114 * Called sometimes before drawing with this shader. Return the type of
michael@0 115 * alpha your shader will return. The default implementation returns 0.
michael@0 116 * Your subclass should override if it can (even sometimes) report a
michael@0 117 * non-zero value, since that will enable various blitters to perform
michael@0 118 * faster.
michael@0 119 */
michael@0 120 virtual uint32_t getFlags() { return 0; }
michael@0 121
michael@0 122 /**
michael@0 123 * Returns true if the shader is guaranteed to produce only opaque
michael@0 124 * colors, subject to the SkPaint using the shader to apply an opaque
michael@0 125 * alpha value. Subclasses should override this to allow some
michael@0 126 * optimizations. isOpaque() can be called at any time, unlike getFlags,
michael@0 127 * which only works properly when the context is set.
michael@0 128 */
michael@0 129 virtual bool isOpaque() const { return false; }
michael@0 130
michael@0 131 /**
michael@0 132 * Return the alpha associated with the data returned by shadeSpan16(). If
michael@0 133 * kHasSpan16_Flag is not set, this value is meaningless.
michael@0 134 */
michael@0 135 virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
michael@0 136
michael@0 137 /**
michael@0 138 * Called once before drawing, with the current paint and device matrix.
michael@0 139 * Return true if your shader supports these parameters, or false if not.
michael@0 140 * If false is returned, nothing will be drawn. If true is returned, then
michael@0 141 * a balancing call to endContext() will be made before the next call to
michael@0 142 * setContext.
michael@0 143 *
michael@0 144 * Subclasses should be sure to call their INHERITED::setContext() if they
michael@0 145 * override this method.
michael@0 146 */
michael@0 147 virtual bool setContext(const SkBitmap& device, const SkPaint& paint,
michael@0 148 const SkMatrix& matrix);
michael@0 149
michael@0 150 /**
michael@0 151 * Assuming setContext returned true, endContext() will be called when
michael@0 152 * the draw using the shader has completed. It is an error for setContext
michael@0 153 * to be called twice w/o an intervening call to endContext().
michael@0 154 *
michael@0 155 * Subclasses should be sure to call their INHERITED::endContext() if they
michael@0 156 * override this method.
michael@0 157 */
michael@0 158 virtual void endContext();
michael@0 159
michael@0 160 SkDEBUGCODE(bool setContextHasBeenCalled() const { return SkToBool(fInSetContext); })
michael@0 161
michael@0 162 /**
michael@0 163 * Called for each span of the object being drawn. Your subclass should
michael@0 164 * set the appropriate colors (with premultiplied alpha) that correspond
michael@0 165 * to the specified device coordinates.
michael@0 166 */
michael@0 167 virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
michael@0 168
michael@0 169 typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count);
michael@0 170 virtual ShadeProc asAShadeProc(void** ctx);
michael@0 171
michael@0 172 /**
michael@0 173 * Called only for 16bit devices when getFlags() returns
michael@0 174 * kOpaqueAlphaFlag | kHasSpan16_Flag
michael@0 175 */
michael@0 176 virtual void shadeSpan16(int x, int y, uint16_t[], int count);
michael@0 177
michael@0 178 /**
michael@0 179 * Similar to shadeSpan, but only returns the alpha-channel for a span.
michael@0 180 * The default implementation calls shadeSpan() and then extracts the alpha
michael@0 181 * values from the returned colors.
michael@0 182 */
michael@0 183 virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
michael@0 184
michael@0 185 /**
michael@0 186 * Helper function that returns true if this shader's shadeSpan16() method
michael@0 187 * can be called.
michael@0 188 */
michael@0 189 bool canCallShadeSpan16() {
michael@0 190 return SkShader::CanCallShadeSpan16(this->getFlags());
michael@0 191 }
michael@0 192
michael@0 193 /**
michael@0 194 * Helper to check the flags to know if it is legal to call shadeSpan16()
michael@0 195 */
michael@0 196 static bool CanCallShadeSpan16(uint32_t flags) {
michael@0 197 return (flags & kHasSpan16_Flag) != 0;
michael@0 198 }
michael@0 199
michael@0 200 /**
michael@0 201 Gives method bitmap should be read to implement a shader.
michael@0 202 Also determines number and interpretation of "extra" parameters returned
michael@0 203 by asABitmap
michael@0 204 */
michael@0 205 enum BitmapType {
michael@0 206 kNone_BitmapType, //<! Shader is not represented as a bitmap
michael@0 207 kDefault_BitmapType,//<! Access bitmap using local coords transformed
michael@0 208 // by matrix. No extras
michael@0 209 kRadial_BitmapType, //<! Access bitmap by transforming local coordinates
michael@0 210 // by the matrix and taking the distance of result
michael@0 211 // from (0,0) as bitmap column. Bitmap is 1 pixel
michael@0 212 // tall. No extras
michael@0 213 kSweep_BitmapType, //<! Access bitmap by transforming local coordinates
michael@0 214 // by the matrix and taking the angle of result
michael@0 215 // to (0,0) as bitmap x coord, where angle = 0 is
michael@0 216 // bitmap left edge of bitmap = 2pi is the
michael@0 217 // right edge. Bitmap is 1 pixel tall. No extras
michael@0 218 kTwoPointRadial_BitmapType,
michael@0 219 //<! Matrix transforms to space where (0,0) is
michael@0 220 // the center of the starting circle. The second
michael@0 221 // circle will be centered (x, 0) where x may be
michael@0 222 // 0. The post-matrix space is normalized such
michael@0 223 // that 1 is the second radius - first radius.
michael@0 224 // Three extra parameters are returned:
michael@0 225 // 0: x-offset of second circle center
michael@0 226 // to first.
michael@0 227 // 1: radius of first circle in post-matrix
michael@0 228 // space
michael@0 229 // 2: the second radius minus the first radius
michael@0 230 // in pre-transformed space.
michael@0 231 kTwoPointConical_BitmapType,
michael@0 232 //<! Matrix transforms to space where (0,0) is
michael@0 233 // the center of the starting circle. The second
michael@0 234 // circle will be centered (x, 0) where x may be
michael@0 235 // 0.
michael@0 236 // Three extra parameters are returned:
michael@0 237 // 0: x-offset of second circle center
michael@0 238 // to first.
michael@0 239 // 1: radius of first circle
michael@0 240 // 2: the second radius minus the first radius
michael@0 241 kLinear_BitmapType, //<! Access bitmap using local coords transformed
michael@0 242 // by matrix. No extras
michael@0 243
michael@0 244 kLast_BitmapType = kLinear_BitmapType
michael@0 245 };
michael@0 246 /** Optional methods for shaders that can pretend to be a bitmap/texture
michael@0 247 to play along with opengl. Default just returns kNone_BitmapType and
michael@0 248 ignores the out parameters.
michael@0 249
michael@0 250 @param outTexture if non-NULL will be the bitmap representing the shader
michael@0 251 after return.
michael@0 252 @param outMatrix if non-NULL will be the matrix to apply to vertices
michael@0 253 to access the bitmap after return.
michael@0 254 @param xy if non-NULL will be the tile modes that should be
michael@0 255 used to access the bitmap after return.
michael@0 256 @param twoPointRadialParams Two extra return values needed for two point
michael@0 257 radial bitmaps. The first is the x-offset of
michael@0 258 the second point and the second is the radius
michael@0 259 about the first point.
michael@0 260 */
michael@0 261 virtual BitmapType asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix,
michael@0 262 TileMode xy[2]) const;
michael@0 263
michael@0 264 /**
michael@0 265 * If the shader subclass can be represented as a gradient, asAGradient
michael@0 266 * returns the matching GradientType enum (or kNone_GradientType if it
michael@0 267 * cannot). Also, if info is not null, asAGradient populates info with
michael@0 268 * the relevant (see below) parameters for the gradient. fColorCount
michael@0 269 * is both an input and output parameter. On input, it indicates how
michael@0 270 * many entries in fColors and fColorOffsets can be used, if they are
michael@0 271 * non-NULL. After asAGradient has run, fColorCount indicates how
michael@0 272 * many color-offset pairs there are in the gradient. If there is
michael@0 273 * insufficient space to store all of the color-offset pairs, fColors
michael@0 274 * and fColorOffsets will not be altered. fColorOffsets specifies
michael@0 275 * where on the range of 0 to 1 to transition to the given color.
michael@0 276 * The meaning of fPoint and fRadius is dependant on the type of gradient.
michael@0 277 *
michael@0 278 * None:
michael@0 279 * info is ignored.
michael@0 280 * Color:
michael@0 281 * fColorOffsets[0] is meaningless.
michael@0 282 * Linear:
michael@0 283 * fPoint[0] and fPoint[1] are the end-points of the gradient
michael@0 284 * Radial:
michael@0 285 * fPoint[0] and fRadius[0] are the center and radius
michael@0 286 * Radial2:
michael@0 287 * fPoint[0] and fRadius[0] are the center and radius of the 1st circle
michael@0 288 * fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
michael@0 289 * Sweep:
michael@0 290 * fPoint[0] is the center of the sweep.
michael@0 291 */
michael@0 292
michael@0 293 enum GradientType {
michael@0 294 kNone_GradientType,
michael@0 295 kColor_GradientType,
michael@0 296 kLinear_GradientType,
michael@0 297 kRadial_GradientType,
michael@0 298 kRadial2_GradientType,
michael@0 299 kSweep_GradientType,
michael@0 300 kConical_GradientType,
michael@0 301 kLast_GradientType = kConical_GradientType
michael@0 302 };
michael@0 303
michael@0 304 struct GradientInfo {
michael@0 305 int fColorCount; //!< In-out parameter, specifies passed size
michael@0 306 // of fColors/fColorOffsets on input, and
michael@0 307 // actual number of colors/offsets on
michael@0 308 // output.
michael@0 309 SkColor* fColors; //!< The colors in the gradient.
michael@0 310 SkScalar* fColorOffsets; //!< The unit offset for color transitions.
michael@0 311 SkPoint fPoint[2]; //!< Type specific, see above.
michael@0 312 SkScalar fRadius[2]; //!< Type specific, see above.
michael@0 313 TileMode fTileMode; //!< The tile mode used.
michael@0 314 uint32_t fGradientFlags; //!< see SkGradientShader::Flags
michael@0 315 };
michael@0 316
michael@0 317 virtual GradientType asAGradient(GradientInfo* info) const;
michael@0 318
michael@0 319 /**
michael@0 320 * If the shader subclass has a GrEffect implementation, this resturns the effect to install.
michael@0 321 * The incoming color to the effect has r=g=b=a all extracted from the SkPaint's alpha.
michael@0 322 * The output color should be the computed SkShader premul color modulated by the incoming
michael@0 323 * color. The GrContext may be used by the effect to create textures. The GPU device does not
michael@0 324 * call setContext. Instead we pass the SkPaint here in case the shader needs paint info.
michael@0 325 */
michael@0 326 virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const;
michael@0 327
michael@0 328 //////////////////////////////////////////////////////////////////////////
michael@0 329 // Factory methods for stock shaders
michael@0 330
michael@0 331 /** Call this to create a new shader that will draw with the specified bitmap.
michael@0 332 *
michael@0 333 * If the bitmap cannot be used (e.g. has no pixels, or its dimensions
michael@0 334 * exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
michael@0 335 * may be returned.
michael@0 336 *
michael@0 337 * If the src is kA8_Config then that mask will be colorized using the color on
michael@0 338 * the paint.
michael@0 339 *
michael@0 340 * @param src The bitmap to use inside the shader
michael@0 341 * @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
michael@0 342 * @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
michael@0 343 * @return Returns a new shader object. Note: this function never returns null.
michael@0 344 */
michael@0 345 static SkShader* CreateBitmapShader(const SkBitmap& src,
michael@0 346 TileMode tmx, TileMode tmy);
michael@0 347
michael@0 348 SK_TO_STRING_VIRT()
michael@0 349 SK_DEFINE_FLATTENABLE_TYPE(SkShader)
michael@0 350
michael@0 351 protected:
michael@0 352 enum MatrixClass {
michael@0 353 kLinear_MatrixClass, // no perspective
michael@0 354 kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each scanline
michael@0 355 kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
michael@0 356 };
michael@0 357 static MatrixClass ComputeMatrixClass(const SkMatrix&);
michael@0 358
michael@0 359 // These can be called by your subclass after setContext() has been called
michael@0 360 uint8_t getPaintAlpha() const { return fPaintAlpha; }
michael@0 361 const SkMatrix& getTotalInverse() const { return fTotalInverse; }
michael@0 362 MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
michael@0 363
michael@0 364 SkShader(SkReadBuffer& );
michael@0 365 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
michael@0 366 private:
michael@0 367 SkMatrix fLocalMatrix;
michael@0 368 SkMatrix fTotalInverse;
michael@0 369 uint8_t fPaintAlpha;
michael@0 370 uint8_t fTotalInverseClass;
michael@0 371 SkDEBUGCODE(SkBool8 fInSetContext;)
michael@0 372
michael@0 373 typedef SkFlattenable INHERITED;
michael@0 374 };
michael@0 375
michael@0 376 #endif

mercurial