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