gfx/skia/trunk/include/gpu/GrEffect.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 2012 Google Inc.
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 #ifndef GrEffect_DEFINED
michael@0 9 #define GrEffect_DEFINED
michael@0 10
michael@0 11 #include "GrColor.h"
michael@0 12 #include "GrEffectUnitTest.h"
michael@0 13 #include "GrTexture.h"
michael@0 14 #include "GrTextureAccess.h"
michael@0 15 #include "GrTypesPriv.h"
michael@0 16
michael@0 17 class GrBackendEffectFactory;
michael@0 18 class GrContext;
michael@0 19 class GrCoordTransform;
michael@0 20 class GrEffect;
michael@0 21 class GrVertexEffect;
michael@0 22 class SkString;
michael@0 23
michael@0 24 /**
michael@0 25 * A Wrapper class for GrEffect. Its ref-count will track owners that may use effects to enqueue
michael@0 26 * new draw operations separately from ownership within a deferred drawing queue. When the
michael@0 27 * GrEffectRef ref count reaches zero the scratch GrResources owned by the effect can be recycled
michael@0 28 * in service of later draws. However, the deferred draw queue may still own direct references to
michael@0 29 * the underlying GrEffect.
michael@0 30 *
michael@0 31 * GrEffectRefs created by new are placed in a per-thread managed pool. The pool is destroyed when
michael@0 32 * the thread ends. Therefore, all dynamically allocated GrEffectRefs must be unreffed before thread
michael@0 33 * termination.
michael@0 34 */
michael@0 35 class GrEffectRef : public SkRefCnt {
michael@0 36 public:
michael@0 37 SK_DECLARE_INST_COUNT(GrEffectRef);
michael@0 38 virtual ~GrEffectRef();
michael@0 39
michael@0 40 GrEffect* get() { return fEffect; }
michael@0 41 const GrEffect* get() const { return fEffect; }
michael@0 42
michael@0 43 const GrEffect* operator-> () { return fEffect; }
michael@0 44 const GrEffect* operator-> () const { return fEffect; }
michael@0 45
michael@0 46 void* operator new(size_t size);
michael@0 47 void operator delete(void* target);
michael@0 48
michael@0 49 void* operator new(size_t size, void* placement) {
michael@0 50 return ::operator new(size, placement);
michael@0 51 }
michael@0 52 void operator delete(void* target, void* placement) {
michael@0 53 ::operator delete(target, placement);
michael@0 54 }
michael@0 55
michael@0 56 private:
michael@0 57 friend class GrEffect; // to construct these
michael@0 58
michael@0 59 explicit GrEffectRef(GrEffect* effect);
michael@0 60
michael@0 61 GrEffect* fEffect;
michael@0 62
michael@0 63 typedef SkRefCnt INHERITED;
michael@0 64 };
michael@0 65
michael@0 66 /** Provides custom vertex shader, fragment shader, uniform data for a particular stage of the
michael@0 67 Ganesh shading pipeline.
michael@0 68 Subclasses must have a function that produces a human-readable name:
michael@0 69 static const char* Name();
michael@0 70 GrEffect objects *must* be immutable: after being constructed, their fields may not change.
michael@0 71
michael@0 72 GrEffect subclass objects should be created by factory functions that return GrEffectRef.
michael@0 73 There is no public way to wrap a GrEffect in a GrEffectRef. Thus, a factory should be a static
michael@0 74 member function of a GrEffect subclass.
michael@0 75
michael@0 76 Because almost no code should ever handle a GrEffect directly outside of a GrEffectRef, we
michael@0 77 privately inherit from SkRefCnt to help prevent accidental direct ref'ing/unref'ing of effects.
michael@0 78
michael@0 79 Dynamically allocated GrEffects and their corresponding GrEffectRefs are managed by a per-thread
michael@0 80 memory pool. The ref count of an effect must reach 0 before the thread terminates and the pool
michael@0 81 is destroyed. To create a static effect use the macro GR_CREATE_STATIC_EFFECT declared below.
michael@0 82 */
michael@0 83 class GrEffect : private SkRefCnt {
michael@0 84 public:
michael@0 85 SK_DECLARE_INST_COUNT(GrEffect)
michael@0 86
michael@0 87 virtual ~GrEffect();
michael@0 88
michael@0 89 /**
michael@0 90 * This function is used to perform optimizations. When called the color and validFlags params
michael@0 91 * indicate whether the input components to this effect in the FS will have known values.
michael@0 92 * validFlags is a bitfield of GrColorComponentFlags. The function updates both params to
michael@0 93 * indicate known values of its output. A component of the color param only has meaning if the
michael@0 94 * corresponding bit in validFlags is set.
michael@0 95 */
michael@0 96 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const = 0;
michael@0 97
michael@0 98 /** Will this effect read the source color value? */
michael@0 99 bool willUseInputColor() const { return fWillUseInputColor; }
michael@0 100
michael@0 101 /** This object, besides creating back-end-specific helper objects, is used for run-time-type-
michael@0 102 identification. The factory should be an instance of templated class,
michael@0 103 GrTBackendEffectFactory. It is templated on the subclass of GrEffect. The subclass must have
michael@0 104 a nested type (or typedef) named GLEffect which will be the subclass of GrGLEffect created
michael@0 105 by the factory.
michael@0 106
michael@0 107 Example:
michael@0 108 class MyCustomEffect : public GrEffect {
michael@0 109 ...
michael@0 110 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
michael@0 111 return GrTBackendEffectFactory<MyCustomEffect>::getInstance();
michael@0 112 }
michael@0 113 ...
michael@0 114 };
michael@0 115 */
michael@0 116 virtual const GrBackendEffectFactory& getFactory() const = 0;
michael@0 117
michael@0 118 /** Returns true if this and other effect conservatively draw identically. It can only return
michael@0 119 true when the two effects are of the same subclass (i.e. they return the same object from
michael@0 120 from getFactory()).
michael@0 121
michael@0 122 A return value of true from isEqual() should not be used to test whether the effects would
michael@0 123 generate the same shader code. To test for identical code generation use the EffectKey
michael@0 124 computed by the GrBackendEffectFactory:
michael@0 125 effectA.getFactory().glEffectKey(effectA) == effectB.getFactory().glEffectKey(effectB).
michael@0 126 */
michael@0 127 bool isEqual(const GrEffectRef& other) const {
michael@0 128 return this->isEqual(*other.get());
michael@0 129 }
michael@0 130
michael@0 131 /** Human-meaningful string to identify this effect; may be embedded
michael@0 132 in generated shader code. */
michael@0 133 const char* name() const;
michael@0 134
michael@0 135 int numTransforms() const { return fCoordTransforms.count(); }
michael@0 136
michael@0 137 /** Returns the coordinate transformation at index. index must be valid according to
michael@0 138 numTransforms(). */
michael@0 139 const GrCoordTransform& coordTransform(int index) const { return *fCoordTransforms[index]; }
michael@0 140
michael@0 141 int numTextures() const { return fTextureAccesses.count(); }
michael@0 142
michael@0 143 /** Returns the access pattern for the texture at index. index must be valid according to
michael@0 144 numTextures(). */
michael@0 145 const GrTextureAccess& textureAccess(int index) const { return *fTextureAccesses[index]; }
michael@0 146
michael@0 147 /** Shortcut for textureAccess(index).texture(); */
michael@0 148 GrTexture* texture(int index) const { return this->textureAccess(index).getTexture(); }
michael@0 149
michael@0 150 /** Will this effect read the destination pixel value? */
michael@0 151 bool willReadDstColor() const { return fWillReadDstColor; }
michael@0 152
michael@0 153 /** Will this effect read the fragment position? */
michael@0 154 bool willReadFragmentPosition() const { return fWillReadFragmentPosition; }
michael@0 155
michael@0 156 /** Will this effect emit custom vertex shader code?
michael@0 157 (To set this value the effect must inherit from GrVertexEffect.) */
michael@0 158 bool hasVertexCode() const { return fHasVertexCode; }
michael@0 159
michael@0 160 int numVertexAttribs() const {
michael@0 161 SkASSERT(0 == fVertexAttribTypes.count() || fHasVertexCode);
michael@0 162 return fVertexAttribTypes.count();
michael@0 163 }
michael@0 164
michael@0 165 GrSLType vertexAttribType(int index) const { return fVertexAttribTypes[index]; }
michael@0 166
michael@0 167 static const int kMaxVertexAttribs = 2;
michael@0 168
michael@0 169 /** Useful for effects that want to insert a texture matrix that is implied by the texture
michael@0 170 dimensions */
michael@0 171 static inline SkMatrix MakeDivByTextureWHMatrix(const GrTexture* texture) {
michael@0 172 SkASSERT(NULL != texture);
michael@0 173 SkMatrix mat;
michael@0 174 mat.setIDiv(texture->width(), texture->height());
michael@0 175 return mat;
michael@0 176 }
michael@0 177
michael@0 178 void* operator new(size_t size);
michael@0 179 void operator delete(void* target);
michael@0 180
michael@0 181 void* operator new(size_t size, void* placement) {
michael@0 182 return ::operator new(size, placement);
michael@0 183 }
michael@0 184 void operator delete(void* target, void* placement) {
michael@0 185 ::operator delete(target, placement);
michael@0 186 }
michael@0 187
michael@0 188 /** These functions are used when recording effects into a deferred drawing queue. The inc call
michael@0 189 keeps the effect alive outside of GrEffectRef while allowing any resources owned by the
michael@0 190 effect to be returned to the cache for reuse. The dec call must balance the inc call. */
michael@0 191 void incDeferredRefCounts() const {
michael@0 192 this->ref();
michael@0 193 int count = fTextureAccesses.count();
michael@0 194 for (int t = 0; t < count; ++t) {
michael@0 195 fTextureAccesses[t]->getTexture()->incDeferredRefCount();
michael@0 196 }
michael@0 197 }
michael@0 198 void decDeferredRefCounts() const {
michael@0 199 int count = fTextureAccesses.count();
michael@0 200 for (int t = 0; t < count; ++t) {
michael@0 201 fTextureAccesses[t]->getTexture()->decDeferredRefCount();
michael@0 202 }
michael@0 203 this->unref();
michael@0 204 }
michael@0 205
michael@0 206 protected:
michael@0 207 /**
michael@0 208 * Subclasses call this from their constructor to register coordinate transformations. The
michael@0 209 * effect subclass manages the lifetime of the transformations (this function only stores a
michael@0 210 * pointer). The GrCoordTransform is typically a member field of the GrEffect subclass. When the
michael@0 211 * matrix has perspective, the transformed coordinates will have 3 components. Otherwise they'll
michael@0 212 * have 2. This must only be called from the constructor because GrEffects are immutable.
michael@0 213 */
michael@0 214 void addCoordTransform(const GrCoordTransform* coordTransform);
michael@0 215
michael@0 216 /**
michael@0 217 * Subclasses call this from their constructor to register GrTextureAccesses. The effect
michael@0 218 * subclass manages the lifetime of the accesses (this function only stores a pointer). The
michael@0 219 * GrTextureAccess is typically a member field of the GrEffect subclass. This must only be
michael@0 220 * called from the constructor because GrEffects are immutable.
michael@0 221 */
michael@0 222 void addTextureAccess(const GrTextureAccess* textureAccess);
michael@0 223
michael@0 224 GrEffect()
michael@0 225 : fWillReadDstColor(false)
michael@0 226 , fWillReadFragmentPosition(false)
michael@0 227 , fWillUseInputColor(true)
michael@0 228 , fHasVertexCode(false)
michael@0 229 , fEffectRef(NULL) {}
michael@0 230
michael@0 231 /** This should be called by GrEffect subclass factories. See the comment on AutoEffectUnref for
michael@0 232 an example factory function. */
michael@0 233 static GrEffectRef* CreateEffectRef(GrEffect* effect) {
michael@0 234 if (NULL == effect->fEffectRef) {
michael@0 235 effect->fEffectRef = SkNEW_ARGS(GrEffectRef, (effect));
michael@0 236 } else {
michael@0 237 effect->fEffectRef->ref();
michael@0 238 }
michael@0 239 return effect->fEffectRef;
michael@0 240 }
michael@0 241
michael@0 242 static const GrEffectRef* CreateEffectRef(const GrEffect* effect) {
michael@0 243 return CreateEffectRef(const_cast<GrEffect*>(effect));
michael@0 244 }
michael@0 245
michael@0 246 /** Used by GR_CREATE_STATIC_EFFECT below */
michael@0 247 static GrEffectRef* CreateStaticEffectRef(void* refStorage, GrEffect* effect) {
michael@0 248 SkASSERT(NULL == effect->fEffectRef);
michael@0 249 effect->fEffectRef = SkNEW_PLACEMENT_ARGS(refStorage, GrEffectRef, (effect));
michael@0 250 return effect->fEffectRef;
michael@0 251 }
michael@0 252
michael@0 253
michael@0 254 /** Helper used in subclass factory functions to unref the effect after it has been wrapped in a
michael@0 255 GrEffectRef. E.g.:
michael@0 256
michael@0 257 class EffectSubclass : public GrEffect {
michael@0 258 public:
michael@0 259 GrEffectRef* Create(ParamType1 param1, ParamType2 param2, ...) {
michael@0 260 AutoEffectUnref effect(SkNEW_ARGS(EffectSubclass, (param1, param2, ...)));
michael@0 261 return CreateEffectRef(effect);
michael@0 262 }
michael@0 263 */
michael@0 264 class AutoEffectUnref {
michael@0 265 public:
michael@0 266 AutoEffectUnref(GrEffect* effect) : fEffect(effect) { }
michael@0 267 ~AutoEffectUnref() { fEffect->unref(); }
michael@0 268 operator GrEffect*() { return fEffect; }
michael@0 269 private:
michael@0 270 GrEffect* fEffect;
michael@0 271 };
michael@0 272
michael@0 273 /** Helper for getting the GrEffect out of a GrEffectRef and down-casting to a GrEffect subclass
michael@0 274 */
michael@0 275 template <typename T>
michael@0 276 static const T& CastEffect(const GrEffect& effectRef) {
michael@0 277 return *static_cast<const T*>(&effectRef);
michael@0 278 }
michael@0 279
michael@0 280 /**
michael@0 281 * If the effect subclass will read the destination pixel value then it must call this function
michael@0 282 * from its constructor. Otherwise, when its generated backend-specific effect class attempts
michael@0 283 * to generate code that reads the destination pixel it will fail.
michael@0 284 */
michael@0 285 void setWillReadDstColor() { fWillReadDstColor = true; }
michael@0 286
michael@0 287 /**
michael@0 288 * If the effect will generate a backend-specific effect that will read the fragment position
michael@0 289 * in the FS then it must call this method from its constructor. Otherwise, the request to
michael@0 290 * access the fragment position will be denied.
michael@0 291 */
michael@0 292 void setWillReadFragmentPosition() { fWillReadFragmentPosition = true; }
michael@0 293
michael@0 294 /**
michael@0 295 * If the effect will generate a result that does not depend on the input color value then it must
michael@0 296 * call this function from its constructor. Otherwise, when its generated backend-specific code
michael@0 297 * might fail during variable binding due to unused variables.
michael@0 298 */
michael@0 299 void setWillNotUseInputColor() { fWillUseInputColor = false; }
michael@0 300
michael@0 301 private:
michael@0 302 bool isEqual(const GrEffect& other) const {
michael@0 303 if (&this->getFactory() != &other.getFactory()) {
michael@0 304 return false;
michael@0 305 }
michael@0 306 bool result = this->onIsEqual(other);
michael@0 307 #ifdef SK_DEBUG
michael@0 308 if (result) {
michael@0 309 this->assertEquality(other);
michael@0 310 }
michael@0 311 #endif
michael@0 312 return result;
michael@0 313 }
michael@0 314
michael@0 315 SkDEBUGCODE(void assertEquality(const GrEffect& other) const;)
michael@0 316
michael@0 317 /** Subclass implements this to support isEqual(). It will only be called if it is known that
michael@0 318 the two effects are of the same subclass (i.e. they return the same object from
michael@0 319 getFactory()).*/
michael@0 320 virtual bool onIsEqual(const GrEffect& other) const = 0;
michael@0 321
michael@0 322 void EffectRefDestroyed() { fEffectRef = NULL; }
michael@0 323
michael@0 324 friend class GrEffectRef; // to call EffectRefDestroyed()
michael@0 325 friend class GrEffectStage; // to rewrap GrEffect in GrEffectRef when restoring an effect-stage
michael@0 326 // from deferred state, to call isEqual on naked GrEffects, and
michael@0 327 // to inc/dec deferred ref counts.
michael@0 328 friend class GrVertexEffect; // to set fHasVertexCode and build fVertexAttribTypes.
michael@0 329
michael@0 330 SkSTArray<4, const GrCoordTransform*, true> fCoordTransforms;
michael@0 331 SkSTArray<4, const GrTextureAccess*, true> fTextureAccesses;
michael@0 332 SkSTArray<kMaxVertexAttribs, GrSLType, true> fVertexAttribTypes;
michael@0 333 bool fWillReadDstColor;
michael@0 334 bool fWillReadFragmentPosition;
michael@0 335 bool fWillUseInputColor;
michael@0 336 bool fHasVertexCode;
michael@0 337 GrEffectRef* fEffectRef;
michael@0 338
michael@0 339 typedef SkRefCnt INHERITED;
michael@0 340 };
michael@0 341
michael@0 342 inline GrEffectRef::GrEffectRef(GrEffect* effect) {
michael@0 343 SkASSERT(NULL != effect);
michael@0 344 effect->ref();
michael@0 345 fEffect = effect;
michael@0 346 }
michael@0 347
michael@0 348 /**
michael@0 349 * This creates an effect outside of the effect memory pool. The effect's destructor will be called
michael@0 350 * at global destruction time. NAME will be the name of the created GrEffectRef.
michael@0 351 */
michael@0 352 #define GR_CREATE_STATIC_EFFECT(NAME, EFFECT_CLASS, ARGS) \
michael@0 353 enum { \
michael@0 354 k_##NAME##_EffectRefOffset = GR_CT_ALIGN_UP(sizeof(EFFECT_CLASS), 8), \
michael@0 355 k_##NAME##_StorageSize = k_##NAME##_EffectRefOffset + sizeof(GrEffectRef) \
michael@0 356 }; \
michael@0 357 static SkAlignedSStorage<k_##NAME##_StorageSize> g_##NAME##_Storage; \
michael@0 358 static void* NAME##_RefLocation = (char*)g_##NAME##_Storage.get() + k_##NAME##_EffectRefOffset; \
michael@0 359 static GrEffect* NAME##_Effect SkNEW_PLACEMENT_ARGS(g_##NAME##_Storage.get(), EFFECT_CLASS, ARGS);\
michael@0 360 static SkAutoTDestroy<GrEffect> NAME##_ad(NAME##_Effect); \
michael@0 361 static GrEffectRef* NAME(GrEffect::CreateStaticEffectRef(NAME##_RefLocation, NAME##_Effect)); \
michael@0 362 static SkAutoTDestroy<GrEffectRef> NAME##_Ref_ad(NAME)
michael@0 363
michael@0 364
michael@0 365 #endif

mercurial