• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2010 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  #ifndef ANDROID_HWUI_PROGRAM_H
18  #define ANDROID_HWUI_PROGRAM_H
19  
20  #include <utils/KeyedVector.h>
21  
22  #include <GLES2/gl2.h>
23  #include <GLES2/gl2ext.h>
24  
25  #include <SkXfermode.h>
26  
27  #include "Matrix.h"
28  #include "Properties.h"
29  
30  namespace android {
31  namespace uirenderer {
32  
33  ///////////////////////////////////////////////////////////////////////////////
34  // Defines
35  ///////////////////////////////////////////////////////////////////////////////
36  
37  // Debug
38  #if DEBUG_PROGRAMS
39      #define PROGRAM_LOGD(...) ALOGD(__VA_ARGS__)
40  #else
41      #define PROGRAM_LOGD(...)
42  #endif
43  
44  #define COLOR_COMPONENT_THRESHOLD (1.0f - (0.5f / PANEL_BIT_DEPTH))
45  #define COLOR_COMPONENT_INV_THRESHOLD (0.5f / PANEL_BIT_DEPTH)
46  
47  #define PROGRAM_KEY_TEXTURE 0x1
48  #define PROGRAM_KEY_A8_TEXTURE 0x2
49  #define PROGRAM_KEY_BITMAP 0x4
50  #define PROGRAM_KEY_GRADIENT 0x8
51  #define PROGRAM_KEY_BITMAP_FIRST 0x10
52  #define PROGRAM_KEY_COLOR_MATRIX 0x20
53  #define PROGRAM_KEY_COLOR_LIGHTING 0x40
54  #define PROGRAM_KEY_COLOR_BLEND 0x80
55  #define PROGRAM_KEY_BITMAP_NPOT 0x100
56  #define PROGRAM_KEY_SWAP_SRC_DST 0x2000
57  
58  #define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
59  #define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
60  
61  // Encode the xfermodes on 6 bits
62  #define PROGRAM_MAX_XFERMODE 0x1f
63  #define PROGRAM_XFERMODE_SHADER_SHIFT 26
64  #define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
65  #define PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT 14
66  
67  #define PROGRAM_BITMAP_WRAPS_SHIFT 9
68  #define PROGRAM_BITMAP_WRAPT_SHIFT 11
69  
70  #define PROGRAM_GRADIENT_TYPE_SHIFT 33
71  #define PROGRAM_MODULATE_SHIFT 35
72  
73  #define PROGRAM_IS_POINT_SHIFT 36
74  
75  #define PROGRAM_HAS_AA_SHIFT 37
76  
77  #define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 38
78  #define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 39
79  
80  ///////////////////////////////////////////////////////////////////////////////
81  // Types
82  ///////////////////////////////////////////////////////////////////////////////
83  
84  typedef uint64_t programid;
85  
86  ///////////////////////////////////////////////////////////////////////////////
87  // Program description
88  ///////////////////////////////////////////////////////////////////////////////
89  
90  /**
91   * Describe the features required for a given program. The features
92   * determine the generation of both the vertex and fragment shaders.
93   * A ProgramDescription must be used in conjunction with a ProgramCache.
94   */
95  struct ProgramDescription {
96      enum ColorModifier {
97          kColorNone,
98          kColorMatrix,
99          kColorLighting,
100          kColorBlend
101      };
102  
103      enum Gradient {
104          kGradientLinear,
105          kGradientCircular,
106          kGradientSweep
107      };
108  
ProgramDescriptionProgramDescription109      ProgramDescription() {
110          reset();
111      }
112  
113      // Texturing
114      bool hasTexture;
115      bool hasAlpha8Texture;
116      bool hasExternalTexture;
117      bool hasTextureTransform;
118  
119      // Modulate, this should only be set when setColor() return true
120      bool modulate;
121  
122      // Shaders
123      bool hasBitmap;
124      bool isBitmapNpot;
125  
126      bool isAA;
127  
128      bool hasGradient;
129      Gradient gradientType;
130  
131      SkXfermode::Mode shadersMode;
132  
133      bool isBitmapFirst;
134      GLenum bitmapWrapS;
135      GLenum bitmapWrapT;
136  
137      // Color operations
138      ColorModifier colorOp;
139      SkXfermode::Mode colorMode;
140  
141      // Framebuffer blending (requires Extensions.hasFramebufferFetch())
142      // Ignored for all values < SkXfermode::kPlus_Mode
143      SkXfermode::Mode framebufferMode;
144      bool swapSrcDst;
145  
146      bool isPoint;
147      float pointSize;
148  
149      /**
150       * Resets this description. All fields are reset back to the default
151       * values they hold after building a new instance.
152       */
resetProgramDescription153      void reset() {
154          hasTexture = false;
155          hasAlpha8Texture = false;
156          hasExternalTexture = false;
157          hasTextureTransform = false;
158  
159          isAA = false;
160  
161          modulate = false;
162  
163          hasBitmap = false;
164          isBitmapNpot = false;
165  
166          hasGradient = false;
167          gradientType = kGradientLinear;
168  
169          shadersMode = SkXfermode::kClear_Mode;
170  
171          isBitmapFirst = false;
172          bitmapWrapS = GL_CLAMP_TO_EDGE;
173          bitmapWrapT = GL_CLAMP_TO_EDGE;
174  
175          colorOp = kColorNone;
176          colorMode = SkXfermode::kClear_Mode;
177  
178          framebufferMode = SkXfermode::kClear_Mode;
179          swapSrcDst = false;
180  
181          isPoint = false;
182          pointSize = 0.0f;
183      }
184  
185      /**
186       * Indicates, for a given color, whether color modulation is required in
187       * the fragment shader. When this method returns true, the program should
188       * be provided with a modulation color.
189       */
setColorProgramDescription190      bool setColor(const float r, const float g, const float b, const float a) {
191          modulate = a < COLOR_COMPONENT_THRESHOLD || r < COLOR_COMPONENT_THRESHOLD ||
192                  g < COLOR_COMPONENT_THRESHOLD || b < COLOR_COMPONENT_THRESHOLD;
193          return modulate;
194      }
195  
196      /**
197       * Indicates, for a given color, whether color modulation is required in
198       * the fragment shader. When this method returns true, the program should
199       * be provided with a modulation color.
200       */
setAlpha8ColorProgramDescription201      bool setAlpha8Color(const float r, const float g, const float b, const float a) {
202          modulate = a < COLOR_COMPONENT_THRESHOLD || r > COLOR_COMPONENT_INV_THRESHOLD ||
203                  g > COLOR_COMPONENT_INV_THRESHOLD || b > COLOR_COMPONENT_INV_THRESHOLD;
204          return modulate;
205      }
206  
207      /**
208       * Computes the unique key identifying this program.
209       */
keyProgramDescription210      programid key() const {
211          programid key = 0;
212          if (hasTexture) key |= PROGRAM_KEY_TEXTURE;
213          if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
214          if (hasBitmap) {
215              key |= PROGRAM_KEY_BITMAP;
216              if (isBitmapNpot) {
217                  key |= PROGRAM_KEY_BITMAP_NPOT;
218                  key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT;
219                  key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT;
220              }
221          }
222          if (hasGradient) key |= PROGRAM_KEY_GRADIENT;
223          key |= programid(gradientType) << PROGRAM_GRADIENT_TYPE_SHIFT;
224          if (isBitmapFirst) key |= PROGRAM_KEY_BITMAP_FIRST;
225          if (hasBitmap && hasGradient) {
226              key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
227          }
228          switch (colorOp) {
229              case kColorMatrix:
230                  key |= PROGRAM_KEY_COLOR_MATRIX;
231                  break;
232              case kColorLighting:
233                  key |= PROGRAM_KEY_COLOR_LIGHTING;
234                  break;
235              case kColorBlend:
236                  key |= PROGRAM_KEY_COLOR_BLEND;
237                  key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
238                  break;
239              case kColorNone:
240                  break;
241          }
242          key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
243          if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
244          if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
245          if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT;
246          if (isAA) key |= programid(0x1) << PROGRAM_HAS_AA_SHIFT;
247          if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT;
248          if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
249          return key;
250      }
251  
252      /**
253       * Logs the specified message followed by the key identifying this program.
254       */
logProgramDescription255      void log(const char* message) const {
256  #if DEBUG_PROGRAMS
257          programid k = key();
258          PROGRAM_LOGD("%s (key = 0x%.8x%.8x)", message, uint32_t(k >> 32),
259                  uint32_t(k & 0xffffffff));
260  #endif
261      }
262  
263  private:
getEnumForWrapProgramDescription264      inline uint32_t getEnumForWrap(GLenum wrap) const {
265          switch (wrap) {
266              case GL_CLAMP_TO_EDGE:
267                  return 0;
268              case GL_REPEAT:
269                  return 1;
270              case GL_MIRRORED_REPEAT:
271                  return 2;
272          }
273          return 0;
274      }
275  
276  }; // struct ProgramDescription
277  
278  /**
279   * A program holds a vertex and a fragment shader. It offers several utility
280   * methods to query attributes and uniforms.
281   */
282  class Program {
283  public:
284      enum ShaderBindings {
285          kBindingPosition,
286          kBindingTexCoords
287      };
288  
289      /**
290       * Creates a new program with the specified vertex and fragment
291       * shaders sources.
292       */
293      Program(const ProgramDescription& description, const char* vertex, const char* fragment);
294      virtual ~Program();
295  
296      /**
297       * Binds this program to the GL context.
298       */
299      virtual void use();
300  
301      /**
302       * Marks this program as unused. This will not unbind
303       * the program from the GL context.
304       */
305      virtual void remove();
306  
307      /**
308       * Returns the OpenGL name of the specified attribute.
309       */
310      int getAttrib(const char* name);
311  
312      /**
313       * Returns the OpenGL name of the specified uniform.
314       */
315      int getUniform(const char* name);
316  
317      /**
318       * Indicates whether this program is currently in use with
319       * the GL context.
320       */
isInUse()321      inline bool isInUse() const {
322          return mUse;
323      }
324  
325      /**
326       * Indicates whether this program was correctly compiled and linked.
327       */
isInitialized()328      inline bool isInitialized() const {
329          return mInitialized;
330      }
331  
332      /**
333       * Binds the program with the specified projection, modelView and
334       * transform matrices.
335       */
336      void set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
337               const mat4& transformMatrix, bool offset = false);
338  
339      /**
340       * Sets the color associated with this shader.
341       */
342      void setColor(const float r, const float g, const float b, const float a);
343  
344      /**
345       * Name of the position attribute.
346       */
347      int position;
348  
349      /**
350       * Name of the texCoords attribute if it exists, -1 otherwise.
351       */
352      int texCoords;
353  
354      /**
355       * Name of the transform uniform.
356       */
357      int transform;
358  
359  protected:
360      /**
361       * Adds an attribute with the specified name.
362       *
363       * @return The OpenGL name of the attribute.
364       */
365      int addAttrib(const char* name);
366  
367      /**
368       * Binds the specified attribute name to the specified slot.
369       */
370      int bindAttrib(const char* name, ShaderBindings bindingSlot);
371  
372      /**
373       * Adds a uniform with the specified name.
374       *
375       * @return The OpenGL name of the uniform.
376       */
377      int addUniform(const char* name);
378  
379  private:
380      /**
381       * Compiles the specified shader of the specified type.
382       *
383       * @return The name of the compiled shader.
384       */
385      GLuint buildShader(const char* source, GLenum type);
386  
387      // Name of the OpenGL program and shaders
388      GLuint mProgramId;
389      GLuint mVertexShader;
390      GLuint mFragmentShader;
391  
392      // Keeps track of attributes and uniforms slots
393      KeyedVector<const char*, int> mAttributes;
394      KeyedVector<const char*, int> mUniforms;
395  
396      bool mUse;
397      bool mInitialized;
398  
399      bool mHasColorUniform;
400      int mColorUniform;
401  
402      bool mHasSampler;
403  }; // class Program
404  
405  }; // namespace uirenderer
406  }; // namespace android
407  
408  #endif // ANDROID_HWUI_PROGRAM_H
409