1d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com/* 2d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * Copyright 2012 Google Inc. 3d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * 4d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * Use of this source code is governed by a BSD-style license that can be 5d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * found in the LICENSE file. 6d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com */ 7d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 8d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com#ifndef GrGLEffectMatrix_DEFINED 9d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com#define GrGLEffectMatrix_DEFINED 10d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 11d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com#include "GrGLEffect.h" 12d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com#include "SkMatrix.h" 13d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 14d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.comclass GrTexture; 15d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 16d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com/** 178bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * This is a helper to implement a matrix in a GrGLEffect that operates on incoming coords in the 188bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * vertex shader and writes them to an attribute to be used in the fragment shader. When the input 198bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * coords in the vertex shader are local coordinates this class accounts for the coord change matrix 208bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * communicated via GrDrawEffect. The input coords may also be positions and in this case the coord 218bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * change matrix is ignored. The GrGLEffectMatrix will emit different code based on the type of 228bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * matrix and thus must contribute to the effect's key. 238bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * 248bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * This class cannot be used to apply a matrix to coordinates that come in the form of custom vertex 258bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * attributes. 26d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com */ 27d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.comclass GrGLEffectMatrix { 288bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.comprivate: 298bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com // We specialize the generated code for each of these matrix types. 308bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com enum MatrixTypes { 318bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kIdentity_MatrixType = 0, 328bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kTrans_MatrixType = 1, 338bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kNoPersp_MatrixType = 2, 348bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kGeneral_MatrixType = 3, 358bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com }; 368bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com // The key for is made up of a matrix type and a bit that indicates the source of the input 378bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com // coords. 388bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com enum { 398bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kMatrixTypeKeyBits = 2, 408bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, 418bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kPositionCoords_Flag = (1 << kMatrixTypeKeyBits), 428bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kKeyBitsPrivate = kMatrixTypeKeyBits + 1, 438bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com }; 448bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com 45d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.compublic: 468bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com 478bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com typedef GrEffect::CoordsType CoordsType; 488bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com 49d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com typedef GrGLEffect::EffectKey EffectKey; 508bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com 51d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com /** 52d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * The matrix uses kKeyBits of the effect's EffectKey. A GrGLEffect may place these bits at an 53d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * arbitrary shift in its final key. However, when GrGLEffectMatrix::emitCode*() code is called 54d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * the relevant bits must be in the lower kKeyBits of the key parameter. 55d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com */ 56d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com enum { 578bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com kKeyBits = kKeyBitsPrivate, 58d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com kKeyMask = (1 << kKeyBits) - 1, 59d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com }; 60d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 618bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com GrGLEffectMatrix(CoordsType coordsType) 628bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com : fUni(GrGLUniformManager::kInvalidUniformHandle) 638bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com , fCoordsType(coordsType) { 648bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com GrAssert(GrEffect::kLocal_CoordsType == coordsType || 658bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com GrEffect::kPosition_CoordsType == coordsType); 66d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com fPrevMatrix = SkMatrix::InvalidMatrix(); 67d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com } 68d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 69d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com /** 70d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * Generates the key for the portion of the code emitted by this class's emitCode() function. 71d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * Pass a texture to make GrGLEffectMatrix automatically adjust for the texture's origin. Pass 728bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * NULL when not using the EffectMatrix for a texture lookup, or if the GrGLEffect subclass 738bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * wants to handle origin adjustments in some other manner. The coords type param must match the 748bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * param that would be used to initialize GrGLEffectMatrix for the generating GrEffect. 75d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com */ 76d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com static EffectKey GenKey(const SkMatrix& effectMatrix, 778bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com const GrDrawEffect&, 788bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com CoordsType, 79d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const GrTexture*); 80d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 81d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com /** 82d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * Emits code to implement the matrix in the VS. A varying is added as an output of the VS and 83d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * input to the FS. The varying may be either a vec2f or vec3f depending upon whether 84d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * perspective interpolation is required or not. The names of the varying in the VS and FS are 85d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * are returned as output parameters and the type of the varying is the return value. The suffix 86d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * is an optional parameter that can be used to make all variables emitted by the object 87d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * unique within a stage. It is only necessary if multiple GrGLEffectMatrix objects are used by 88d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * a GrGLEffect. 89d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com */ 90d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com GrSLType emitCode(GrGLShaderBuilder*, 91d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com EffectKey, 92d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const char** fsCoordName, /* optional */ 93d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const char** vsCoordName = NULL, 94d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const char* suffix = NULL); 95d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 96d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com /** 97d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * This is similar to emitCode except that it performs perspective division in the FS if the 98d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com * texture coordinates have a w coordinate. The fsCoordName always refers to a vec2f. 99d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com */ 100d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com void emitCodeMakeFSCoords2D(GrGLShaderBuilder*, 101d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com EffectKey, 102d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const char** fsCoordName, /* optional */ 103d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const char** vsVaryingName = NULL, 104d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com GrSLType* vsVaryingType = NULL, 105d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const char* suffix = NULL); 106d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com /** 1078bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * Call from a GrGLEffect's subclass to update the texture matrix. The effectMatrix and texture 1088bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com * params should match those used with GenKey. 109d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com */ 110d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com void setData(const GrGLUniformManager& uniformManager, 111d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const SkMatrix& effectMatrix, 1128bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com const GrDrawEffect& drawEffect, 113d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com const GrTexture*); 114d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 115d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com GrGLUniformManager::UniformHandle fUni; 116d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com GrSLType fUniType; 117d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com SkMatrix fPrevMatrix; 1188bc9236bf27d711cc7fe5cd618b02d29d7c59881bsalomon@google.com CoordsType fCoordsType; 119d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com}; 120d2a97043a9a9a8a389afc7c551e76586a3cc93afbsalomon@google.com 1213a729be1ae6a0bdfb6a8745f1859e8cb7f23baddbsalomon@google.com#endif 122