ProgramCache.h revision 06f96e2652e4855b6520ad9dd70583677605b79a
1ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/*
2ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * Copyright (C) 2010 The Android Open Source Project
3ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy *
4ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * you may not use this file except in compliance with the License.
6ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * You may obtain a copy of the License at
7ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy *
8ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy *
10ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * Unless required by applicable law or agreed to in writing, software
11ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * See the License for the specific language governing permissions and
14ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * limitations under the License.
15ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy */
16ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
17ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#ifndef ANDROID_UI_PROGRAM_CACHE_H
18ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define ANDROID_UI_PROGRAM_CACHE_H
19ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
20ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#include <utils/KeyedVector.h>
21ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#include <utils/Log.h>
2206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include <utils/String8.h>
23ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
24889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy#include <GLES2/gl2.h>
25889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy
26ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#include <SkXfermode.h>
27ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
28ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#include "Program.h"
29ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
30ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guynamespace android {
31ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guynamespace uirenderer {
32ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
33ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy///////////////////////////////////////////////////////////////////////////////
34ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Defines
35ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy///////////////////////////////////////////////////////////////////////////////
36ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
37ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Debug
38889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy#define DEBUG_PROGRAM_CACHE 1
39ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
40ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Debug
41ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#if DEBUG_PROGRAM_CACHE
42ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    #define PROGRAM_LOGD(...) LOGD(__VA_ARGS__)
43ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#else
44ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    #define PROGRAM_LOGD(...)
45ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#endif
46ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
47ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_KEY_TEXTURE 0x1
48ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_KEY_A8_TEXTURE 0x2
49ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_KEY_BITMAP 0x4
50ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_KEY_GRADIENT 0x8
51ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_KEY_BITMAP_FIRST 0x10
52ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_KEY_COLOR_MATRIX 0x20
53ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_KEY_COLOR_LIGHTING 0x40
54ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_KEY_COLOR_BLEND 0x80
55889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy#define PROGRAM_KEY_BITMAP_NPOT 0x100
56889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy
57889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
58889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
59ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
60ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Support only the 12 Porter-Duff modes for now
61ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_MAX_XFERMODE 0xC
62ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_XFERMODE_SHADER_SHIFT 24
63ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
64ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
65889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy#define PROGRAM_BITMAP_WRAPS_SHIFT 9
66889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy#define PROGRAM_BITMAP_WRAPT_SHIFT 11
67889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy
68ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy///////////////////////////////////////////////////////////////////////////////
69ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Types
70ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy///////////////////////////////////////////////////////////////////////////////
71ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
72ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guytypedef uint32_t programid;
73ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
74ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy///////////////////////////////////////////////////////////////////////////////
75ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Cache
76ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy///////////////////////////////////////////////////////////////////////////////
77ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
78ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/**
79ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * Describe the features required for a given program. The features
80ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * determine the generation of both the vertex and fragment shaders.
81ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * A ProgramDescription must be used in conjunction with a ProgramCache.
82ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy */
83ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guystruct ProgramDescription {
84ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    enum ColorModifier {
85ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        kColorNone,
86ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        kColorMatrix,
87ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        kColorLighting,
88ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        kColorBlend
89ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    };
90ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
91ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    ProgramDescription():
92ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        hasTexture(false), hasAlpha8Texture(false),
93889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        hasBitmap(false), isBitmapNpot(false), hasGradient(false),
94889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false),
95889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE),
96ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode) {
97ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    }
98ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
99ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    // Texturing
100ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    bool hasTexture;
101ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    bool hasAlpha8Texture;
102ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
103ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    // Shaders
104ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    bool hasBitmap;
105889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    bool isBitmapNpot;
106ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    bool hasGradient;
107ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    SkXfermode::Mode shadersMode;
108ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    bool isBitmapFirst;
109889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    GLenum bitmapWrapS;
110889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    GLenum bitmapWrapT;
111ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
112ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    // Color operations
113ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    int colorOp;
114ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    SkXfermode::Mode colorMode;
115ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
116889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    inline uint32_t getEnumForWrap(GLenum wrap) const {
117889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        switch (wrap) {
118889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy            case GL_CLAMP_TO_EDGE:
119889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy                return 0;
120889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy            case GL_REPEAT:
121889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy                return 1;
122889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy            case GL_MIRRORED_REPEAT:
123889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy                return 2;
124889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        }
125889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        return 0;
126889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    }
127889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy
128ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    programid key() const {
129ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        programid key = 0;
130ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        if (hasTexture) key |= PROGRAM_KEY_TEXTURE;
131ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
132889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        if (hasBitmap) {
133889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy            key |= PROGRAM_KEY_BITMAP;
134889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy            if (isBitmapNpot) {
135889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy                key |= PROGRAM_KEY_BITMAP_NPOT;
136889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy                key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT;
137889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy                key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT;
138889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy            }
139889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy        }
140ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        if (hasGradient) key |= PROGRAM_KEY_GRADIENT;
141ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        if (isBitmapFirst) key  |= PROGRAM_KEY_BITMAP_FIRST;
142ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        if (hasBitmap && hasGradient) {
143ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy            key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
144ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        }
145ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        switch (colorOp) {
146ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy            case kColorMatrix:
147ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy                key |= PROGRAM_KEY_COLOR_MATRIX;
148ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy                break;
149ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy            case kColorLighting:
150ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy                key |= PROGRAM_KEY_COLOR_LIGHTING;
151ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy                break;
152ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy            case kColorBlend:
153ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy                key |= PROGRAM_KEY_COLOR_BLEND;
154ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy                key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
155ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy                break;
156ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy            case kColorNone:
157ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy                break;
158ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        }
159ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy        return key;
160ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    }
161ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; // struct ProgramDescription
162ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
163ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/**
164ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * Generates and caches program. Programs are generated based on
165ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * ProgramDescriptions.
166ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy */
167ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyclass ProgramCache {
168ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guypublic:
169ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    ProgramCache();
170ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    ~ProgramCache();
171ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
172ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    Program* get(const ProgramDescription& description);
173ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
174ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    void clear();
175ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
176ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyprivate:
177ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    Program* generateProgram(const ProgramDescription& description, programid key);
178ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    String8 generateVertexShader(const ProgramDescription& description);
179ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    String8 generateFragmentShader(const ProgramDescription& description);
180ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    void generatePorterDuffBlend(String8& shader, const char* name, SkXfermode::Mode mode);
181889f8d1403761d5668115ced6cbb3f767cfe966dRomain Guy    void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT);
182ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
183ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy    KeyedVector<programid, Program*> mCache;
184ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
185ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; // class ProgramCache
186ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
187ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; // namespace uirenderer
188ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; // namespace android
189ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy
190ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#endif // ANDROID_UI_PROGRAM_CACHE_H
191