GrTextureDomain.cpp revision 1aa90cf11e136a722bce71dd77f4bb03cc2b56f8
12f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com/* 22f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * Copyright 2012 Google Inc. 32f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * 42f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be 52f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com * found in the LICENSE file. 62f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com */ 72f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 82f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com#include "GrTextureDomainEffect.h" 92eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com#include "GrTBackendEffectFactory.h" 10d698f77c13d97c61109b861eac4d25b14a5de935bsalomon@google.com#include "gl/GrGLEffect.h" 1192b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com#include "gl/GrGLEffectMatrix.h" 1292b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com#include "SkFloatingPoint.h" 132f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 1422a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.comclass GrGLTextureDomainEffect : public GrGLEffect { 152f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.compublic: 16396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrEffect&); 172f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 1822a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com virtual void emitCode(GrGLShaderBuilder*, 192eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com const GrEffectStage&, 2022a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com EffectKey, 2122a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* vertexCoords, 2222a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* outputColor, 2322a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* inputColor, 2422a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const TextureSamplerArray&) SK_OVERRIDE; 252f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 2628a15fb8d603847949a61657ef5cb73ed9915021bsalomon@google.com virtual void setData(const GrGLUniformManager&, const GrEffectStage&) SK_OVERRIDE; 272f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 2892b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com static inline EffectKey GenKey(const GrEffectStage&, const GrGLCaps&); 292f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 302f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.comprivate: 31dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com GrGLUniformManager::UniformHandle fNameUni; 3292b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com GrGLEffectMatrix fEffectMatrix; 3392b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com GrGLfloat fPrevDomain[4]; 342f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 3522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com typedef GrGLEffect INHERITED; 362f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com}; 372f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 38396e61fe440590744345e0c56970b26ab464591dbsalomon@google.comGrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory, 39021fc736f89fddac4f26b3f32f50263ff8fe3279bsalomon@google.com const GrEffect&) 40374e75956e7a56bbbd2da5509f9c4117512515d2bsalomon@google.com : INHERITED(factory) 41dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com , fNameUni(GrGLUniformManager::kInvalidUniformHandle) { 4292b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com fPrevDomain[0] = SK_FloatNaN; 432f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com} 442f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 4522a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.comvoid GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder, 462eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com const GrEffectStage&, 4792b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com EffectKey key, 4822a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* vertexCoords, 4922a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* outputColor, 5022a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const char* inputColor, 5122a800a2578564a8b66bd4d9903ef4186c37f35cbsalomon@google.com const TextureSamplerArray& samplers) { 5292b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com const char* coords; 5392b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords); 5457143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.com fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 55777c3aab0a902b0917871080d99b0a249ec06298bsalomon@google.com kVec4f_GrSLType, "TexDom"); 562f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 5734bcb9f80336fe0dc56ad5f67aeb0859bf84d92ebsalomon@google.com builder->fFSCode.appendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n", 5892b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com coords, 5957143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.com builder->getUniformCStr(fNameUni), 6057143a2d87ef5fb7276ffc11abaa2e77d31f0ad8tomhudson@google.com builder->getUniformCStr(fNameUni)); 612f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 62868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com builder->fFSCode.appendf("\t%s = ", outputColor); 63f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com builder->appendTextureLookupAndModulate(&builder->fFSCode, 64f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com inputColor, 65f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com samplers[0], 66f06df1bb9ab201a78bfc906a9e95326c6e15a119bsalomon@google.com "clampCoord"); 67868a8e7fc83e9ac6ee1418e75b84a0595605626cbsalomon@google.com builder->fFSCode.append(";\n"); 682f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com} 692f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 7028a15fb8d603847949a61657ef5cb73ed9915021bsalomon@google.comvoid GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) { 7128a15fb8d603847949a61657ef5cb73ed9915021bsalomon@google.com const GrTextureDomainEffect& effect = 7228a15fb8d603847949a61657ef5cb73ed9915021bsalomon@google.com static_cast<const GrTextureDomainEffect&>(*stage.getEffect()); 732f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com const GrRect& domain = effect.domain(); 742f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 752f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com float values[4] = { 7681712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalarToFloat(domain.left()), 7781712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalarToFloat(domain.top()), 7881712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalarToFloat(domain.right()), 7981712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com SkScalarToFloat(domain.bottom()) 802f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com }; 812f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com // vertical flip if necessary 822d0baded0f45dfde9dc8c25313ff14ea18c0c915bsalomon@google.com if (GrSurface::kBottomLeft_Origin == effect.texture(0)->origin()) { 832f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com values[1] = 1.0f - values[1]; 842f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com values[3] = 1.0f - values[3]; 852f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com // The top and bottom were just flipped, so correct the ordering 862f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com // of elements so that values = (l, t, r, b). 872f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com SkTSwap(values[1], values[3]); 882f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com } 8992b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com if (0 != memcmp(values, fPrevDomain, 4 * sizeof(GrGLfloat))) { 9092b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com uman.set4fv(fNameUni, 0, 1, values); 9192b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com } 9292b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com fEffectMatrix.setData(uman, 9392b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com effect.getMatrix(), 9492b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com stage.getCoordChangeMatrix(), 9592b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com effect.texture(0)); 961aa90cf11e136a722bce71dd77f4bb03cc2b56f8skia.committer@gmail.com} 9792b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com 9892b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.comGrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrEffectStage& stage, const GrGLCaps&) { 9992b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com const GrTextureDomainEffect& effect = 10092b6a94ac103ea3f37a8f9f02072ef884cc17a7cbsalomon@google.com static_cast<const GrTextureDomainEffect&>(*stage.getEffect()); 10131ca955c0611712528c0897928bf3b1100be2fcdbsalomon@google.com return GrGLEffectMatrix::GenKey(effect.getMatrix(), stage.getCoordChangeMatrix(), effect.texture(0)); 1022f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com} 1032f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 1042f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 1052f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com/////////////////////////////////////////////////////////////////////////////// 1062f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 1071ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.comGrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, const GrRect& domain) 1082f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com : GrSingleTextureEffect(texture) 1092f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com , fTextureDomain(domain) { 1102f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com} 1112f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 1121ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.comGrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, 1131ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com const GrRect& domain, 1141ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com const GrTextureParams& params) 1151ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com : GrSingleTextureEffect(texture, params) 1161ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com , fTextureDomain(domain) { 1171ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com} 1181ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com 1192f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.comGrTextureDomainEffect::~GrTextureDomainEffect() { 1202f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 1212f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com} 1222f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 123396e61fe440590744345e0c56970b26ab464591dbsalomon@google.comconst GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const { 124396e61fe440590744345e0c56970b26ab464591dbsalomon@google.com return GrTBackendEffectFactory<GrTextureDomainEffect>::getInstance(); 1252f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com} 1262f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com 127a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.combool GrTextureDomainEffect::isEqual(const GrEffect& sBase) const { 1282f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com const GrTextureDomainEffect& s = static_cast<const GrTextureDomainEffect&>(sBase); 1292f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com return (INHERITED::isEqual(sBase) && this->fTextureDomain == s.fTextureDomain); 1302f68e7684bb2ecdf0c03a513c31d0626d2caf752tomhudson@google.com} 1310a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com 1320a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com/////////////////////////////////////////////////////////////////////////////// 1330a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com 134f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.comGR_DEFINE_EFFECT_TEST(GrTextureDomainEffect); 1350a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com 136a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.comGrEffect* GrTextureDomainEffect::TestCreate(SkRandom* random, 137a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com GrContext* context, 138a469c28c3c16214733a25201a286970f57b3d944bsalomon@google.com GrTexture* textures[]) { 1396f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : 1406f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com GrEffectUnitTest::kAlphaTextureIdx; 1410a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com GrRect domain; 1420a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com domain.fLeft = random->nextUScalar1(); 1430a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1); 1440a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com domain.fTop = random->nextUScalar1(); 1450a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1); 1460a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com return SkNEW_ARGS(GrTextureDomainEffect, (textures[texIdx], domain)); 1470a7672f85ef7655b343679609d02018f83fcfc23bsalomon@google.com} 148