gfx/skia/trunk/src/gpu/effects/GrTextureDomain.cpp

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 #include "GrTextureDomain.h"
michael@0 9 #include "GrSimpleTextureEffect.h"
michael@0 10 #include "GrTBackendEffectFactory.h"
michael@0 11 #include "gl/GrGLEffect.h"
michael@0 12 #include "SkFloatingPoint.h"
michael@0 13
michael@0 14
michael@0 15 GrTextureDomain::GrTextureDomain(const SkRect& domain, Mode mode, int index)
michael@0 16 : fIndex(index) {
michael@0 17
michael@0 18 static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
michael@0 19 if (domain.contains(kFullRect)) {
michael@0 20 fMode = kIgnore_Mode;
michael@0 21 } else {
michael@0 22 fMode = mode;
michael@0 23 }
michael@0 24
michael@0 25 if (fMode != kIgnore_Mode) {
michael@0 26 // We don't currently handle domains that are empty or don't intersect the texture.
michael@0 27 // It is OK if the domain rect is a line or point, but it should not be inverted. We do not
michael@0 28 // handle rects that do not intersect the [0..1]x[0..1] rect.
michael@0 29 SkASSERT(domain.fLeft <= domain.fRight);
michael@0 30 SkASSERT(domain.fTop <= domain.fBottom);
michael@0 31 fDomain.fLeft = SkMaxScalar(domain.fLeft, kFullRect.fLeft);
michael@0 32 fDomain.fRight = SkMinScalar(domain.fRight, kFullRect.fRight);
michael@0 33 fDomain.fTop = SkMaxScalar(domain.fTop, kFullRect.fTop);
michael@0 34 fDomain.fBottom = SkMinScalar(domain.fBottom, kFullRect.fBottom);
michael@0 35 SkASSERT(fDomain.fLeft <= fDomain.fRight);
michael@0 36 SkASSERT(fDomain.fTop <= fDomain.fBottom);
michael@0 37 }
michael@0 38 }
michael@0 39
michael@0 40 //////////////////////////////////////////////////////////////////////////////
michael@0 41
michael@0 42 void GrTextureDomain::GLDomain::sampleTexture(GrGLShaderBuilder* builder,
michael@0 43 const GrTextureDomain& textureDomain,
michael@0 44 const char* outColor,
michael@0 45 const SkString& inCoords,
michael@0 46 const GrGLEffect::TextureSampler sampler,
michael@0 47 const char* inModulateColor) {
michael@0 48 SkASSERT((Mode)-1 == fMode || textureDomain.mode() == fMode);
michael@0 49 SkDEBUGCODE(fMode = textureDomain.mode();)
michael@0 50
michael@0 51 if (kIgnore_Mode == textureDomain.mode()) {
michael@0 52 builder->fsCodeAppendf("\t%s = ", outColor);
michael@0 53 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler,
michael@0 54 inCoords.c_str());
michael@0 55 builder->fsCodeAppend(";\n");
michael@0 56 return;
michael@0 57 }
michael@0 58
michael@0 59 if (!fDomainUni.isValid()) {
michael@0 60 const char* name;
michael@0 61 SkString uniName("TexDom");
michael@0 62 if (textureDomain.fIndex >= 0) {
michael@0 63 uniName.appendS32(textureDomain.fIndex);
michael@0 64 }
michael@0 65 fDomainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
michael@0 66 kVec4f_GrSLType, uniName.c_str(), &name);
michael@0 67 fDomainName = name;
michael@0 68 }
michael@0 69 if (kClamp_Mode == textureDomain.mode()) {
michael@0 70 SkString clampedCoords;
michael@0 71 clampedCoords.appendf("\tclamp(%s, %s.xy, %s.zw)",
michael@0 72 inCoords.c_str(), fDomainName.c_str(), fDomainName.c_str());
michael@0 73
michael@0 74 builder->fsCodeAppendf("\t%s = ", outColor);
michael@0 75 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, clampedCoords.c_str());
michael@0 76 builder->fsCodeAppend(";\n");
michael@0 77 } else {
michael@0 78 SkASSERT(GrTextureDomain::kDecal_Mode == textureDomain.mode());
michael@0 79 // Add a block since we're going to declare variables.
michael@0 80 GrGLShaderBuilder::FSBlock block(builder);
michael@0 81
michael@0 82 const char* domain = fDomainName.c_str();
michael@0 83 if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
michael@0 84 // On the NexusS and GalaxyNexus, the other path (with the 'any'
michael@0 85 // call) causes the compilation error "Calls to any function that
michael@0 86 // may require a gradient calculation inside a conditional block
michael@0 87 // may return undefined results". This appears to be an issue with
michael@0 88 // the 'any' call since even the simple "result=black; if (any())
michael@0 89 // result=white;" code fails to compile.
michael@0 90 builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
michael@0 91 builder->fsCodeAppend("\tvec4 inside = ");
michael@0 92 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str());
michael@0 93 builder->fsCodeAppend(";\n");
michael@0 94
michael@0 95 builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n",
michael@0 96 inCoords.c_str(), domain, domain, domain);
michael@0 97 builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n",
michael@0 98 inCoords.c_str(), domain, domain, domain);
michael@0 99 builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n");
michael@0 100 builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outColor);
michael@0 101 } else {
michael@0 102 builder->fsCodeAppend("\tbvec4 outside;\n");
michael@0 103 builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", inCoords.c_str(),
michael@0 104 domain);
michael@0 105 builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", inCoords.c_str(),
michael@0 106 domain);
michael@0 107 builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outColor);
michael@0 108 builder->fsAppendTextureLookupAndModulate(inModulateColor, sampler, inCoords.c_str());
michael@0 109 builder->fsCodeAppend(";\n");
michael@0 110 }
michael@0 111 }
michael@0 112 }
michael@0 113
michael@0 114 void GrTextureDomain::GLDomain::setData(const GrGLUniformManager& uman,
michael@0 115 const GrTextureDomain& textureDomain,
michael@0 116 GrSurfaceOrigin textureOrigin) {
michael@0 117 SkASSERT(textureDomain.mode() == fMode);
michael@0 118 if (kIgnore_Mode != textureDomain.mode()) {
michael@0 119 GrGLfloat values[4] = {
michael@0 120 SkScalarToFloat(textureDomain.domain().left()),
michael@0 121 SkScalarToFloat(textureDomain.domain().top()),
michael@0 122 SkScalarToFloat(textureDomain.domain().right()),
michael@0 123 SkScalarToFloat(textureDomain.domain().bottom())
michael@0 124 };
michael@0 125 // vertical flip if necessary
michael@0 126 if (kBottomLeft_GrSurfaceOrigin == textureOrigin) {
michael@0 127 values[1] = 1.0f - values[1];
michael@0 128 values[3] = 1.0f - values[3];
michael@0 129 // The top and bottom were just flipped, so correct the ordering
michael@0 130 // of elements so that values = (l, t, r, b).
michael@0 131 SkTSwap(values[1], values[3]);
michael@0 132 }
michael@0 133 if (0 != memcmp(values, fPrevDomain, 4 * sizeof(GrGLfloat))) {
michael@0 134 uman.set4fv(fDomainUni, 1, values);
michael@0 135 memcpy(fPrevDomain, values, 4 * sizeof(GrGLfloat));
michael@0 136 }
michael@0 137 }
michael@0 138 }
michael@0 139
michael@0 140
michael@0 141 //////////////////////////////////////////////////////////////////////////////
michael@0 142
michael@0 143 class GrGLTextureDomainEffect : public GrGLEffect {
michael@0 144 public:
michael@0 145 GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
michael@0 146
michael@0 147 virtual void emitCode(GrGLShaderBuilder*,
michael@0 148 const GrDrawEffect&,
michael@0 149 EffectKey,
michael@0 150 const char* outputColor,
michael@0 151 const char* inputColor,
michael@0 152 const TransformedCoordsArray&,
michael@0 153 const TextureSamplerArray&) SK_OVERRIDE;
michael@0 154
michael@0 155 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
michael@0 156
michael@0 157 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
michael@0 158
michael@0 159 private:
michael@0 160 GrTextureDomain::GLDomain fGLDomain;
michael@0 161 typedef GrGLEffect INHERITED;
michael@0 162 };
michael@0 163
michael@0 164 GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory,
michael@0 165 const GrDrawEffect&)
michael@0 166 : INHERITED(factory) {
michael@0 167 }
michael@0 168
michael@0 169 void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
michael@0 170 const GrDrawEffect& drawEffect,
michael@0 171 EffectKey key,
michael@0 172 const char* outputColor,
michael@0 173 const char* inputColor,
michael@0 174 const TransformedCoordsArray& coords,
michael@0 175 const TextureSamplerArray& samplers) {
michael@0 176 const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainEffect>();
michael@0 177 const GrTextureDomain& domain = effect.textureDomain();
michael@0 178
michael@0 179 SkString coords2D = builder->ensureFSCoords2D(coords, 0);
michael@0 180 fGLDomain.sampleTexture(builder, domain, outputColor, coords2D, samplers[0], inputColor);
michael@0 181 }
michael@0 182
michael@0 183 void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman,
michael@0 184 const GrDrawEffect& drawEffect) {
michael@0 185 const GrTextureDomainEffect& effect = drawEffect.castEffect<GrTextureDomainEffect>();
michael@0 186 const GrTextureDomain& domain = effect.textureDomain();
michael@0 187 fGLDomain.setData(uman, domain, effect.texture(0)->origin());
michael@0 188 }
michael@0 189
michael@0 190 GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect,
michael@0 191 const GrGLCaps&) {
michael@0 192 const GrTextureDomain& domain = drawEffect.castEffect<GrTextureDomainEffect>().textureDomain();
michael@0 193 return GrTextureDomain::GLDomain::DomainKey(domain);
michael@0 194 }
michael@0 195
michael@0 196
michael@0 197 ///////////////////////////////////////////////////////////////////////////////
michael@0 198
michael@0 199 GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture,
michael@0 200 const SkMatrix& matrix,
michael@0 201 const SkRect& domain,
michael@0 202 GrTextureDomain::Mode mode,
michael@0 203 GrTextureParams::FilterMode filterMode,
michael@0 204 GrCoordSet coordSet) {
michael@0 205 static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
michael@0 206 if (GrTextureDomain::kIgnore_Mode == mode ||
michael@0 207 (GrTextureDomain::kClamp_Mode == mode && domain.contains(kFullRect))) {
michael@0 208 return GrSimpleTextureEffect::Create(texture, matrix, filterMode);
michael@0 209 } else {
michael@0 210
michael@0 211 AutoEffectUnref effect(SkNEW_ARGS(GrTextureDomainEffect, (texture,
michael@0 212 matrix,
michael@0 213 domain,
michael@0 214 mode,
michael@0 215 filterMode,
michael@0 216 coordSet)));
michael@0 217 return CreateEffectRef(effect);
michael@0 218
michael@0 219 }
michael@0 220 }
michael@0 221
michael@0 222 GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
michael@0 223 const SkMatrix& matrix,
michael@0 224 const SkRect& domain,
michael@0 225 GrTextureDomain::Mode mode,
michael@0 226 GrTextureParams::FilterMode filterMode,
michael@0 227 GrCoordSet coordSet)
michael@0 228 : GrSingleTextureEffect(texture, matrix, filterMode, coordSet)
michael@0 229 , fTextureDomain(domain, mode) {
michael@0 230 }
michael@0 231
michael@0 232 GrTextureDomainEffect::~GrTextureDomainEffect() {
michael@0 233
michael@0 234 }
michael@0 235
michael@0 236 const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const {
michael@0 237 return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance();
michael@0 238 }
michael@0 239
michael@0 240 bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const {
michael@0 241 const GrTextureDomainEffect& s = CastEffect<GrTextureDomainEffect>(sBase);
michael@0 242 return this->hasSameTextureParamsMatrixAndSourceCoords(s) &&
michael@0 243 this->fTextureDomain == s.fTextureDomain;
michael@0 244 }
michael@0 245
michael@0 246 void GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
michael@0 247 if (GrTextureDomain::kDecal_Mode == fTextureDomain.mode()) { // TODO: helper
michael@0 248 *validFlags = 0;
michael@0 249 } else {
michael@0 250 this->updateConstantColorComponentsForModulation(color, validFlags);
michael@0 251 }
michael@0 252 }
michael@0 253
michael@0 254 ///////////////////////////////////////////////////////////////////////////////
michael@0 255
michael@0 256 GR_DEFINE_EFFECT_TEST(GrTextureDomainEffect);
michael@0 257
michael@0 258 GrEffectRef* GrTextureDomainEffect::TestCreate(SkRandom* random,
michael@0 259 GrContext*,
michael@0 260 const GrDrawTargetCaps&,
michael@0 261 GrTexture* textures[]) {
michael@0 262 int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx :
michael@0 263 GrEffectUnitTest::kAlphaTextureIdx;
michael@0 264 SkRect domain;
michael@0 265 domain.fLeft = random->nextUScalar1();
michael@0 266 domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1);
michael@0 267 domain.fTop = random->nextUScalar1();
michael@0 268 domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
michael@0 269 GrTextureDomain::Mode mode =
michael@0 270 (GrTextureDomain::Mode) random->nextULessThan(GrTextureDomain::kModeCount);
michael@0 271 const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
michael@0 272 bool bilerp = random->nextBool();
michael@0 273 GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoordSet;
michael@0 274 return GrTextureDomainEffect::Create(textures[texIdx],
michael@0 275 matrix,
michael@0 276 domain,
michael@0 277 mode,
michael@0 278 bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode,
michael@0 279 coords);
michael@0 280 }

mercurial