xref: /aosp_15_r20/external/angle/src/libANGLE/GLES1Renderer.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2018 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // GLES1Renderer.cpp: Implements the GLES1Renderer renderer.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/GLES1Renderer.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include <string.h>
12*8975f5c5SAndroid Build Coastguard Worker #include <iterator>
13*8975f5c5SAndroid Build Coastguard Worker #include <sstream>
14*8975f5c5SAndroid Build Coastguard Worker #include <vector>
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker #include "common/hash_utils.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.inl.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Program.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ResourceManager.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Shader.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/State.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/context_private_call_autogen.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/ContextImpl.h"
25*8975f5c5SAndroid Build Coastguard Worker 
26*8975f5c5SAndroid Build Coastguard Worker namespace
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/GLES1Shaders.inc"
29*8975f5c5SAndroid Build Coastguard Worker 
GetLogicOpUniform(const gl::FramebufferAttachment * color,gl::LogicalOperation logicOp)30*8975f5c5SAndroid Build Coastguard Worker uint32_t GetLogicOpUniform(const gl::FramebufferAttachment *color, gl::LogicalOperation logicOp)
31*8975f5c5SAndroid Build Coastguard Worker {
32*8975f5c5SAndroid Build Coastguard Worker     const uint32_t red   = color->getRedSize();
33*8975f5c5SAndroid Build Coastguard Worker     const uint32_t green = color->getGreenSize();
34*8975f5c5SAndroid Build Coastguard Worker     const uint32_t blue  = color->getBlueSize();
35*8975f5c5SAndroid Build Coastguard Worker     const uint32_t alpha = color->getAlphaSize();
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker     ASSERT(red <= 8 && green <= 8 && blue <= 8 && alpha <= 8);
38*8975f5c5SAndroid Build Coastguard Worker 
39*8975f5c5SAndroid Build Coastguard Worker     return red | green << 4 | blue << 8 | alpha << 12 | static_cast<uint32_t>(logicOp) << 16;
40*8975f5c5SAndroid Build Coastguard Worker }
41*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker namespace gl
44*8975f5c5SAndroid Build Coastguard Worker {
45*8975f5c5SAndroid Build Coastguard Worker GLES1ShaderState::GLES1ShaderState()  = default;
46*8975f5c5SAndroid Build Coastguard Worker GLES1ShaderState::~GLES1ShaderState() = default;
GLES1ShaderState(const GLES1ShaderState & other)47*8975f5c5SAndroid Build Coastguard Worker GLES1ShaderState::GLES1ShaderState(const GLES1ShaderState &other)
48*8975f5c5SAndroid Build Coastguard Worker {
49*8975f5c5SAndroid Build Coastguard Worker     memcpy(this, &other, sizeof(GLES1ShaderState));
50*8975f5c5SAndroid Build Coastguard Worker }
51*8975f5c5SAndroid Build Coastguard Worker 
operator ==(const GLES1ShaderState & a,const GLES1ShaderState & b)52*8975f5c5SAndroid Build Coastguard Worker bool operator==(const GLES1ShaderState &a, const GLES1ShaderState &b)
53*8975f5c5SAndroid Build Coastguard Worker {
54*8975f5c5SAndroid Build Coastguard Worker     return memcmp(&a, &b, sizeof(GLES1ShaderState)) == 0;
55*8975f5c5SAndroid Build Coastguard Worker }
operator !=(const GLES1ShaderState & a,const GLES1ShaderState & b)56*8975f5c5SAndroid Build Coastguard Worker bool operator!=(const GLES1ShaderState &a, const GLES1ShaderState &b)
57*8975f5c5SAndroid Build Coastguard Worker {
58*8975f5c5SAndroid Build Coastguard Worker     return !(a == b);
59*8975f5c5SAndroid Build Coastguard Worker }
60*8975f5c5SAndroid Build Coastguard Worker 
hash() const61*8975f5c5SAndroid Build Coastguard Worker size_t GLES1ShaderState::hash() const
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker     return angle::ComputeGenericHash(*this);
64*8975f5c5SAndroid Build Coastguard Worker }
65*8975f5c5SAndroid Build Coastguard Worker 
GLES1Renderer()66*8975f5c5SAndroid Build Coastguard Worker GLES1Renderer::GLES1Renderer() : mRendererProgramInitialized(false) {}
67*8975f5c5SAndroid Build Coastguard Worker 
onDestroy(Context * context,State * state)68*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::onDestroy(Context *context, State *state)
69*8975f5c5SAndroid Build Coastguard Worker {
70*8975f5c5SAndroid Build Coastguard Worker     if (mRendererProgramInitialized)
71*8975f5c5SAndroid Build Coastguard Worker     {
72*8975f5c5SAndroid Build Coastguard Worker         (void)state->setProgram(context, 0);
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker         for (const auto &iter : mUberShaderState)
75*8975f5c5SAndroid Build Coastguard Worker         {
76*8975f5c5SAndroid Build Coastguard Worker             const GLES1UberShaderState &UberShaderState = iter.second;
77*8975f5c5SAndroid Build Coastguard Worker             mShaderPrograms->deleteProgram(context, {UberShaderState.programState.program});
78*8975f5c5SAndroid Build Coastguard Worker         }
79*8975f5c5SAndroid Build Coastguard Worker         mShaderPrograms->release(context);
80*8975f5c5SAndroid Build Coastguard Worker         mShaderPrograms             = nullptr;
81*8975f5c5SAndroid Build Coastguard Worker         mRendererProgramInitialized = false;
82*8975f5c5SAndroid Build Coastguard Worker     }
83*8975f5c5SAndroid Build Coastguard Worker }
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker GLES1Renderer::~GLES1Renderer() = default;
86*8975f5c5SAndroid Build Coastguard Worker 
prepareForDraw(PrimitiveMode mode,Context * context,State * glState,GLES1State * gles1State)87*8975f5c5SAndroid Build Coastguard Worker angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode,
88*8975f5c5SAndroid Build Coastguard Worker                                             Context *context,
89*8975f5c5SAndroid Build Coastguard Worker                                             State *glState,
90*8975f5c5SAndroid Build Coastguard Worker                                             GLES1State *gles1State)
91*8975f5c5SAndroid Build Coastguard Worker {
92*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::BoolTexArray &tex2DEnables   = mShaderState.tex2DEnables;
93*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::BoolTexArray &texCubeEnables = mShaderState.texCubeEnables;
94*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &tex2DFormats   = mShaderState.tex2DFormats;
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
97*8975f5c5SAndroid Build Coastguard Worker     {
98*8975f5c5SAndroid Build Coastguard Worker         // GL_OES_cube_map allows only one of TEXTURE_2D / TEXTURE_CUBE_MAP
99*8975f5c5SAndroid Build Coastguard Worker         // to be enabled per unit, thankfully. From the extension text:
100*8975f5c5SAndroid Build Coastguard Worker         //
101*8975f5c5SAndroid Build Coastguard Worker         //  --  Section 3.8.10 "Texture Application"
102*8975f5c5SAndroid Build Coastguard Worker         //
103*8975f5c5SAndroid Build Coastguard Worker         //      Replace the beginning sentences of the first paragraph (page 138)
104*8975f5c5SAndroid Build Coastguard Worker         //      with:
105*8975f5c5SAndroid Build Coastguard Worker         //
106*8975f5c5SAndroid Build Coastguard Worker         //      "Texturing is enabled or disabled using the generic Enable
107*8975f5c5SAndroid Build Coastguard Worker         //      and Disable commands, respectively, with the symbolic constants
108*8975f5c5SAndroid Build Coastguard Worker         //      TEXTURE_2D or TEXTURE_CUBE_MAP_OES to enable the two-dimensional or cube
109*8975f5c5SAndroid Build Coastguard Worker         //      map texturing respectively.  If the cube map texture and the two-
110*8975f5c5SAndroid Build Coastguard Worker         //      dimensional texture are enabled, then cube map texturing is used.  If
111*8975f5c5SAndroid Build Coastguard Worker         //      texturing is disabled, a rasterized fragment is passed on unaltered to the
112*8975f5c5SAndroid Build Coastguard Worker         //      next stage of the GL (although its texture coordinates may be discarded).
113*8975f5c5SAndroid Build Coastguard Worker         //      Otherwise, a texture value is found according to the parameter values of
114*8975f5c5SAndroid Build Coastguard Worker         //      the currently bound texture image of the appropriate dimensionality.
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker         texCubeEnables[i] = gles1State->isTextureTargetEnabled(i, TextureType::CubeMap);
117*8975f5c5SAndroid Build Coastguard Worker         tex2DEnables[i] =
118*8975f5c5SAndroid Build Coastguard Worker             !texCubeEnables[i] && gles1State->isTextureTargetEnabled(i, TextureType::_2D);
119*8975f5c5SAndroid Build Coastguard Worker 
120*8975f5c5SAndroid Build Coastguard Worker         Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D);
121*8975f5c5SAndroid Build Coastguard Worker         if (curr2DTexture)
122*8975f5c5SAndroid Build Coastguard Worker         {
123*8975f5c5SAndroid Build Coastguard Worker             tex2DFormats[i] = static_cast<uint16_t>(gl::GetUnsizedFormat(
124*8975f5c5SAndroid Build Coastguard Worker                 curr2DTexture->getFormat(TextureTarget::_2D, 0).info->internalFormat));
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker             // Handle GL_BGRA the same way we do GL_RGBA
127*8975f5c5SAndroid Build Coastguard Worker             if (tex2DFormats[i] == static_cast<uint16_t>(GL_BGRA_EXT))
128*8975f5c5SAndroid Build Coastguard Worker                 tex2DFormats[i] = static_cast<uint16_t>(GL_RGBA);
129*8975f5c5SAndroid Build Coastguard Worker         }
130*8975f5c5SAndroid Build Coastguard Worker 
131*8975f5c5SAndroid Build Coastguard Worker         Texture *currCubeTexture = glState->getSamplerTexture(i, TextureType::CubeMap);
132*8975f5c5SAndroid Build Coastguard Worker 
133*8975f5c5SAndroid Build Coastguard Worker         // > If texturing is enabled for a texture unit at the time a primitive is rasterized, if
134*8975f5c5SAndroid Build Coastguard Worker         // > TEXTURE MIN FILTER is one that requires a mipmap, and if the texture image bound to the
135*8975f5c5SAndroid Build Coastguard Worker         // > enabled texture target is not complete, then it is as if texture mapping were disabled
136*8975f5c5SAndroid Build Coastguard Worker         // > for that texture unit.
137*8975f5c5SAndroid Build Coastguard Worker         if (tex2DEnables[i] && curr2DTexture && IsMipmapFiltered(curr2DTexture->getMinFilter()))
138*8975f5c5SAndroid Build Coastguard Worker         {
139*8975f5c5SAndroid Build Coastguard Worker             tex2DEnables[i] = curr2DTexture->isMipmapComplete();
140*8975f5c5SAndroid Build Coastguard Worker         }
141*8975f5c5SAndroid Build Coastguard Worker         if (texCubeEnables[i] && currCubeTexture &&
142*8975f5c5SAndroid Build Coastguard Worker             IsMipmapFiltered(currCubeTexture->getMinFilter()))
143*8975f5c5SAndroid Build Coastguard Worker         {
144*8975f5c5SAndroid Build Coastguard Worker             texCubeEnables[i] = curr2DTexture->isMipmapComplete();
145*8975f5c5SAndroid Build Coastguard Worker         }
146*8975f5c5SAndroid Build Coastguard Worker     }
147*8975f5c5SAndroid Build Coastguard Worker 
148*8975f5c5SAndroid Build Coastguard Worker     // If texture has been disabled on the active sampler, texture coordinate data should not be
149*8975f5c5SAndroid Build Coastguard Worker     // used. However, according to the spec, a rasterized fragment is passed on unaltered to the
150*8975f5c5SAndroid Build Coastguard Worker     // next stage.
151*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_TEXTURE_UNIT_ENABLE))
152*8975f5c5SAndroid Build Coastguard Worker     {
153*8975f5c5SAndroid Build Coastguard Worker         unsigned int clientActiveTexture = gles1State->getClientTextureUnit();
154*8975f5c5SAndroid Build Coastguard Worker         bool isTextureEnabled =
155*8975f5c5SAndroid Build Coastguard Worker             tex2DEnables[clientActiveTexture] || texCubeEnables[clientActiveTexture];
156*8975f5c5SAndroid Build Coastguard Worker         glState->setEnableVertexAttribArray(
157*8975f5c5SAndroid Build Coastguard Worker             TexCoordArrayIndex(clientActiveTexture),
158*8975f5c5SAndroid Build Coastguard Worker             isTextureEnabled && gles1State->isTexCoordArrayEnabled(clientActiveTexture));
159*8975f5c5SAndroid Build Coastguard Worker         context->getStateCache().onGLES1TextureStateChange(context);
160*8975f5c5SAndroid Build Coastguard Worker     }
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texEnvModes          = mShaderState.texEnvModes;
163*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineRgbs       = mShaderState.texCombineRgbs;
164*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineAlphas     = mShaderState.texCombineAlphas;
165*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineSrc0Rgbs   = mShaderState.texCombineSrc0Rgbs;
166*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineSrc0Alphas = mShaderState.texCombineSrc0Alphas;
167*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineSrc1Rgbs   = mShaderState.texCombineSrc1Rgbs;
168*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineSrc1Alphas = mShaderState.texCombineSrc1Alphas;
169*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineSrc2Rgbs   = mShaderState.texCombineSrc2Rgbs;
170*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineSrc2Alphas = mShaderState.texCombineSrc2Alphas;
171*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineOp0Rgbs    = mShaderState.texCombineOp0Rgbs;
172*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineOp0Alphas  = mShaderState.texCombineOp0Alphas;
173*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineOp1Rgbs    = mShaderState.texCombineOp1Rgbs;
174*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineOp1Alphas  = mShaderState.texCombineOp1Alphas;
175*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineOp2Rgbs    = mShaderState.texCombineOp2Rgbs;
176*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::UintTexArray &texCombineOp2Alphas  = mShaderState.texCombineOp2Alphas;
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT))
179*8975f5c5SAndroid Build Coastguard Worker     {
180*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kTexUnitCount; i++)
181*8975f5c5SAndroid Build Coastguard Worker         {
182*8975f5c5SAndroid Build Coastguard Worker             const auto &env         = gles1State->textureEnvironment(i);
183*8975f5c5SAndroid Build Coastguard Worker             texEnvModes[i]          = static_cast<uint16_t>(ToGLenum(env.mode));
184*8975f5c5SAndroid Build Coastguard Worker             texCombineRgbs[i]       = static_cast<uint16_t>(ToGLenum(env.combineRgb));
185*8975f5c5SAndroid Build Coastguard Worker             texCombineAlphas[i]     = static_cast<uint16_t>(ToGLenum(env.combineAlpha));
186*8975f5c5SAndroid Build Coastguard Worker             texCombineSrc0Rgbs[i]   = static_cast<uint16_t>(ToGLenum(env.src0Rgb));
187*8975f5c5SAndroid Build Coastguard Worker             texCombineSrc0Alphas[i] = static_cast<uint16_t>(ToGLenum(env.src0Alpha));
188*8975f5c5SAndroid Build Coastguard Worker             texCombineSrc1Rgbs[i]   = static_cast<uint16_t>(ToGLenum(env.src1Rgb));
189*8975f5c5SAndroid Build Coastguard Worker             texCombineSrc1Alphas[i] = static_cast<uint16_t>(ToGLenum(env.src1Alpha));
190*8975f5c5SAndroid Build Coastguard Worker             texCombineSrc2Rgbs[i]   = static_cast<uint16_t>(ToGLenum(env.src2Rgb));
191*8975f5c5SAndroid Build Coastguard Worker             texCombineSrc2Alphas[i] = static_cast<uint16_t>(ToGLenum(env.src2Alpha));
192*8975f5c5SAndroid Build Coastguard Worker             texCombineOp0Rgbs[i]    = static_cast<uint16_t>(ToGLenum(env.op0Rgb));
193*8975f5c5SAndroid Build Coastguard Worker             texCombineOp0Alphas[i]  = static_cast<uint16_t>(ToGLenum(env.op0Alpha));
194*8975f5c5SAndroid Build Coastguard Worker             texCombineOp1Rgbs[i]    = static_cast<uint16_t>(ToGLenum(env.op1Rgb));
195*8975f5c5SAndroid Build Coastguard Worker             texCombineOp1Alphas[i]  = static_cast<uint16_t>(ToGLenum(env.op1Alpha));
196*8975f5c5SAndroid Build Coastguard Worker             texCombineOp2Rgbs[i]    = static_cast<uint16_t>(ToGLenum(env.op2Rgb));
197*8975f5c5SAndroid Build Coastguard Worker             texCombineOp2Alphas[i]  = static_cast<uint16_t>(ToGLenum(env.op2Alpha));
198*8975f5c5SAndroid Build Coastguard Worker         }
199*8975f5c5SAndroid Build Coastguard Worker     }
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker     bool enableClipPlanes                                  = false;
202*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::BoolClipPlaneArray &clipPlaneEnables = mShaderState.clipPlaneEnables;
203*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kClipPlaneCount; i++)
204*8975f5c5SAndroid Build Coastguard Worker     {
205*8975f5c5SAndroid Build Coastguard Worker         clipPlaneEnables[i] = glState->getEnableFeature(GL_CLIP_PLANE0 + i);
206*8975f5c5SAndroid Build Coastguard Worker         enableClipPlanes    = enableClipPlanes || clipPlaneEnables[i];
207*8975f5c5SAndroid Build Coastguard Worker     }
208*8975f5c5SAndroid Build Coastguard Worker 
209*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::ClipPlanes]  = enableClipPlanes;
210*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::DrawTexture] = mDrawTextureEnabled;
211*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::PointRasterization] =
212*8975f5c5SAndroid Build Coastguard Worker         mode == PrimitiveMode::Points;
213*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::ShadeModelFlat] =
214*8975f5c5SAndroid Build Coastguard Worker         gles1State->mShadeModel == ShadingModel::Flat;
215*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::AlphaTest] =
216*8975f5c5SAndroid Build Coastguard Worker         glState->getEnableFeature(GL_ALPHA_TEST);
217*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::Lighting] =
218*8975f5c5SAndroid Build Coastguard Worker         glState->getEnableFeature(GL_LIGHTING);
219*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::RescaleNormal] =
220*8975f5c5SAndroid Build Coastguard Worker         glState->getEnableFeature(GL_RESCALE_NORMAL);
221*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::Normalize] =
222*8975f5c5SAndroid Build Coastguard Worker         glState->getEnableFeature(GL_NORMALIZE);
223*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::Fog] = glState->getEnableFeature(GL_FOG);
224*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::PointSprite] =
225*8975f5c5SAndroid Build Coastguard Worker         glState->getEnableFeature(GL_POINT_SPRITE_OES);
226*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::ColorMaterial] =
227*8975f5c5SAndroid Build Coastguard Worker         glState->getEnableFeature(GL_COLOR_MATERIAL);
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker     // TODO ([email protected]): Implement two-sided lighting model (lightModel.twoSided)
230*8975f5c5SAndroid Build Coastguard Worker     mShaderState.mGLES1StateEnabled[GLES1StateEnables::LightModelTwoSided] = false;
231*8975f5c5SAndroid Build Coastguard Worker 
232*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::BoolTexArray &pointSpriteCoordReplaces =
233*8975f5c5SAndroid Build Coastguard Worker         mShaderState.pointSpriteCoordReplaces;
234*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
235*8975f5c5SAndroid Build Coastguard Worker     {
236*8975f5c5SAndroid Build Coastguard Worker         const auto &env             = gles1State->textureEnvironment(i);
237*8975f5c5SAndroid Build Coastguard Worker         pointSpriteCoordReplaces[i] = env.pointSpriteCoordReplace;
238*8975f5c5SAndroid Build Coastguard Worker     }
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker     GLES1ShaderState::BoolLightArray &lightEnables = mShaderState.lightEnables;
241*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kLightCount; i++)
242*8975f5c5SAndroid Build Coastguard Worker     {
243*8975f5c5SAndroid Build Coastguard Worker         const auto &light = gles1State->mLights[i];
244*8975f5c5SAndroid Build Coastguard Worker         lightEnables[i]   = light.enabled;
245*8975f5c5SAndroid Build Coastguard Worker     }
246*8975f5c5SAndroid Build Coastguard Worker 
247*8975f5c5SAndroid Build Coastguard Worker     mShaderState.alphaTestFunc = gles1State->mAlphaTestParameters.func;
248*8975f5c5SAndroid Build Coastguard Worker     mShaderState.fogMode       = gles1State->fogParameters().mode;
249*8975f5c5SAndroid Build Coastguard Worker 
250*8975f5c5SAndroid Build Coastguard Worker     const bool hasLogicOpANGLE     = context->getExtensions().logicOpANGLE;
251*8975f5c5SAndroid Build Coastguard Worker     const bool hasFramebufferFetch = context->getExtensions().shaderFramebufferFetchEXT ||
252*8975f5c5SAndroid Build Coastguard Worker                                      context->getExtensions().shaderFramebufferFetchNonCoherentEXT;
253*8975f5c5SAndroid Build Coastguard Worker 
254*8975f5c5SAndroid Build Coastguard Worker     if (!hasLogicOpANGLE && hasFramebufferFetch)
255*8975f5c5SAndroid Build Coastguard Worker     {
256*8975f5c5SAndroid Build Coastguard Worker         mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch] =
257*8975f5c5SAndroid Build Coastguard Worker             gles1State->mLogicOpEnabled;
258*8975f5c5SAndroid Build Coastguard Worker     }
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker     // All the states set before this spot affect ubershader creation
261*8975f5c5SAndroid Build Coastguard Worker 
262*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(initializeRendererProgram(context, glState, gles1State));
263*8975f5c5SAndroid Build Coastguard Worker 
264*8975f5c5SAndroid Build Coastguard Worker     GLES1UberShaderState UberShaderState = getUberShaderState();
265*8975f5c5SAndroid Build Coastguard Worker 
266*8975f5c5SAndroid Build Coastguard Worker     const GLES1ProgramState &programState = UberShaderState.programState;
267*8975f5c5SAndroid Build Coastguard Worker     GLES1UniformBuffers &uniformBuffers   = UberShaderState.uniformBuffers;
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker     Program *programObject        = getProgram(programState.program);
270*8975f5c5SAndroid Build Coastguard Worker     ProgramExecutable &executable = programObject->getExecutable();
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker     // If anything is dirty in gles1 or the common parts of gles1/2, just redo these parts
273*8975f5c5SAndroid Build Coastguard Worker     // completely for now.
274*8975f5c5SAndroid Build Coastguard Worker 
275*8975f5c5SAndroid Build Coastguard Worker     // Feature enables
276*8975f5c5SAndroid Build Coastguard Worker 
277*8975f5c5SAndroid Build Coastguard Worker     // Texture unit enables and format info
278*8975f5c5SAndroid Build Coastguard Worker     std::array<Vec4Uniform, kTexUnitCount> texCropRects;
279*8975f5c5SAndroid Build Coastguard Worker     Vec4Uniform *cropRectBuffer = texCropRects.data();
280*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
281*8975f5c5SAndroid Build Coastguard Worker     {
282*8975f5c5SAndroid Build Coastguard Worker         Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D);
283*8975f5c5SAndroid Build Coastguard Worker         if (curr2DTexture)
284*8975f5c5SAndroid Build Coastguard Worker         {
285*8975f5c5SAndroid Build Coastguard Worker             const gl::Rectangle &cropRect = curr2DTexture->getCrop();
286*8975f5c5SAndroid Build Coastguard Worker 
287*8975f5c5SAndroid Build Coastguard Worker             GLfloat textureWidth =
288*8975f5c5SAndroid Build Coastguard Worker                 static_cast<GLfloat>(curr2DTexture->getWidth(TextureTarget::_2D, 0));
289*8975f5c5SAndroid Build Coastguard Worker             GLfloat textureHeight =
290*8975f5c5SAndroid Build Coastguard Worker                 static_cast<GLfloat>(curr2DTexture->getHeight(TextureTarget::_2D, 0));
291*8975f5c5SAndroid Build Coastguard Worker 
292*8975f5c5SAndroid Build Coastguard Worker             if (textureWidth > 0.0f && textureHeight > 0.0f)
293*8975f5c5SAndroid Build Coastguard Worker             {
294*8975f5c5SAndroid Build Coastguard Worker                 cropRectBuffer[i][0] = cropRect.x / textureWidth;
295*8975f5c5SAndroid Build Coastguard Worker                 cropRectBuffer[i][1] = cropRect.y / textureHeight;
296*8975f5c5SAndroid Build Coastguard Worker                 cropRectBuffer[i][2] = cropRect.width / textureWidth;
297*8975f5c5SAndroid Build Coastguard Worker                 cropRectBuffer[i][3] = cropRect.height / textureHeight;
298*8975f5c5SAndroid Build Coastguard Worker             }
299*8975f5c5SAndroid Build Coastguard Worker         }
300*8975f5c5SAndroid Build Coastguard Worker     }
301*8975f5c5SAndroid Build Coastguard Worker     setUniform4fv(&executable, programState.drawTextureNormalizedCropRectLoc, kTexUnitCount,
302*8975f5c5SAndroid Build Coastguard Worker                   reinterpret_cast<GLfloat *>(cropRectBuffer));
303*8975f5c5SAndroid Build Coastguard Worker 
304*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_LOGIC_OP) && hasLogicOpANGLE)
305*8975f5c5SAndroid Build Coastguard Worker     {
306*8975f5c5SAndroid Build Coastguard Worker         // Note: ContextPrivateEnable(GL_COLOR_LOGIC_OP) is not used because that entry point
307*8975f5c5SAndroid Build Coastguard Worker         // implementation forwards logicOp back to GLES1State.
308*8975f5c5SAndroid Build Coastguard Worker         context->setLogicOpEnabledForGLES1(gles1State->mLogicOpEnabled);
309*8975f5c5SAndroid Build Coastguard Worker         ContextPrivateLogicOpANGLE(context->getMutablePrivateState(),
310*8975f5c5SAndroid Build Coastguard Worker                                    context->getMutablePrivateStateCache(), gles1State->mLogicOp);
311*8975f5c5SAndroid Build Coastguard Worker     }
312*8975f5c5SAndroid Build Coastguard Worker     else if (hasFramebufferFetch)
313*8975f5c5SAndroid Build Coastguard Worker     {
314*8975f5c5SAndroid Build Coastguard Worker         const Framebuffer *drawFramebuffer           = glState->getDrawFramebuffer();
315*8975f5c5SAndroid Build Coastguard Worker         const FramebufferAttachment *colorAttachment = drawFramebuffer->getColorAttachment(0);
316*8975f5c5SAndroid Build Coastguard Worker 
317*8975f5c5SAndroid Build Coastguard Worker         if (gles1State->mLogicOpEnabled)
318*8975f5c5SAndroid Build Coastguard Worker         {
319*8975f5c5SAndroid Build Coastguard Worker             if (gles1State->isDirty(GLES1State::DIRTY_GLES1_LOGIC_OP))
320*8975f5c5SAndroid Build Coastguard Worker             {
321*8975f5c5SAndroid Build Coastguard Worker                 // Set up uniform value for logic op
322*8975f5c5SAndroid Build Coastguard Worker                 setUniform1ui(&executable, programState.logicOpLoc,
323*8975f5c5SAndroid Build Coastguard Worker                               GetLogicOpUniform(colorAttachment, gles1State->mLogicOp));
324*8975f5c5SAndroid Build Coastguard Worker             }
325*8975f5c5SAndroid Build Coastguard Worker 
326*8975f5c5SAndroid Build Coastguard Worker             // Issue a framebuffer fetch barrier if non-coherent
327*8975f5c5SAndroid Build Coastguard Worker             if (!context->getExtensions().shaderFramebufferFetchEXT)
328*8975f5c5SAndroid Build Coastguard Worker             {
329*8975f5c5SAndroid Build Coastguard Worker                 context->framebufferFetchBarrier();
330*8975f5c5SAndroid Build Coastguard Worker             }
331*8975f5c5SAndroid Build Coastguard Worker         }
332*8975f5c5SAndroid Build Coastguard Worker     }
333*8975f5c5SAndroid Build Coastguard Worker 
334*8975f5c5SAndroid Build Coastguard Worker     // Client state / current vector enables
335*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_CLIENT_STATE_ENABLE) ||
336*8975f5c5SAndroid Build Coastguard Worker         gles1State->isDirty(GLES1State::DIRTY_GLES1_CURRENT_VECTOR))
337*8975f5c5SAndroid Build Coastguard Worker     {
338*8975f5c5SAndroid Build Coastguard Worker         if (!gles1State->isClientStateEnabled(ClientVertexArrayType::Normal))
339*8975f5c5SAndroid Build Coastguard Worker         {
340*8975f5c5SAndroid Build Coastguard Worker             const angle::Vector3 normal = gles1State->getCurrentNormal();
341*8975f5c5SAndroid Build Coastguard Worker             ContextPrivateVertexAttrib3f(context->getMutablePrivateState(),
342*8975f5c5SAndroid Build Coastguard Worker                                          context->getMutablePrivateStateCache(), kNormalAttribIndex,
343*8975f5c5SAndroid Build Coastguard Worker                                          normal.x(), normal.y(), normal.z());
344*8975f5c5SAndroid Build Coastguard Worker         }
345*8975f5c5SAndroid Build Coastguard Worker 
346*8975f5c5SAndroid Build Coastguard Worker         if (!gles1State->isClientStateEnabled(ClientVertexArrayType::Color))
347*8975f5c5SAndroid Build Coastguard Worker         {
348*8975f5c5SAndroid Build Coastguard Worker             const ColorF color = gles1State->getCurrentColor();
349*8975f5c5SAndroid Build Coastguard Worker             ContextPrivateVertexAttrib4f(context->getMutablePrivateState(),
350*8975f5c5SAndroid Build Coastguard Worker                                          context->getMutablePrivateStateCache(), kColorAttribIndex,
351*8975f5c5SAndroid Build Coastguard Worker                                          color.red, color.green, color.blue, color.alpha);
352*8975f5c5SAndroid Build Coastguard Worker         }
353*8975f5c5SAndroid Build Coastguard Worker 
354*8975f5c5SAndroid Build Coastguard Worker         if (!gles1State->isClientStateEnabled(ClientVertexArrayType::PointSize))
355*8975f5c5SAndroid Build Coastguard Worker         {
356*8975f5c5SAndroid Build Coastguard Worker             GLfloat pointSize = gles1State->mPointParameters.pointSize;
357*8975f5c5SAndroid Build Coastguard Worker             ContextPrivateVertexAttrib1f(context->getMutablePrivateState(),
358*8975f5c5SAndroid Build Coastguard Worker                                          context->getMutablePrivateStateCache(),
359*8975f5c5SAndroid Build Coastguard Worker                                          kPointSizeAttribIndex, pointSize);
360*8975f5c5SAndroid Build Coastguard Worker         }
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kTexUnitCount; i++)
363*8975f5c5SAndroid Build Coastguard Worker         {
364*8975f5c5SAndroid Build Coastguard Worker             if (!gles1State->mTexCoordArrayEnabled[i])
365*8975f5c5SAndroid Build Coastguard Worker             {
366*8975f5c5SAndroid Build Coastguard Worker                 const TextureCoordF texcoord = gles1State->getCurrentTextureCoords(i);
367*8975f5c5SAndroid Build Coastguard Worker                 ContextPrivateVertexAttrib4f(context->getMutablePrivateState(),
368*8975f5c5SAndroid Build Coastguard Worker                                              context->getMutablePrivateStateCache(),
369*8975f5c5SAndroid Build Coastguard Worker                                              kTextureCoordAttribIndexBase + i, texcoord.s,
370*8975f5c5SAndroid Build Coastguard Worker                                              texcoord.t, texcoord.r, texcoord.q);
371*8975f5c5SAndroid Build Coastguard Worker             }
372*8975f5c5SAndroid Build Coastguard Worker         }
373*8975f5c5SAndroid Build Coastguard Worker     }
374*8975f5c5SAndroid Build Coastguard Worker 
375*8975f5c5SAndroid Build Coastguard Worker     // Matrices
376*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_MATRICES))
377*8975f5c5SAndroid Build Coastguard Worker     {
378*8975f5c5SAndroid Build Coastguard Worker         angle::Mat4 proj = gles1State->mProjectionMatrices.back();
379*8975f5c5SAndroid Build Coastguard Worker         setUniformMatrix4fv(&executable, programState.projMatrixLoc, 1, GL_FALSE, proj.data());
380*8975f5c5SAndroid Build Coastguard Worker 
381*8975f5c5SAndroid Build Coastguard Worker         angle::Mat4 modelview = gles1State->mModelviewMatrices.back();
382*8975f5c5SAndroid Build Coastguard Worker         setUniformMatrix4fv(&executable, programState.modelviewMatrixLoc, 1, GL_FALSE,
383*8975f5c5SAndroid Build Coastguard Worker                             modelview.data());
384*8975f5c5SAndroid Build Coastguard Worker 
385*8975f5c5SAndroid Build Coastguard Worker         angle::Mat4 modelviewInvTr = modelview.transpose().inverse();
386*8975f5c5SAndroid Build Coastguard Worker         setUniformMatrix4fv(&executable, programState.modelviewInvTrLoc, 1, GL_FALSE,
387*8975f5c5SAndroid Build Coastguard Worker                             modelviewInvTr.data());
388*8975f5c5SAndroid Build Coastguard Worker 
389*8975f5c5SAndroid Build Coastguard Worker         Mat4Uniform *textureMatrixBuffer = uniformBuffers.textureMatrices.data();
390*8975f5c5SAndroid Build Coastguard Worker 
391*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kTexUnitCount; i++)
392*8975f5c5SAndroid Build Coastguard Worker         {
393*8975f5c5SAndroid Build Coastguard Worker             angle::Mat4 textureMatrix = gles1State->mTextureMatrices[i].back();
394*8975f5c5SAndroid Build Coastguard Worker             memcpy(textureMatrixBuffer + i, textureMatrix.data(), sizeof(Mat4Uniform));
395*8975f5c5SAndroid Build Coastguard Worker         }
396*8975f5c5SAndroid Build Coastguard Worker 
397*8975f5c5SAndroid Build Coastguard Worker         setUniformMatrix4fv(&executable, programState.textureMatrixLoc, kTexUnitCount, GL_FALSE,
398*8975f5c5SAndroid Build Coastguard Worker                             reinterpret_cast<float *>(uniformBuffers.textureMatrices.data()));
399*8975f5c5SAndroid Build Coastguard Worker     }
400*8975f5c5SAndroid Build Coastguard Worker 
401*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT))
402*8975f5c5SAndroid Build Coastguard Worker     {
403*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kTexUnitCount; i++)
404*8975f5c5SAndroid Build Coastguard Worker         {
405*8975f5c5SAndroid Build Coastguard Worker             const auto &env = gles1State->textureEnvironment(i);
406*8975f5c5SAndroid Build Coastguard Worker 
407*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.texEnvColors[i][0] = env.color.red;
408*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.texEnvColors[i][1] = env.color.green;
409*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.texEnvColors[i][2] = env.color.blue;
410*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.texEnvColors[i][3] = env.color.alpha;
411*8975f5c5SAndroid Build Coastguard Worker 
412*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.texEnvRgbScales[i]   = env.rgbScale;
413*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.texEnvAlphaScales[i] = env.alphaScale;
414*8975f5c5SAndroid Build Coastguard Worker         }
415*8975f5c5SAndroid Build Coastguard Worker 
416*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.textureEnvColorLoc, kTexUnitCount,
417*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.texEnvColors.data()));
418*8975f5c5SAndroid Build Coastguard Worker         setUniform1fv(&executable, programState.rgbScaleLoc, kTexUnitCount,
419*8975f5c5SAndroid Build Coastguard Worker                       uniformBuffers.texEnvRgbScales.data());
420*8975f5c5SAndroid Build Coastguard Worker         setUniform1fv(&executable, programState.alphaScaleLoc, kTexUnitCount,
421*8975f5c5SAndroid Build Coastguard Worker                       uniformBuffers.texEnvAlphaScales.data());
422*8975f5c5SAndroid Build Coastguard Worker     }
423*8975f5c5SAndroid Build Coastguard Worker 
424*8975f5c5SAndroid Build Coastguard Worker     // Alpha test
425*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_ALPHA_TEST))
426*8975f5c5SAndroid Build Coastguard Worker     {
427*8975f5c5SAndroid Build Coastguard Worker         setUniform1f(&executable, programState.alphaTestRefLoc,
428*8975f5c5SAndroid Build Coastguard Worker                      gles1State->mAlphaTestParameters.ref);
429*8975f5c5SAndroid Build Coastguard Worker     }
430*8975f5c5SAndroid Build Coastguard Worker 
431*8975f5c5SAndroid Build Coastguard Worker     // Shading, materials, and lighting
432*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_MATERIAL))
433*8975f5c5SAndroid Build Coastguard Worker     {
434*8975f5c5SAndroid Build Coastguard Worker         const auto &material = gles1State->mMaterial;
435*8975f5c5SAndroid Build Coastguard Worker 
436*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.materialAmbientLoc, 1, material.ambient.data());
437*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.materialDiffuseLoc, 1, material.diffuse.data());
438*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.materialSpecularLoc, 1, material.specular.data());
439*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.materialEmissiveLoc, 1, material.emissive.data());
440*8975f5c5SAndroid Build Coastguard Worker         setUniform1f(&executable, programState.materialSpecularExponentLoc,
441*8975f5c5SAndroid Build Coastguard Worker                      material.specularExponent);
442*8975f5c5SAndroid Build Coastguard Worker     }
443*8975f5c5SAndroid Build Coastguard Worker 
444*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_LIGHTS))
445*8975f5c5SAndroid Build Coastguard Worker     {
446*8975f5c5SAndroid Build Coastguard Worker         const auto &lightModel = gles1State->mLightModel;
447*8975f5c5SAndroid Build Coastguard Worker 
448*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.lightModelSceneAmbientLoc, 1,
449*8975f5c5SAndroid Build Coastguard Worker                       lightModel.color.data());
450*8975f5c5SAndroid Build Coastguard Worker 
451*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kLightCount; i++)
452*8975f5c5SAndroid Build Coastguard Worker         {
453*8975f5c5SAndroid Build Coastguard Worker             const auto &light = gles1State->mLights[i];
454*8975f5c5SAndroid Build Coastguard Worker             memcpy(uniformBuffers.lightAmbients.data() + i, light.ambient.data(),
455*8975f5c5SAndroid Build Coastguard Worker                    sizeof(Vec4Uniform));
456*8975f5c5SAndroid Build Coastguard Worker             memcpy(uniformBuffers.lightDiffuses.data() + i, light.diffuse.data(),
457*8975f5c5SAndroid Build Coastguard Worker                    sizeof(Vec4Uniform));
458*8975f5c5SAndroid Build Coastguard Worker             memcpy(uniformBuffers.lightSpeculars.data() + i, light.specular.data(),
459*8975f5c5SAndroid Build Coastguard Worker                    sizeof(Vec4Uniform));
460*8975f5c5SAndroid Build Coastguard Worker             memcpy(uniformBuffers.lightPositions.data() + i, light.position.data(),
461*8975f5c5SAndroid Build Coastguard Worker                    sizeof(Vec4Uniform));
462*8975f5c5SAndroid Build Coastguard Worker             memcpy(uniformBuffers.lightDirections.data() + i, light.direction.data(),
463*8975f5c5SAndroid Build Coastguard Worker                    sizeof(Vec3Uniform));
464*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.spotlightExponents[i]    = light.spotlightExponent;
465*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.spotlightCutoffAngles[i] = light.spotlightCutoffAngle;
466*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.attenuationConsts[i]     = light.attenuationConst;
467*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.attenuationLinears[i]    = light.attenuationLinear;
468*8975f5c5SAndroid Build Coastguard Worker             uniformBuffers.attenuationQuadratics[i] = light.attenuationQuadratic;
469*8975f5c5SAndroid Build Coastguard Worker         }
470*8975f5c5SAndroid Build Coastguard Worker 
471*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.lightAmbientsLoc, kLightCount,
472*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.lightAmbients.data()));
473*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.lightDiffusesLoc, kLightCount,
474*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.lightDiffuses.data()));
475*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.lightSpecularsLoc, kLightCount,
476*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.lightSpeculars.data()));
477*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.lightPositionsLoc, kLightCount,
478*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.lightPositions.data()));
479*8975f5c5SAndroid Build Coastguard Worker         setUniform3fv(&executable, programState.lightDirectionsLoc, kLightCount,
480*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.lightDirections.data()));
481*8975f5c5SAndroid Build Coastguard Worker         setUniform1fv(&executable, programState.lightSpotlightExponentsLoc, kLightCount,
482*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.spotlightExponents.data()));
483*8975f5c5SAndroid Build Coastguard Worker         setUniform1fv(&executable, programState.lightSpotlightCutoffAnglesLoc, kLightCount,
484*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.spotlightCutoffAngles.data()));
485*8975f5c5SAndroid Build Coastguard Worker         setUniform1fv(&executable, programState.lightAttenuationConstsLoc, kLightCount,
486*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.attenuationConsts.data()));
487*8975f5c5SAndroid Build Coastguard Worker         setUniform1fv(&executable, programState.lightAttenuationLinearsLoc, kLightCount,
488*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.attenuationLinears.data()));
489*8975f5c5SAndroid Build Coastguard Worker         setUniform1fv(&executable, programState.lightAttenuationQuadraticsLoc, kLightCount,
490*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.attenuationQuadratics.data()));
491*8975f5c5SAndroid Build Coastguard Worker     }
492*8975f5c5SAndroid Build Coastguard Worker 
493*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_FOG))
494*8975f5c5SAndroid Build Coastguard Worker     {
495*8975f5c5SAndroid Build Coastguard Worker         const FogParameters &fog = gles1State->fogParameters();
496*8975f5c5SAndroid Build Coastguard Worker         setUniform1f(&executable, programState.fogDensityLoc, fog.density);
497*8975f5c5SAndroid Build Coastguard Worker         setUniform1f(&executable, programState.fogStartLoc, fog.start);
498*8975f5c5SAndroid Build Coastguard Worker         setUniform1f(&executable, programState.fogEndLoc, fog.end);
499*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.fogColorLoc, 1, fog.color.data());
500*8975f5c5SAndroid Build Coastguard Worker     }
501*8975f5c5SAndroid Build Coastguard Worker 
502*8975f5c5SAndroid Build Coastguard Worker     // Clip planes
503*8975f5c5SAndroid Build Coastguard Worker     if (gles1State->isDirty(GLES1State::DIRTY_GLES1_CLIP_PLANES))
504*8975f5c5SAndroid Build Coastguard Worker     {
505*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < kClipPlaneCount; i++)
506*8975f5c5SAndroid Build Coastguard Worker         {
507*8975f5c5SAndroid Build Coastguard Worker             gles1State->getClipPlane(
508*8975f5c5SAndroid Build Coastguard Worker                 i, reinterpret_cast<float *>(uniformBuffers.clipPlanes.data() + i));
509*8975f5c5SAndroid Build Coastguard Worker         }
510*8975f5c5SAndroid Build Coastguard Worker 
511*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.clipPlanesLoc, kClipPlaneCount,
512*8975f5c5SAndroid Build Coastguard Worker                       reinterpret_cast<float *>(uniformBuffers.clipPlanes.data()));
513*8975f5c5SAndroid Build Coastguard Worker     }
514*8975f5c5SAndroid Build Coastguard Worker 
515*8975f5c5SAndroid Build Coastguard Worker     // Point rasterization
516*8975f5c5SAndroid Build Coastguard Worker     {
517*8975f5c5SAndroid Build Coastguard Worker         const PointParameters &pointParams = gles1State->mPointParameters;
518*8975f5c5SAndroid Build Coastguard Worker 
519*8975f5c5SAndroid Build Coastguard Worker         setUniform1f(&executable, programState.pointSizeMinLoc, pointParams.pointSizeMin);
520*8975f5c5SAndroid Build Coastguard Worker         setUniform1f(&executable, programState.pointSizeMaxLoc, pointParams.pointSizeMax);
521*8975f5c5SAndroid Build Coastguard Worker         setUniform3fv(&executable, programState.pointDistanceAttenuationLoc, 1,
522*8975f5c5SAndroid Build Coastguard Worker                       pointParams.pointDistanceAttenuation.data());
523*8975f5c5SAndroid Build Coastguard Worker     }
524*8975f5c5SAndroid Build Coastguard Worker 
525*8975f5c5SAndroid Build Coastguard Worker     // Draw texture
526*8975f5c5SAndroid Build Coastguard Worker     {
527*8975f5c5SAndroid Build Coastguard Worker         setUniform4fv(&executable, programState.drawTextureCoordsLoc, 1, mDrawTextureCoords);
528*8975f5c5SAndroid Build Coastguard Worker         setUniform2fv(&executable, programState.drawTextureDimsLoc, 1, mDrawTextureDims);
529*8975f5c5SAndroid Build Coastguard Worker     }
530*8975f5c5SAndroid Build Coastguard Worker 
531*8975f5c5SAndroid Build Coastguard Worker     gles1State->clearDirty();
532*8975f5c5SAndroid Build Coastguard Worker 
533*8975f5c5SAndroid Build Coastguard Worker     // None of those are changes in sampler, so there is no need to set the GL_PROGRAM dirty.
534*8975f5c5SAndroid Build Coastguard Worker     // Otherwise, put the dirtying here.
535*8975f5c5SAndroid Build Coastguard Worker 
536*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
537*8975f5c5SAndroid Build Coastguard Worker }
538*8975f5c5SAndroid Build Coastguard Worker 
539*8975f5c5SAndroid Build Coastguard Worker // static
VertexArrayIndex(ClientVertexArrayType type,const GLES1State & gles1)540*8975f5c5SAndroid Build Coastguard Worker int GLES1Renderer::VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1)
541*8975f5c5SAndroid Build Coastguard Worker {
542*8975f5c5SAndroid Build Coastguard Worker     switch (type)
543*8975f5c5SAndroid Build Coastguard Worker     {
544*8975f5c5SAndroid Build Coastguard Worker         case ClientVertexArrayType::Vertex:
545*8975f5c5SAndroid Build Coastguard Worker             return kVertexAttribIndex;
546*8975f5c5SAndroid Build Coastguard Worker         case ClientVertexArrayType::Normal:
547*8975f5c5SAndroid Build Coastguard Worker             return kNormalAttribIndex;
548*8975f5c5SAndroid Build Coastguard Worker         case ClientVertexArrayType::Color:
549*8975f5c5SAndroid Build Coastguard Worker             return kColorAttribIndex;
550*8975f5c5SAndroid Build Coastguard Worker         case ClientVertexArrayType::PointSize:
551*8975f5c5SAndroid Build Coastguard Worker             return kPointSizeAttribIndex;
552*8975f5c5SAndroid Build Coastguard Worker         case ClientVertexArrayType::TextureCoord:
553*8975f5c5SAndroid Build Coastguard Worker             return kTextureCoordAttribIndexBase + gles1.getClientTextureUnit();
554*8975f5c5SAndroid Build Coastguard Worker         default:
555*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
556*8975f5c5SAndroid Build Coastguard Worker             return 0;
557*8975f5c5SAndroid Build Coastguard Worker     }
558*8975f5c5SAndroid Build Coastguard Worker }
559*8975f5c5SAndroid Build Coastguard Worker 
560*8975f5c5SAndroid Build Coastguard Worker // static
VertexArrayType(int attribIndex)561*8975f5c5SAndroid Build Coastguard Worker ClientVertexArrayType GLES1Renderer::VertexArrayType(int attribIndex)
562*8975f5c5SAndroid Build Coastguard Worker {
563*8975f5c5SAndroid Build Coastguard Worker     switch (attribIndex)
564*8975f5c5SAndroid Build Coastguard Worker     {
565*8975f5c5SAndroid Build Coastguard Worker         case kVertexAttribIndex:
566*8975f5c5SAndroid Build Coastguard Worker             return ClientVertexArrayType::Vertex;
567*8975f5c5SAndroid Build Coastguard Worker         case kNormalAttribIndex:
568*8975f5c5SAndroid Build Coastguard Worker             return ClientVertexArrayType::Normal;
569*8975f5c5SAndroid Build Coastguard Worker         case kColorAttribIndex:
570*8975f5c5SAndroid Build Coastguard Worker             return ClientVertexArrayType::Color;
571*8975f5c5SAndroid Build Coastguard Worker         case kPointSizeAttribIndex:
572*8975f5c5SAndroid Build Coastguard Worker             return ClientVertexArrayType::PointSize;
573*8975f5c5SAndroid Build Coastguard Worker         default:
574*8975f5c5SAndroid Build Coastguard Worker             if (attribIndex < kTextureCoordAttribIndexBase + kTexUnitCount)
575*8975f5c5SAndroid Build Coastguard Worker             {
576*8975f5c5SAndroid Build Coastguard Worker                 return ClientVertexArrayType::TextureCoord;
577*8975f5c5SAndroid Build Coastguard Worker             }
578*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
579*8975f5c5SAndroid Build Coastguard Worker             return ClientVertexArrayType::InvalidEnum;
580*8975f5c5SAndroid Build Coastguard Worker     }
581*8975f5c5SAndroid Build Coastguard Worker }
582*8975f5c5SAndroid Build Coastguard Worker 
583*8975f5c5SAndroid Build Coastguard Worker // static
TexCoordArrayIndex(unsigned int unit)584*8975f5c5SAndroid Build Coastguard Worker int GLES1Renderer::TexCoordArrayIndex(unsigned int unit)
585*8975f5c5SAndroid Build Coastguard Worker {
586*8975f5c5SAndroid Build Coastguard Worker     return kTextureCoordAttribIndexBase + unit;
587*8975f5c5SAndroid Build Coastguard Worker }
588*8975f5c5SAndroid Build Coastguard Worker 
drawTexture(Context * context,State * glState,GLES1State * gles1State,float x,float y,float z,float width,float height)589*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::drawTexture(Context *context,
590*8975f5c5SAndroid Build Coastguard Worker                                 State *glState,
591*8975f5c5SAndroid Build Coastguard Worker                                 GLES1State *gles1State,
592*8975f5c5SAndroid Build Coastguard Worker                                 float x,
593*8975f5c5SAndroid Build Coastguard Worker                                 float y,
594*8975f5c5SAndroid Build Coastguard Worker                                 float z,
595*8975f5c5SAndroid Build Coastguard Worker                                 float width,
596*8975f5c5SAndroid Build Coastguard Worker                                 float height)
597*8975f5c5SAndroid Build Coastguard Worker {
598*8975f5c5SAndroid Build Coastguard Worker 
599*8975f5c5SAndroid Build Coastguard Worker     // get viewport
600*8975f5c5SAndroid Build Coastguard Worker     const gl::Rectangle &viewport = glState->getViewport();
601*8975f5c5SAndroid Build Coastguard Worker 
602*8975f5c5SAndroid Build Coastguard Worker     // Translate from viewport to NDC for feeding the shader.
603*8975f5c5SAndroid Build Coastguard Worker     // Recenter, rescale. (e.g., [0, 0, 1080, 1920] -> [-1, -1, 1, 1])
604*8975f5c5SAndroid Build Coastguard Worker     float xNdc = scaleScreenCoordinateToNdc(x, static_cast<GLfloat>(viewport.width));
605*8975f5c5SAndroid Build Coastguard Worker     float yNdc = scaleScreenCoordinateToNdc(y, static_cast<GLfloat>(viewport.height));
606*8975f5c5SAndroid Build Coastguard Worker     float wNdc = scaleScreenDimensionToNdc(width, static_cast<GLfloat>(viewport.width));
607*8975f5c5SAndroid Build Coastguard Worker     float hNdc = scaleScreenDimensionToNdc(height, static_cast<GLfloat>(viewport.height));
608*8975f5c5SAndroid Build Coastguard Worker 
609*8975f5c5SAndroid Build Coastguard Worker     float zNdc = 2.0f * clamp(z, 0.0f, 1.0f) - 1.0f;
610*8975f5c5SAndroid Build Coastguard Worker 
611*8975f5c5SAndroid Build Coastguard Worker     mDrawTextureCoords[0] = xNdc;
612*8975f5c5SAndroid Build Coastguard Worker     mDrawTextureCoords[1] = yNdc;
613*8975f5c5SAndroid Build Coastguard Worker     mDrawTextureCoords[2] = zNdc;
614*8975f5c5SAndroid Build Coastguard Worker 
615*8975f5c5SAndroid Build Coastguard Worker     mDrawTextureDims[0] = wNdc;
616*8975f5c5SAndroid Build Coastguard Worker     mDrawTextureDims[1] = hNdc;
617*8975f5c5SAndroid Build Coastguard Worker 
618*8975f5c5SAndroid Build Coastguard Worker     mDrawTextureEnabled = true;
619*8975f5c5SAndroid Build Coastguard Worker 
620*8975f5c5SAndroid Build Coastguard Worker     AttributesMask prevAttributesMask = glState->gles1().getVertexArraysAttributeMask();
621*8975f5c5SAndroid Build Coastguard Worker 
622*8975f5c5SAndroid Build Coastguard Worker     setAttributesEnabled(context, glState, gles1State, AttributesMask());
623*8975f5c5SAndroid Build Coastguard Worker 
624*8975f5c5SAndroid Build Coastguard Worker     gles1State->setAllDirty();
625*8975f5c5SAndroid Build Coastguard Worker 
626*8975f5c5SAndroid Build Coastguard Worker     context->drawArrays(PrimitiveMode::Triangles, 0, 6);
627*8975f5c5SAndroid Build Coastguard Worker 
628*8975f5c5SAndroid Build Coastguard Worker     setAttributesEnabled(context, glState, gles1State, prevAttributesMask);
629*8975f5c5SAndroid Build Coastguard Worker 
630*8975f5c5SAndroid Build Coastguard Worker     mDrawTextureEnabled = false;
631*8975f5c5SAndroid Build Coastguard Worker }
632*8975f5c5SAndroid Build Coastguard Worker 
getShader(ShaderProgramID handle) const633*8975f5c5SAndroid Build Coastguard Worker Shader *GLES1Renderer::getShader(ShaderProgramID handle) const
634*8975f5c5SAndroid Build Coastguard Worker {
635*8975f5c5SAndroid Build Coastguard Worker     return mShaderPrograms->getShader(handle);
636*8975f5c5SAndroid Build Coastguard Worker }
637*8975f5c5SAndroid Build Coastguard Worker 
getProgram(ShaderProgramID handle) const638*8975f5c5SAndroid Build Coastguard Worker Program *GLES1Renderer::getProgram(ShaderProgramID handle) const
639*8975f5c5SAndroid Build Coastguard Worker {
640*8975f5c5SAndroid Build Coastguard Worker     return mShaderPrograms->getProgram(handle);
641*8975f5c5SAndroid Build Coastguard Worker }
642*8975f5c5SAndroid Build Coastguard Worker 
compileShader(Context * context,ShaderType shaderType,const char * src,ShaderProgramID * shaderOut)643*8975f5c5SAndroid Build Coastguard Worker angle::Result GLES1Renderer::compileShader(Context *context,
644*8975f5c5SAndroid Build Coastguard Worker                                            ShaderType shaderType,
645*8975f5c5SAndroid Build Coastguard Worker                                            const char *src,
646*8975f5c5SAndroid Build Coastguard Worker                                            ShaderProgramID *shaderOut)
647*8975f5c5SAndroid Build Coastguard Worker {
648*8975f5c5SAndroid Build Coastguard Worker     rx::ContextImpl *implementation = context->getImplementation();
649*8975f5c5SAndroid Build Coastguard Worker     const Limitations &limitations  = implementation->getNativeLimitations();
650*8975f5c5SAndroid Build Coastguard Worker 
651*8975f5c5SAndroid Build Coastguard Worker     ShaderProgramID shader = mShaderPrograms->createShader(implementation, limitations, shaderType);
652*8975f5c5SAndroid Build Coastguard Worker 
653*8975f5c5SAndroid Build Coastguard Worker     Shader *shaderObject = getShader(shader);
654*8975f5c5SAndroid Build Coastguard Worker     ANGLE_CHECK(context, shaderObject, "Missing shader object", GL_INVALID_OPERATION);
655*8975f5c5SAndroid Build Coastguard Worker 
656*8975f5c5SAndroid Build Coastguard Worker     shaderObject->setSource(context, 1, &src, nullptr);
657*8975f5c5SAndroid Build Coastguard Worker     shaderObject->compile(context, angle::JobResultExpectancy::Immediate);
658*8975f5c5SAndroid Build Coastguard Worker 
659*8975f5c5SAndroid Build Coastguard Worker     *shaderOut = shader;
660*8975f5c5SAndroid Build Coastguard Worker 
661*8975f5c5SAndroid Build Coastguard Worker     if (!shaderObject->isCompiled(context))
662*8975f5c5SAndroid Build Coastguard Worker     {
663*8975f5c5SAndroid Build Coastguard Worker         GLint infoLogLength = shaderObject->getInfoLogLength(context);
664*8975f5c5SAndroid Build Coastguard Worker         std::vector<char> infoLog(infoLogLength, 0);
665*8975f5c5SAndroid Build Coastguard Worker         shaderObject->getInfoLog(context, infoLogLength - 1, nullptr, infoLog.data());
666*8975f5c5SAndroid Build Coastguard Worker 
667*8975f5c5SAndroid Build Coastguard Worker         ERR() << "Internal GLES 1 shader compile failed. Info log: " << infoLog.data();
668*8975f5c5SAndroid Build Coastguard Worker         ERR() << "Shader source:" << src;
669*8975f5c5SAndroid Build Coastguard Worker         ANGLE_CHECK(context, false, "GLES1Renderer shader compile failed.", GL_INVALID_OPERATION);
670*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Stop;
671*8975f5c5SAndroid Build Coastguard Worker     }
672*8975f5c5SAndroid Build Coastguard Worker 
673*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
674*8975f5c5SAndroid Build Coastguard Worker }
675*8975f5c5SAndroid Build Coastguard Worker 
linkProgram(Context * context,State * glState,ShaderProgramID vertexShader,ShaderProgramID fragmentShader,const angle::HashMap<GLint,std::string> & attribLocs,ShaderProgramID * programOut)676*8975f5c5SAndroid Build Coastguard Worker angle::Result GLES1Renderer::linkProgram(Context *context,
677*8975f5c5SAndroid Build Coastguard Worker                                          State *glState,
678*8975f5c5SAndroid Build Coastguard Worker                                          ShaderProgramID vertexShader,
679*8975f5c5SAndroid Build Coastguard Worker                                          ShaderProgramID fragmentShader,
680*8975f5c5SAndroid Build Coastguard Worker                                          const angle::HashMap<GLint, std::string> &attribLocs,
681*8975f5c5SAndroid Build Coastguard Worker                                          ShaderProgramID *programOut)
682*8975f5c5SAndroid Build Coastguard Worker {
683*8975f5c5SAndroid Build Coastguard Worker     ShaderProgramID program = mShaderPrograms->createProgram(context->getImplementation());
684*8975f5c5SAndroid Build Coastguard Worker 
685*8975f5c5SAndroid Build Coastguard Worker     Program *programObject = getProgram(program);
686*8975f5c5SAndroid Build Coastguard Worker     ANGLE_CHECK(context, programObject, "Missing program object", GL_INVALID_OPERATION);
687*8975f5c5SAndroid Build Coastguard Worker 
688*8975f5c5SAndroid Build Coastguard Worker     *programOut = program;
689*8975f5c5SAndroid Build Coastguard Worker 
690*8975f5c5SAndroid Build Coastguard Worker     programObject->attachShader(context, getShader(vertexShader));
691*8975f5c5SAndroid Build Coastguard Worker     programObject->attachShader(context, getShader(fragmentShader));
692*8975f5c5SAndroid Build Coastguard Worker 
693*8975f5c5SAndroid Build Coastguard Worker     for (auto it : attribLocs)
694*8975f5c5SAndroid Build Coastguard Worker     {
695*8975f5c5SAndroid Build Coastguard Worker         GLint index             = it.first;
696*8975f5c5SAndroid Build Coastguard Worker         const std::string &name = it.second;
697*8975f5c5SAndroid Build Coastguard Worker         programObject->bindAttributeLocation(context, index, name.c_str());
698*8975f5c5SAndroid Build Coastguard Worker     }
699*8975f5c5SAndroid Build Coastguard Worker 
700*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(programObject->link(context, angle::JobResultExpectancy::Immediate));
701*8975f5c5SAndroid Build Coastguard Worker     programObject->resolveLink(context);
702*8975f5c5SAndroid Build Coastguard Worker 
703*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(glState->setProgram(context, programObject));
704*8975f5c5SAndroid Build Coastguard Worker 
705*8975f5c5SAndroid Build Coastguard Worker     if (!programObject->isLinked())
706*8975f5c5SAndroid Build Coastguard Worker     {
707*8975f5c5SAndroid Build Coastguard Worker         GLint infoLogLength = programObject->getInfoLogLength();
708*8975f5c5SAndroid Build Coastguard Worker         std::vector<char> infoLog(infoLogLength, 0);
709*8975f5c5SAndroid Build Coastguard Worker         programObject->getInfoLog(infoLogLength - 1, nullptr, infoLog.data());
710*8975f5c5SAndroid Build Coastguard Worker 
711*8975f5c5SAndroid Build Coastguard Worker         ERR() << "Internal GLES 1 shader link failed. Info log: " << infoLog.data();
712*8975f5c5SAndroid Build Coastguard Worker         ANGLE_CHECK(context, false, "GLES1Renderer program link failed.", GL_INVALID_OPERATION);
713*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Stop;
714*8975f5c5SAndroid Build Coastguard Worker     }
715*8975f5c5SAndroid Build Coastguard Worker 
716*8975f5c5SAndroid Build Coastguard Worker     programObject->detachShader(context, getShader(vertexShader));
717*8975f5c5SAndroid Build Coastguard Worker     programObject->detachShader(context, getShader(fragmentShader));
718*8975f5c5SAndroid Build Coastguard Worker 
719*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
720*8975f5c5SAndroid Build Coastguard Worker }
721*8975f5c5SAndroid Build Coastguard Worker 
getShaderBool(GLES1StateEnables state)722*8975f5c5SAndroid Build Coastguard Worker const char *GLES1Renderer::getShaderBool(GLES1StateEnables state)
723*8975f5c5SAndroid Build Coastguard Worker {
724*8975f5c5SAndroid Build Coastguard Worker     if (mShaderState.mGLES1StateEnabled[state])
725*8975f5c5SAndroid Build Coastguard Worker     {
726*8975f5c5SAndroid Build Coastguard Worker         return "true";
727*8975f5c5SAndroid Build Coastguard Worker     }
728*8975f5c5SAndroid Build Coastguard Worker     else
729*8975f5c5SAndroid Build Coastguard Worker     {
730*8975f5c5SAndroid Build Coastguard Worker         return "false";
731*8975f5c5SAndroid Build Coastguard Worker     }
732*8975f5c5SAndroid Build Coastguard Worker }
733*8975f5c5SAndroid Build Coastguard Worker 
addShaderDefine(std::stringstream & outStream,GLES1StateEnables state,const char * enableString)734*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::addShaderDefine(std::stringstream &outStream,
735*8975f5c5SAndroid Build Coastguard Worker                                     GLES1StateEnables state,
736*8975f5c5SAndroid Build Coastguard Worker                                     const char *enableString)
737*8975f5c5SAndroid Build Coastguard Worker {
738*8975f5c5SAndroid Build Coastguard Worker     outStream << "\n";
739*8975f5c5SAndroid Build Coastguard Worker     outStream << "#define " << enableString << " " << getShaderBool(state);
740*8975f5c5SAndroid Build Coastguard Worker }
741*8975f5c5SAndroid Build Coastguard Worker 
addShaderUint(std::stringstream & outStream,const char * name,uint16_t value)742*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::addShaderUint(std::stringstream &outStream, const char *name, uint16_t value)
743*8975f5c5SAndroid Build Coastguard Worker {
744*8975f5c5SAndroid Build Coastguard Worker     outStream << "\n";
745*8975f5c5SAndroid Build Coastguard Worker     outStream << "const uint " << name << " = " << value << "u;";
746*8975f5c5SAndroid Build Coastguard Worker }
747*8975f5c5SAndroid Build Coastguard Worker 
addShaderUintTexArray(std::stringstream & outStream,const char * texString,GLES1ShaderState::UintTexArray & texState)748*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::addShaderUintTexArray(std::stringstream &outStream,
749*8975f5c5SAndroid Build Coastguard Worker                                           const char *texString,
750*8975f5c5SAndroid Build Coastguard Worker                                           GLES1ShaderState::UintTexArray &texState)
751*8975f5c5SAndroid Build Coastguard Worker {
752*8975f5c5SAndroid Build Coastguard Worker     outStream << "\n";
753*8975f5c5SAndroid Build Coastguard Worker     outStream << "const uint " << texString << "[kMaxTexUnits] = uint[kMaxTexUnits](";
754*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
755*8975f5c5SAndroid Build Coastguard Worker     {
756*8975f5c5SAndroid Build Coastguard Worker         if (i != 0)
757*8975f5c5SAndroid Build Coastguard Worker         {
758*8975f5c5SAndroid Build Coastguard Worker             outStream << ", ";
759*8975f5c5SAndroid Build Coastguard Worker         }
760*8975f5c5SAndroid Build Coastguard Worker         outStream << texState[i] << "u";
761*8975f5c5SAndroid Build Coastguard Worker     }
762*8975f5c5SAndroid Build Coastguard Worker     outStream << ");";
763*8975f5c5SAndroid Build Coastguard Worker }
764*8975f5c5SAndroid Build Coastguard Worker 
addShaderBoolTexArray(std::stringstream & outStream,const char * name,GLES1ShaderState::BoolTexArray & value)765*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::addShaderBoolTexArray(std::stringstream &outStream,
766*8975f5c5SAndroid Build Coastguard Worker                                           const char *name,
767*8975f5c5SAndroid Build Coastguard Worker                                           GLES1ShaderState::BoolTexArray &value)
768*8975f5c5SAndroid Build Coastguard Worker {
769*8975f5c5SAndroid Build Coastguard Worker     outStream << std::boolalpha;
770*8975f5c5SAndroid Build Coastguard Worker     outStream << "\n";
771*8975f5c5SAndroid Build Coastguard Worker     outStream << "bool " << name << "[kMaxTexUnits] = bool[kMaxTexUnits](";
772*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
773*8975f5c5SAndroid Build Coastguard Worker     {
774*8975f5c5SAndroid Build Coastguard Worker         if (i != 0)
775*8975f5c5SAndroid Build Coastguard Worker         {
776*8975f5c5SAndroid Build Coastguard Worker             outStream << ", ";
777*8975f5c5SAndroid Build Coastguard Worker         }
778*8975f5c5SAndroid Build Coastguard Worker         outStream << value[i];
779*8975f5c5SAndroid Build Coastguard Worker     }
780*8975f5c5SAndroid Build Coastguard Worker     outStream << ");";
781*8975f5c5SAndroid Build Coastguard Worker }
782*8975f5c5SAndroid Build Coastguard Worker 
addShaderBoolLightArray(std::stringstream & outStream,const char * name,GLES1ShaderState::BoolLightArray & value)783*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::addShaderBoolLightArray(std::stringstream &outStream,
784*8975f5c5SAndroid Build Coastguard Worker                                             const char *name,
785*8975f5c5SAndroid Build Coastguard Worker                                             GLES1ShaderState::BoolLightArray &value)
786*8975f5c5SAndroid Build Coastguard Worker {
787*8975f5c5SAndroid Build Coastguard Worker     outStream << std::boolalpha;
788*8975f5c5SAndroid Build Coastguard Worker     outStream << "\n";
789*8975f5c5SAndroid Build Coastguard Worker     outStream << "bool " << name << "[kMaxLights] = bool[kMaxLights](";
790*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kLightCount; i++)
791*8975f5c5SAndroid Build Coastguard Worker     {
792*8975f5c5SAndroid Build Coastguard Worker         if (i != 0)
793*8975f5c5SAndroid Build Coastguard Worker         {
794*8975f5c5SAndroid Build Coastguard Worker             outStream << ", ";
795*8975f5c5SAndroid Build Coastguard Worker         }
796*8975f5c5SAndroid Build Coastguard Worker         outStream << value[i];
797*8975f5c5SAndroid Build Coastguard Worker     }
798*8975f5c5SAndroid Build Coastguard Worker     outStream << ");";
799*8975f5c5SAndroid Build Coastguard Worker }
800*8975f5c5SAndroid Build Coastguard Worker 
addShaderBoolClipPlaneArray(std::stringstream & outStream,const char * name,GLES1ShaderState::BoolClipPlaneArray & value)801*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::addShaderBoolClipPlaneArray(std::stringstream &outStream,
802*8975f5c5SAndroid Build Coastguard Worker                                                 const char *name,
803*8975f5c5SAndroid Build Coastguard Worker                                                 GLES1ShaderState::BoolClipPlaneArray &value)
804*8975f5c5SAndroid Build Coastguard Worker {
805*8975f5c5SAndroid Build Coastguard Worker     outStream << std::boolalpha;
806*8975f5c5SAndroid Build Coastguard Worker     outStream << "\n";
807*8975f5c5SAndroid Build Coastguard Worker     outStream << "bool " << name << "[kMaxClipPlanes] = bool[kMaxClipPlanes](";
808*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kClipPlaneCount; i++)
809*8975f5c5SAndroid Build Coastguard Worker     {
810*8975f5c5SAndroid Build Coastguard Worker         if (i != 0)
811*8975f5c5SAndroid Build Coastguard Worker         {
812*8975f5c5SAndroid Build Coastguard Worker             outStream << ", ";
813*8975f5c5SAndroid Build Coastguard Worker         }
814*8975f5c5SAndroid Build Coastguard Worker         outStream << value[i];
815*8975f5c5SAndroid Build Coastguard Worker     }
816*8975f5c5SAndroid Build Coastguard Worker     outStream << ");";
817*8975f5c5SAndroid Build Coastguard Worker }
818*8975f5c5SAndroid Build Coastguard Worker 
addVertexShaderDefs(std::stringstream & outStream)819*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::addVertexShaderDefs(std::stringstream &outStream)
820*8975f5c5SAndroid Build Coastguard Worker {
821*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::Lighting, "enable_lighting");
822*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::ColorMaterial, "enable_color_material");
823*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::DrawTexture, "enable_draw_texture");
824*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::PointRasterization, "point_rasterization");
825*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::RescaleNormal, "enable_rescale_normal");
826*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::Normalize, "enable_normalize");
827*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::LightModelTwoSided, "light_model_two_sided");
828*8975f5c5SAndroid Build Coastguard Worker 
829*8975f5c5SAndroid Build Coastguard Worker     // bool light_enables[kMaxLights] = bool[kMaxLights](...);
830*8975f5c5SAndroid Build Coastguard Worker     addShaderBoolLightArray(outStream, "light_enables", mShaderState.lightEnables);
831*8975f5c5SAndroid Build Coastguard Worker }
832*8975f5c5SAndroid Build Coastguard Worker 
addFragmentShaderDefs(std::stringstream & outStream)833*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::addFragmentShaderDefs(std::stringstream &outStream)
834*8975f5c5SAndroid Build Coastguard Worker {
835*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::Fog, "enable_fog");
836*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::ClipPlanes, "enable_clip_planes");
837*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::DrawTexture, "enable_draw_texture");
838*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::PointRasterization, "point_rasterization");
839*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::PointSprite, "point_sprite_enabled");
840*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::AlphaTest, "enable_alpha_test");
841*8975f5c5SAndroid Build Coastguard Worker     addShaderDefine(outStream, GLES1StateEnables::ShadeModelFlat, "shade_model_flat");
842*8975f5c5SAndroid Build Coastguard Worker 
843*8975f5c5SAndroid Build Coastguard Worker     // bool enable_texture_2d[kMaxTexUnits] = bool[kMaxTexUnits](...);
844*8975f5c5SAndroid Build Coastguard Worker     addShaderBoolTexArray(outStream, "enable_texture_2d", mShaderState.tex2DEnables);
845*8975f5c5SAndroid Build Coastguard Worker 
846*8975f5c5SAndroid Build Coastguard Worker     // bool enable_texture_cube_map[kMaxTexUnits] = bool[kMaxTexUnits](...);
847*8975f5c5SAndroid Build Coastguard Worker     addShaderBoolTexArray(outStream, "enable_texture_cube_map", mShaderState.texCubeEnables);
848*8975f5c5SAndroid Build Coastguard Worker 
849*8975f5c5SAndroid Build Coastguard Worker     // int texture_format[kMaxTexUnits] = int[kMaxTexUnits](...);
850*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "texture_format", mShaderState.tex2DFormats);
851*8975f5c5SAndroid Build Coastguard Worker 
852*8975f5c5SAndroid Build Coastguard Worker     // bool point_sprite_coord_replace[kMaxTexUnits] = bool[kMaxTexUnits](...);
853*8975f5c5SAndroid Build Coastguard Worker     addShaderBoolTexArray(outStream, "point_sprite_coord_replace",
854*8975f5c5SAndroid Build Coastguard Worker                           mShaderState.pointSpriteCoordReplaces);
855*8975f5c5SAndroid Build Coastguard Worker 
856*8975f5c5SAndroid Build Coastguard Worker     // bool clip_plane_enables[kMaxClipPlanes] = bool[kMaxClipPlanes](...);
857*8975f5c5SAndroid Build Coastguard Worker     addShaderBoolClipPlaneArray(outStream, "clip_plane_enables", mShaderState.clipPlaneEnables);
858*8975f5c5SAndroid Build Coastguard Worker 
859*8975f5c5SAndroid Build Coastguard Worker     // int texture_format[kMaxTexUnits] = int[kMaxTexUnits](...);
860*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "texture_env_mode", mShaderState.texEnvModes);
861*8975f5c5SAndroid Build Coastguard Worker 
862*8975f5c5SAndroid Build Coastguard Worker     // int combine_rgb[kMaxTexUnits];
863*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "combine_rgb", mShaderState.texCombineRgbs);
864*8975f5c5SAndroid Build Coastguard Worker 
865*8975f5c5SAndroid Build Coastguard Worker     // int combine_alpha[kMaxTexUnits];
866*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "combine_alpha", mShaderState.texCombineAlphas);
867*8975f5c5SAndroid Build Coastguard Worker 
868*8975f5c5SAndroid Build Coastguard Worker     // int src0_rgb[kMaxTexUnits];
869*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "src0_rgb", mShaderState.texCombineSrc0Rgbs);
870*8975f5c5SAndroid Build Coastguard Worker 
871*8975f5c5SAndroid Build Coastguard Worker     // int src0_alpha[kMaxTexUnits];
872*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "src0_alpha", mShaderState.texCombineSrc0Alphas);
873*8975f5c5SAndroid Build Coastguard Worker 
874*8975f5c5SAndroid Build Coastguard Worker     // int src1_rgb[kMaxTexUnits];
875*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "src1_rgb", mShaderState.texCombineSrc1Rgbs);
876*8975f5c5SAndroid Build Coastguard Worker 
877*8975f5c5SAndroid Build Coastguard Worker     // int src1_alpha[kMaxTexUnits];
878*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "src1_alpha", mShaderState.texCombineSrc1Alphas);
879*8975f5c5SAndroid Build Coastguard Worker 
880*8975f5c5SAndroid Build Coastguard Worker     // int src2_rgb[kMaxTexUnits];
881*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "src2_rgb", mShaderState.texCombineSrc2Rgbs);
882*8975f5c5SAndroid Build Coastguard Worker 
883*8975f5c5SAndroid Build Coastguard Worker     // int src2_alpha[kMaxTexUnits];
884*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "src2_alpha", mShaderState.texCombineSrc2Alphas);
885*8975f5c5SAndroid Build Coastguard Worker 
886*8975f5c5SAndroid Build Coastguard Worker     // int op0_rgb[kMaxTexUnits];
887*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "op0_rgb", mShaderState.texCombineOp0Rgbs);
888*8975f5c5SAndroid Build Coastguard Worker 
889*8975f5c5SAndroid Build Coastguard Worker     // int op0_alpha[kMaxTexUnits];
890*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "op0_alpha", mShaderState.texCombineOp0Alphas);
891*8975f5c5SAndroid Build Coastguard Worker 
892*8975f5c5SAndroid Build Coastguard Worker     // int op1_rgb[kMaxTexUnits];
893*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "op1_rgb", mShaderState.texCombineOp1Rgbs);
894*8975f5c5SAndroid Build Coastguard Worker 
895*8975f5c5SAndroid Build Coastguard Worker     // int op1_alpha[kMaxTexUnits];
896*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "op1_alpha", mShaderState.texCombineOp1Alphas);
897*8975f5c5SAndroid Build Coastguard Worker 
898*8975f5c5SAndroid Build Coastguard Worker     // int op2_rgb[kMaxTexUnits];
899*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "op2_rgb", mShaderState.texCombineOp2Rgbs);
900*8975f5c5SAndroid Build Coastguard Worker 
901*8975f5c5SAndroid Build Coastguard Worker     // int op2_alpha[kMaxTexUnits];
902*8975f5c5SAndroid Build Coastguard Worker     addShaderUintTexArray(outStream, "op2_alpha", mShaderState.texCombineOp2Alphas);
903*8975f5c5SAndroid Build Coastguard Worker 
904*8975f5c5SAndroid Build Coastguard Worker     // int alpha_func;
905*8975f5c5SAndroid Build Coastguard Worker     addShaderUint(outStream, "alpha_func",
906*8975f5c5SAndroid Build Coastguard Worker                   static_cast<uint16_t>(ToGLenum(mShaderState.alphaTestFunc)));
907*8975f5c5SAndroid Build Coastguard Worker 
908*8975f5c5SAndroid Build Coastguard Worker     // int fog_mode;
909*8975f5c5SAndroid Build Coastguard Worker     addShaderUint(outStream, "fog_mode", static_cast<uint16_t>(ToGLenum(mShaderState.fogMode)));
910*8975f5c5SAndroid Build Coastguard Worker }
911*8975f5c5SAndroid Build Coastguard Worker 
initializeRendererProgram(Context * context,State * glState,GLES1State * gles1State)912*8975f5c5SAndroid Build Coastguard Worker angle::Result GLES1Renderer::initializeRendererProgram(Context *context,
913*8975f5c5SAndroid Build Coastguard Worker                                                        State *glState,
914*8975f5c5SAndroid Build Coastguard Worker                                                        GLES1State *gles1State)
915*8975f5c5SAndroid Build Coastguard Worker {
916*8975f5c5SAndroid Build Coastguard Worker     // See if we have the shader for this combination of states
917*8975f5c5SAndroid Build Coastguard Worker     if (mUberShaderState.find(mShaderState) != mUberShaderState.end())
918*8975f5c5SAndroid Build Coastguard Worker     {
919*8975f5c5SAndroid Build Coastguard Worker         Program *programObject = getProgram(getUberShaderState().programState.program);
920*8975f5c5SAndroid Build Coastguard Worker 
921*8975f5c5SAndroid Build Coastguard Worker         // If this is different than the current program, we need to sync everything
922*8975f5c5SAndroid Build Coastguard Worker         // TODO: This could be optimized to only dirty state that differs between the two programs
923*8975f5c5SAndroid Build Coastguard Worker         if (glState->getProgram()->id() != programObject->id())
924*8975f5c5SAndroid Build Coastguard Worker         {
925*8975f5c5SAndroid Build Coastguard Worker             gles1State->setAllDirty();
926*8975f5c5SAndroid Build Coastguard Worker         }
927*8975f5c5SAndroid Build Coastguard Worker 
928*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(glState->setProgram(context, programObject));
929*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
930*8975f5c5SAndroid Build Coastguard Worker     }
931*8975f5c5SAndroid Build Coastguard Worker 
932*8975f5c5SAndroid Build Coastguard Worker     if (!mRendererProgramInitialized)
933*8975f5c5SAndroid Build Coastguard Worker     {
934*8975f5c5SAndroid Build Coastguard Worker         mShaderPrograms = new ShaderProgramManager();
935*8975f5c5SAndroid Build Coastguard Worker     }
936*8975f5c5SAndroid Build Coastguard Worker 
937*8975f5c5SAndroid Build Coastguard Worker     // If we get here, we don't have a shader for this state, need to create it
938*8975f5c5SAndroid Build Coastguard Worker     GLES1ProgramState &programState = mUberShaderState[mShaderState].programState;
939*8975f5c5SAndroid Build Coastguard Worker 
940*8975f5c5SAndroid Build Coastguard Worker     ShaderProgramID vertexShader;
941*8975f5c5SAndroid Build Coastguard Worker     ShaderProgramID fragmentShader;
942*8975f5c5SAndroid Build Coastguard Worker 
943*8975f5c5SAndroid Build Coastguard Worker     // Set the count of texture units to a minimum to avoid requiring unnecessary vertex attributes
944*8975f5c5SAndroid Build Coastguard Worker     // and take up varying slots.
945*8975f5c5SAndroid Build Coastguard Worker     uint32_t maxTexUnitsEnabled = 0;
946*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
947*8975f5c5SAndroid Build Coastguard Worker     {
948*8975f5c5SAndroid Build Coastguard Worker         if (mShaderState.texCubeEnables[i] || mShaderState.tex2DEnables[i])
949*8975f5c5SAndroid Build Coastguard Worker         {
950*8975f5c5SAndroid Build Coastguard Worker             maxTexUnitsEnabled = i + 1;
951*8975f5c5SAndroid Build Coastguard Worker         }
952*8975f5c5SAndroid Build Coastguard Worker     }
953*8975f5c5SAndroid Build Coastguard Worker 
954*8975f5c5SAndroid Build Coastguard Worker     std::stringstream GLES1DrawVShaderStateDefs;
955*8975f5c5SAndroid Build Coastguard Worker     addVertexShaderDefs(GLES1DrawVShaderStateDefs);
956*8975f5c5SAndroid Build Coastguard Worker 
957*8975f5c5SAndroid Build Coastguard Worker     std::stringstream vertexStream;
958*8975f5c5SAndroid Build Coastguard Worker     vertexStream << kGLES1DrawVShaderHeader;
959*8975f5c5SAndroid Build Coastguard Worker     vertexStream << kGLES1TexUnitsDefine << maxTexUnitsEnabled << "u\n";
960*8975f5c5SAndroid Build Coastguard Worker     vertexStream << GLES1DrawVShaderStateDefs.str();
961*8975f5c5SAndroid Build Coastguard Worker     vertexStream << kGLES1DrawVShader;
962*8975f5c5SAndroid Build Coastguard Worker 
963*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(
964*8975f5c5SAndroid Build Coastguard Worker         compileShader(context, ShaderType::Vertex, vertexStream.str().c_str(), &vertexShader));
965*8975f5c5SAndroid Build Coastguard Worker 
966*8975f5c5SAndroid Build Coastguard Worker     std::stringstream GLES1DrawFShaderStateDefs;
967*8975f5c5SAndroid Build Coastguard Worker     addFragmentShaderDefs(GLES1DrawFShaderStateDefs);
968*8975f5c5SAndroid Build Coastguard Worker 
969*8975f5c5SAndroid Build Coastguard Worker     std::stringstream fragmentStream;
970*8975f5c5SAndroid Build Coastguard Worker     fragmentStream << kGLES1DrawFShaderVersion;
971*8975f5c5SAndroid Build Coastguard Worker     if (mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch])
972*8975f5c5SAndroid Build Coastguard Worker     {
973*8975f5c5SAndroid Build Coastguard Worker         if (context->getExtensions().shaderFramebufferFetchEXT)
974*8975f5c5SAndroid Build Coastguard Worker         {
975*8975f5c5SAndroid Build Coastguard Worker             fragmentStream << "#extension GL_EXT_shader_framebuffer_fetch : require\n";
976*8975f5c5SAndroid Build Coastguard Worker         }
977*8975f5c5SAndroid Build Coastguard Worker         else
978*8975f5c5SAndroid Build Coastguard Worker         {
979*8975f5c5SAndroid Build Coastguard Worker             fragmentStream << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require\n";
980*8975f5c5SAndroid Build Coastguard Worker         }
981*8975f5c5SAndroid Build Coastguard Worker     }
982*8975f5c5SAndroid Build Coastguard Worker     fragmentStream << kGLES1DrawFShaderHeader;
983*8975f5c5SAndroid Build Coastguard Worker     fragmentStream << kGLES1TexUnitsDefine << maxTexUnitsEnabled << "u\n";
984*8975f5c5SAndroid Build Coastguard Worker     fragmentStream << GLES1DrawFShaderStateDefs.str();
985*8975f5c5SAndroid Build Coastguard Worker     fragmentStream << kGLES1DrawFShaderUniformDefs;
986*8975f5c5SAndroid Build Coastguard Worker     if (mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch])
987*8975f5c5SAndroid Build Coastguard Worker     {
988*8975f5c5SAndroid Build Coastguard Worker         if (context->getExtensions().shaderFramebufferFetchEXT)
989*8975f5c5SAndroid Build Coastguard Worker         {
990*8975f5c5SAndroid Build Coastguard Worker             fragmentStream << kGLES1DrawFShaderFramebufferFetchOutputDef;
991*8975f5c5SAndroid Build Coastguard Worker         }
992*8975f5c5SAndroid Build Coastguard Worker         else
993*8975f5c5SAndroid Build Coastguard Worker         {
994*8975f5c5SAndroid Build Coastguard Worker             fragmentStream << kGLES1DrawFShaderFramebufferFetchNonCoherentOutputDef;
995*8975f5c5SAndroid Build Coastguard Worker         }
996*8975f5c5SAndroid Build Coastguard Worker         fragmentStream << kGLES1DrawFShaderLogicOpFramebufferFetchEnabled;
997*8975f5c5SAndroid Build Coastguard Worker     }
998*8975f5c5SAndroid Build Coastguard Worker     else
999*8975f5c5SAndroid Build Coastguard Worker     {
1000*8975f5c5SAndroid Build Coastguard Worker         fragmentStream << kGLES1DrawFShaderOutputDef;
1001*8975f5c5SAndroid Build Coastguard Worker         fragmentStream << kGLES1DrawFShaderLogicOpFramebufferFetchDisabled;
1002*8975f5c5SAndroid Build Coastguard Worker     }
1003*8975f5c5SAndroid Build Coastguard Worker     fragmentStream << kGLES1DrawFShaderFunctions;
1004*8975f5c5SAndroid Build Coastguard Worker     fragmentStream << kGLES1DrawFShaderMultitexturing;
1005*8975f5c5SAndroid Build Coastguard Worker     fragmentStream << kGLES1DrawFShaderMain;
1006*8975f5c5SAndroid Build Coastguard Worker 
1007*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(compileShader(context, ShaderType::Fragment, fragmentStream.str().c_str(),
1008*8975f5c5SAndroid Build Coastguard Worker                             &fragmentShader));
1009*8975f5c5SAndroid Build Coastguard Worker 
1010*8975f5c5SAndroid Build Coastguard Worker     angle::HashMap<GLint, std::string> attribLocs;
1011*8975f5c5SAndroid Build Coastguard Worker 
1012*8975f5c5SAndroid Build Coastguard Worker     attribLocs[(GLint)kVertexAttribIndex]    = "pos";
1013*8975f5c5SAndroid Build Coastguard Worker     attribLocs[(GLint)kNormalAttribIndex]    = "normal";
1014*8975f5c5SAndroid Build Coastguard Worker     attribLocs[(GLint)kColorAttribIndex]     = "color";
1015*8975f5c5SAndroid Build Coastguard Worker     attribLocs[(GLint)kPointSizeAttribIndex] = "pointsize";
1016*8975f5c5SAndroid Build Coastguard Worker 
1017*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
1018*8975f5c5SAndroid Build Coastguard Worker     {
1019*8975f5c5SAndroid Build Coastguard Worker         std::stringstream ss;
1020*8975f5c5SAndroid Build Coastguard Worker         ss << "texcoord" << i;
1021*8975f5c5SAndroid Build Coastguard Worker         attribLocs[kTextureCoordAttribIndexBase + i] = ss.str();
1022*8975f5c5SAndroid Build Coastguard Worker     }
1023*8975f5c5SAndroid Build Coastguard Worker 
1024*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(linkProgram(context, glState, vertexShader, fragmentShader, attribLocs,
1025*8975f5c5SAndroid Build Coastguard Worker                           &programState.program));
1026*8975f5c5SAndroid Build Coastguard Worker 
1027*8975f5c5SAndroid Build Coastguard Worker     mShaderPrograms->deleteShader(context, vertexShader);
1028*8975f5c5SAndroid Build Coastguard Worker     mShaderPrograms->deleteShader(context, fragmentShader);
1029*8975f5c5SAndroid Build Coastguard Worker 
1030*8975f5c5SAndroid Build Coastguard Worker     Program *programObject        = getProgram(programState.program);
1031*8975f5c5SAndroid Build Coastguard Worker     ProgramExecutable &executable = programObject->getExecutable();
1032*8975f5c5SAndroid Build Coastguard Worker 
1033*8975f5c5SAndroid Build Coastguard Worker     programState.projMatrixLoc      = executable.getUniformLocation("projection");
1034*8975f5c5SAndroid Build Coastguard Worker     programState.modelviewMatrixLoc = executable.getUniformLocation("modelview");
1035*8975f5c5SAndroid Build Coastguard Worker     programState.textureMatrixLoc   = executable.getUniformLocation("texture_matrix");
1036*8975f5c5SAndroid Build Coastguard Worker     programState.modelviewInvTrLoc  = executable.getUniformLocation("modelview_invtr");
1037*8975f5c5SAndroid Build Coastguard Worker 
1038*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
1039*8975f5c5SAndroid Build Coastguard Worker     {
1040*8975f5c5SAndroid Build Coastguard Worker         std::stringstream ss2d;
1041*8975f5c5SAndroid Build Coastguard Worker         std::stringstream sscube;
1042*8975f5c5SAndroid Build Coastguard Worker 
1043*8975f5c5SAndroid Build Coastguard Worker         ss2d << "tex_sampler" << i;
1044*8975f5c5SAndroid Build Coastguard Worker         sscube << "tex_cube_sampler" << i;
1045*8975f5c5SAndroid Build Coastguard Worker 
1046*8975f5c5SAndroid Build Coastguard Worker         programState.tex2DSamplerLocs[i]   = executable.getUniformLocation(ss2d.str().c_str());
1047*8975f5c5SAndroid Build Coastguard Worker         programState.texCubeSamplerLocs[i] = executable.getUniformLocation(sscube.str().c_str());
1048*8975f5c5SAndroid Build Coastguard Worker     }
1049*8975f5c5SAndroid Build Coastguard Worker 
1050*8975f5c5SAndroid Build Coastguard Worker     programState.textureEnvColorLoc = executable.getUniformLocation("texture_env_color");
1051*8975f5c5SAndroid Build Coastguard Worker     programState.rgbScaleLoc        = executable.getUniformLocation("texture_env_rgb_scale");
1052*8975f5c5SAndroid Build Coastguard Worker     programState.alphaScaleLoc      = executable.getUniformLocation("texture_env_alpha_scale");
1053*8975f5c5SAndroid Build Coastguard Worker 
1054*8975f5c5SAndroid Build Coastguard Worker     programState.alphaTestRefLoc = executable.getUniformLocation("alpha_test_ref");
1055*8975f5c5SAndroid Build Coastguard Worker 
1056*8975f5c5SAndroid Build Coastguard Worker     programState.materialAmbientLoc  = executable.getUniformLocation("material_ambient");
1057*8975f5c5SAndroid Build Coastguard Worker     programState.materialDiffuseLoc  = executable.getUniformLocation("material_diffuse");
1058*8975f5c5SAndroid Build Coastguard Worker     programState.materialSpecularLoc = executable.getUniformLocation("material_specular");
1059*8975f5c5SAndroid Build Coastguard Worker     programState.materialEmissiveLoc = executable.getUniformLocation("material_emissive");
1060*8975f5c5SAndroid Build Coastguard Worker     programState.materialSpecularExponentLoc =
1061*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("material_specular_exponent");
1062*8975f5c5SAndroid Build Coastguard Worker 
1063*8975f5c5SAndroid Build Coastguard Worker     programState.lightModelSceneAmbientLoc =
1064*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("light_model_scene_ambient");
1065*8975f5c5SAndroid Build Coastguard Worker 
1066*8975f5c5SAndroid Build Coastguard Worker     programState.lightAmbientsLoc   = executable.getUniformLocation("light_ambients");
1067*8975f5c5SAndroid Build Coastguard Worker     programState.lightDiffusesLoc   = executable.getUniformLocation("light_diffuses");
1068*8975f5c5SAndroid Build Coastguard Worker     programState.lightSpecularsLoc  = executable.getUniformLocation("light_speculars");
1069*8975f5c5SAndroid Build Coastguard Worker     programState.lightPositionsLoc  = executable.getUniformLocation("light_positions");
1070*8975f5c5SAndroid Build Coastguard Worker     programState.lightDirectionsLoc = executable.getUniformLocation("light_directions");
1071*8975f5c5SAndroid Build Coastguard Worker     programState.lightSpotlightExponentsLoc =
1072*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("light_spotlight_exponents");
1073*8975f5c5SAndroid Build Coastguard Worker     programState.lightSpotlightCutoffAnglesLoc =
1074*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("light_spotlight_cutoff_angles");
1075*8975f5c5SAndroid Build Coastguard Worker     programState.lightAttenuationConstsLoc =
1076*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("light_attenuation_consts");
1077*8975f5c5SAndroid Build Coastguard Worker     programState.lightAttenuationLinearsLoc =
1078*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("light_attenuation_linears");
1079*8975f5c5SAndroid Build Coastguard Worker     programState.lightAttenuationQuadraticsLoc =
1080*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("light_attenuation_quadratics");
1081*8975f5c5SAndroid Build Coastguard Worker 
1082*8975f5c5SAndroid Build Coastguard Worker     programState.fogDensityLoc = executable.getUniformLocation("fog_density");
1083*8975f5c5SAndroid Build Coastguard Worker     programState.fogStartLoc   = executable.getUniformLocation("fog_start");
1084*8975f5c5SAndroid Build Coastguard Worker     programState.fogEndLoc     = executable.getUniformLocation("fog_end");
1085*8975f5c5SAndroid Build Coastguard Worker     programState.fogColorLoc   = executable.getUniformLocation("fog_color");
1086*8975f5c5SAndroid Build Coastguard Worker 
1087*8975f5c5SAndroid Build Coastguard Worker     programState.clipPlanesLoc = executable.getUniformLocation("clip_planes");
1088*8975f5c5SAndroid Build Coastguard Worker 
1089*8975f5c5SAndroid Build Coastguard Worker     programState.logicOpLoc = executable.getUniformLocation("logic_op");
1090*8975f5c5SAndroid Build Coastguard Worker 
1091*8975f5c5SAndroid Build Coastguard Worker     programState.pointSizeMinLoc = executable.getUniformLocation("point_size_min");
1092*8975f5c5SAndroid Build Coastguard Worker     programState.pointSizeMaxLoc = executable.getUniformLocation("point_size_max");
1093*8975f5c5SAndroid Build Coastguard Worker     programState.pointDistanceAttenuationLoc =
1094*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("point_distance_attenuation");
1095*8975f5c5SAndroid Build Coastguard Worker 
1096*8975f5c5SAndroid Build Coastguard Worker     programState.drawTextureCoordsLoc = executable.getUniformLocation("draw_texture_coords");
1097*8975f5c5SAndroid Build Coastguard Worker     programState.drawTextureDimsLoc   = executable.getUniformLocation("draw_texture_dims");
1098*8975f5c5SAndroid Build Coastguard Worker     programState.drawTextureNormalizedCropRectLoc =
1099*8975f5c5SAndroid Build Coastguard Worker         executable.getUniformLocation("draw_texture_normalized_crop_rect");
1100*8975f5c5SAndroid Build Coastguard Worker 
1101*8975f5c5SAndroid Build Coastguard Worker     ANGLE_TRY(glState->setProgram(context, programObject));
1102*8975f5c5SAndroid Build Coastguard Worker 
1103*8975f5c5SAndroid Build Coastguard Worker     for (int i = 0; i < kTexUnitCount; i++)
1104*8975f5c5SAndroid Build Coastguard Worker     {
1105*8975f5c5SAndroid Build Coastguard Worker         setUniform1i(context, &executable, programState.tex2DSamplerLocs[i], i);
1106*8975f5c5SAndroid Build Coastguard Worker         setUniform1i(context, &executable, programState.texCubeSamplerLocs[i], i + kTexUnitCount);
1107*8975f5c5SAndroid Build Coastguard Worker     }
1108*8975f5c5SAndroid Build Coastguard Worker 
1109*8975f5c5SAndroid Build Coastguard Worker     // We just created a new program, we need to sync everything
1110*8975f5c5SAndroid Build Coastguard Worker     gles1State->setAllDirty();
1111*8975f5c5SAndroid Build Coastguard Worker 
1112*8975f5c5SAndroid Build Coastguard Worker     mRendererProgramInitialized = true;
1113*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
1114*8975f5c5SAndroid Build Coastguard Worker }
1115*8975f5c5SAndroid Build Coastguard Worker 
setUniform1i(Context * context,ProgramExecutable * executable,UniformLocation location,GLint value)1116*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniform1i(Context *context,
1117*8975f5c5SAndroid Build Coastguard Worker                                  ProgramExecutable *executable,
1118*8975f5c5SAndroid Build Coastguard Worker                                  UniformLocation location,
1119*8975f5c5SAndroid Build Coastguard Worker                                  GLint value)
1120*8975f5c5SAndroid Build Coastguard Worker {
1121*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1122*8975f5c5SAndroid Build Coastguard Worker         return;
1123*8975f5c5SAndroid Build Coastguard Worker     executable->setUniform1iv(context, location, 1, &value);
1124*8975f5c5SAndroid Build Coastguard Worker }
1125*8975f5c5SAndroid Build Coastguard Worker 
setUniform1ui(ProgramExecutable * executable,UniformLocation location,GLuint value)1126*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniform1ui(ProgramExecutable *executable,
1127*8975f5c5SAndroid Build Coastguard Worker                                   UniformLocation location,
1128*8975f5c5SAndroid Build Coastguard Worker                                   GLuint value)
1129*8975f5c5SAndroid Build Coastguard Worker {
1130*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1131*8975f5c5SAndroid Build Coastguard Worker         return;
1132*8975f5c5SAndroid Build Coastguard Worker     executable->setUniform1uiv(location, 1, &value);
1133*8975f5c5SAndroid Build Coastguard Worker }
1134*8975f5c5SAndroid Build Coastguard Worker 
setUniform1iv(Context * context,ProgramExecutable * executable,UniformLocation location,GLint count,const GLint * value)1135*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniform1iv(Context *context,
1136*8975f5c5SAndroid Build Coastguard Worker                                   ProgramExecutable *executable,
1137*8975f5c5SAndroid Build Coastguard Worker                                   UniformLocation location,
1138*8975f5c5SAndroid Build Coastguard Worker                                   GLint count,
1139*8975f5c5SAndroid Build Coastguard Worker                                   const GLint *value)
1140*8975f5c5SAndroid Build Coastguard Worker {
1141*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1142*8975f5c5SAndroid Build Coastguard Worker         return;
1143*8975f5c5SAndroid Build Coastguard Worker     executable->setUniform1iv(context, location, count, value);
1144*8975f5c5SAndroid Build Coastguard Worker }
1145*8975f5c5SAndroid Build Coastguard Worker 
setUniformMatrix4fv(ProgramExecutable * executable,UniformLocation location,GLint count,GLboolean transpose,const GLfloat * value)1146*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniformMatrix4fv(ProgramExecutable *executable,
1147*8975f5c5SAndroid Build Coastguard Worker                                         UniformLocation location,
1148*8975f5c5SAndroid Build Coastguard Worker                                         GLint count,
1149*8975f5c5SAndroid Build Coastguard Worker                                         GLboolean transpose,
1150*8975f5c5SAndroid Build Coastguard Worker                                         const GLfloat *value)
1151*8975f5c5SAndroid Build Coastguard Worker {
1152*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1153*8975f5c5SAndroid Build Coastguard Worker         return;
1154*8975f5c5SAndroid Build Coastguard Worker     executable->setUniformMatrix4fv(location, count, transpose, value);
1155*8975f5c5SAndroid Build Coastguard Worker }
1156*8975f5c5SAndroid Build Coastguard Worker 
setUniform4fv(ProgramExecutable * executable,UniformLocation location,GLint count,const GLfloat * value)1157*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniform4fv(ProgramExecutable *executable,
1158*8975f5c5SAndroid Build Coastguard Worker                                   UniformLocation location,
1159*8975f5c5SAndroid Build Coastguard Worker                                   GLint count,
1160*8975f5c5SAndroid Build Coastguard Worker                                   const GLfloat *value)
1161*8975f5c5SAndroid Build Coastguard Worker {
1162*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1163*8975f5c5SAndroid Build Coastguard Worker         return;
1164*8975f5c5SAndroid Build Coastguard Worker     executable->setUniform4fv(location, count, value);
1165*8975f5c5SAndroid Build Coastguard Worker }
1166*8975f5c5SAndroid Build Coastguard Worker 
setUniform3fv(ProgramExecutable * executable,UniformLocation location,GLint count,const GLfloat * value)1167*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniform3fv(ProgramExecutable *executable,
1168*8975f5c5SAndroid Build Coastguard Worker                                   UniformLocation location,
1169*8975f5c5SAndroid Build Coastguard Worker                                   GLint count,
1170*8975f5c5SAndroid Build Coastguard Worker                                   const GLfloat *value)
1171*8975f5c5SAndroid Build Coastguard Worker {
1172*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1173*8975f5c5SAndroid Build Coastguard Worker         return;
1174*8975f5c5SAndroid Build Coastguard Worker     executable->setUniform3fv(location, count, value);
1175*8975f5c5SAndroid Build Coastguard Worker }
1176*8975f5c5SAndroid Build Coastguard Worker 
setUniform2fv(ProgramExecutable * executable,UniformLocation location,GLint count,const GLfloat * value)1177*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniform2fv(ProgramExecutable *executable,
1178*8975f5c5SAndroid Build Coastguard Worker                                   UniformLocation location,
1179*8975f5c5SAndroid Build Coastguard Worker                                   GLint count,
1180*8975f5c5SAndroid Build Coastguard Worker                                   const GLfloat *value)
1181*8975f5c5SAndroid Build Coastguard Worker {
1182*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1183*8975f5c5SAndroid Build Coastguard Worker         return;
1184*8975f5c5SAndroid Build Coastguard Worker     executable->setUniform2fv(location, count, value);
1185*8975f5c5SAndroid Build Coastguard Worker }
1186*8975f5c5SAndroid Build Coastguard Worker 
setUniform1f(ProgramExecutable * executable,UniformLocation location,GLfloat value)1187*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniform1f(ProgramExecutable *executable,
1188*8975f5c5SAndroid Build Coastguard Worker                                  UniformLocation location,
1189*8975f5c5SAndroid Build Coastguard Worker                                  GLfloat value)
1190*8975f5c5SAndroid Build Coastguard Worker {
1191*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1192*8975f5c5SAndroid Build Coastguard Worker         return;
1193*8975f5c5SAndroid Build Coastguard Worker     executable->setUniform1fv(location, 1, &value);
1194*8975f5c5SAndroid Build Coastguard Worker }
1195*8975f5c5SAndroid Build Coastguard Worker 
setUniform1fv(ProgramExecutable * executable,UniformLocation location,GLint count,const GLfloat * value)1196*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setUniform1fv(ProgramExecutable *executable,
1197*8975f5c5SAndroid Build Coastguard Worker                                   UniformLocation location,
1198*8975f5c5SAndroid Build Coastguard Worker                                   GLint count,
1199*8975f5c5SAndroid Build Coastguard Worker                                   const GLfloat *value)
1200*8975f5c5SAndroid Build Coastguard Worker {
1201*8975f5c5SAndroid Build Coastguard Worker     if (location.value == -1)
1202*8975f5c5SAndroid Build Coastguard Worker         return;
1203*8975f5c5SAndroid Build Coastguard Worker     executable->setUniform1fv(location, count, value);
1204*8975f5c5SAndroid Build Coastguard Worker }
1205*8975f5c5SAndroid Build Coastguard Worker 
setAttributesEnabled(Context * context,State * glState,GLES1State * gles1State,AttributesMask mask)1206*8975f5c5SAndroid Build Coastguard Worker void GLES1Renderer::setAttributesEnabled(Context *context,
1207*8975f5c5SAndroid Build Coastguard Worker                                          State *glState,
1208*8975f5c5SAndroid Build Coastguard Worker                                          GLES1State *gles1State,
1209*8975f5c5SAndroid Build Coastguard Worker                                          AttributesMask mask)
1210*8975f5c5SAndroid Build Coastguard Worker {
1211*8975f5c5SAndroid Build Coastguard Worker     ClientVertexArrayType nonTexcoordArrays[] = {
1212*8975f5c5SAndroid Build Coastguard Worker         ClientVertexArrayType::Vertex,
1213*8975f5c5SAndroid Build Coastguard Worker         ClientVertexArrayType::Normal,
1214*8975f5c5SAndroid Build Coastguard Worker         ClientVertexArrayType::Color,
1215*8975f5c5SAndroid Build Coastguard Worker         ClientVertexArrayType::PointSize,
1216*8975f5c5SAndroid Build Coastguard Worker     };
1217*8975f5c5SAndroid Build Coastguard Worker 
1218*8975f5c5SAndroid Build Coastguard Worker     for (const ClientVertexArrayType attrib : nonTexcoordArrays)
1219*8975f5c5SAndroid Build Coastguard Worker     {
1220*8975f5c5SAndroid Build Coastguard Worker         int index = VertexArrayIndex(attrib, *gles1State);
1221*8975f5c5SAndroid Build Coastguard Worker 
1222*8975f5c5SAndroid Build Coastguard Worker         if (mask.test(index))
1223*8975f5c5SAndroid Build Coastguard Worker         {
1224*8975f5c5SAndroid Build Coastguard Worker             gles1State->setClientStateEnabled(attrib, true);
1225*8975f5c5SAndroid Build Coastguard Worker             context->enableVertexAttribArray(index);
1226*8975f5c5SAndroid Build Coastguard Worker         }
1227*8975f5c5SAndroid Build Coastguard Worker         else
1228*8975f5c5SAndroid Build Coastguard Worker         {
1229*8975f5c5SAndroid Build Coastguard Worker             gles1State->setClientStateEnabled(attrib, false);
1230*8975f5c5SAndroid Build Coastguard Worker             context->disableVertexAttribArray(index);
1231*8975f5c5SAndroid Build Coastguard Worker         }
1232*8975f5c5SAndroid Build Coastguard Worker     }
1233*8975f5c5SAndroid Build Coastguard Worker 
1234*8975f5c5SAndroid Build Coastguard Worker     for (unsigned int i = 0; i < kTexUnitCount; i++)
1235*8975f5c5SAndroid Build Coastguard Worker     {
1236*8975f5c5SAndroid Build Coastguard Worker         int index = TexCoordArrayIndex(i);
1237*8975f5c5SAndroid Build Coastguard Worker 
1238*8975f5c5SAndroid Build Coastguard Worker         if (mask.test(index))
1239*8975f5c5SAndroid Build Coastguard Worker         {
1240*8975f5c5SAndroid Build Coastguard Worker             gles1State->setTexCoordArrayEnabled(i, true);
1241*8975f5c5SAndroid Build Coastguard Worker             context->enableVertexAttribArray(index);
1242*8975f5c5SAndroid Build Coastguard Worker         }
1243*8975f5c5SAndroid Build Coastguard Worker         else
1244*8975f5c5SAndroid Build Coastguard Worker         {
1245*8975f5c5SAndroid Build Coastguard Worker             gles1State->setTexCoordArrayEnabled(i, false);
1246*8975f5c5SAndroid Build Coastguard Worker             context->disableVertexAttribArray(index);
1247*8975f5c5SAndroid Build Coastguard Worker         }
1248*8975f5c5SAndroid Build Coastguard Worker     }
1249*8975f5c5SAndroid Build Coastguard Worker }
1250*8975f5c5SAndroid Build Coastguard Worker 
1251*8975f5c5SAndroid Build Coastguard Worker }  // namespace gl
1252