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