summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/GLES1State.cpp
blob: 17ad0de3ada654011d7d916400e138ed4da2a9eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// GLES1State.cpp: Implements the GLES1State class, tracking state
// for GLES1 contexts.

#include "libANGLE/GLES1State.h"

#include "libANGLE/Context.h"
#include "libANGLE/GLES1Renderer.h"

namespace gl
{

TextureCoordF::TextureCoordF() = default;

TextureCoordF::TextureCoordF(float _s, float _t, float _r, float _q) : s(_s), t(_t), r(_r), q(_q) {}

bool TextureCoordF::operator==(const TextureCoordF &other) const
{
    return s == other.s && t == other.t && r == other.r && q == other.q;
}

MaterialParameters::MaterialParameters() = default;

LightModelParameters::LightModelParameters() = default;

LightParameters::LightParameters() = default;

LightParameters::LightParameters(const LightParameters &other) = default;

FogParameters::FogParameters() = default;

TextureEnvironmentParameters::TextureEnvironmentParameters() = default;

TextureEnvironmentParameters::TextureEnvironmentParameters(
    const TextureEnvironmentParameters &other) = default;

PointParameters::PointParameters() = default;

PointParameters::PointParameters(const PointParameters &other) = default;

ClipPlaneParameters::ClipPlaneParameters() = default;

ClipPlaneParameters::ClipPlaneParameters(bool enabled, const angle::Vector4 &equation)
    : enabled(enabled), equation(equation)
{}

ClipPlaneParameters::ClipPlaneParameters(const ClipPlaneParameters &other) = default;

ClipPlaneParameters &ClipPlaneParameters::operator=(const ClipPlaneParameters &other) = default;

GLES1State::GLES1State()
    : mGLState(nullptr),
      mVertexArrayEnabled(false),
      mNormalArrayEnabled(false),
      mColorArrayEnabled(false),
      mPointSizeArrayEnabled(false),
      mLineSmoothEnabled(false),
      mPointSmoothEnabled(false),
      mPointSpriteEnabled(false),
      mAlphaTestEnabled(false),
      mLogicOpEnabled(false),
      mLightingEnabled(false),
      mFogEnabled(false),
      mRescaleNormalEnabled(false),
      mNormalizeEnabled(false),
      mColorMaterialEnabled(false),
      mReflectionMapEnabled(false),
      mCurrentColor({0.0f, 0.0f, 0.0f, 0.0f}),
      mCurrentNormal({0.0f, 0.0f, 0.0f}),
      mClientActiveTexture(0),
      mMatrixMode(MatrixType::Modelview),
      mShadeModel(ShadingModel::Smooth),
      mAlphaTestFunc(AlphaTestFunc::AlwaysPass),
      mAlphaTestRef(0.0f),
      mLogicOp(LogicalOperation::Copy),
      mLineSmoothHint(HintSetting::DontCare),
      mPointSmoothHint(HintSetting::DontCare),
      mPerspectiveCorrectionHint(HintSetting::DontCare),
      mFogHint(HintSetting::DontCare)
{}

GLES1State::~GLES1State() = default;

// Taken from the GLES 1.x spec which specifies all initial state values.
void GLES1State::initialize(const Context *context, const State *state)
{
    mGLState = state;

    const Caps &caps = context->getCaps();

    mTexUnitEnables.resize(caps.maxMultitextureUnits);
    for (auto &enables : mTexUnitEnables)
    {
        enables.reset();
    }

    mVertexArrayEnabled    = false;
    mNormalArrayEnabled    = false;
    mColorArrayEnabled     = false;
    mPointSizeArrayEnabled = false;
    mTexCoordArrayEnabled.resize(caps.maxMultitextureUnits, false);

    mLineSmoothEnabled    = false;
    mPointSmoothEnabled   = false;
    mPointSpriteEnabled   = false;
    mLogicOpEnabled       = false;
    mAlphaTestEnabled     = false;
    mLightingEnabled      = false;
    mFogEnabled           = false;
    mRescaleNormalEnabled = false;
    mNormalizeEnabled     = false;
    mColorMaterialEnabled = false;
    mReflectionMapEnabled = false;

    mMatrixMode = MatrixType::Modelview;

    mCurrentColor  = {1.0f, 1.0f, 1.0f, 1.0f};
    mCurrentNormal = {0.0f, 0.0f, 1.0f};
    mCurrentTextureCoords.resize(caps.maxMultitextureUnits);
    mClientActiveTexture = 0;

    mTextureEnvironments.resize(caps.maxMultitextureUnits);

    mModelviewMatrices.push_back(angle::Mat4());
    mProjectionMatrices.push_back(angle::Mat4());
    mTextureMatrices.resize(caps.maxMultitextureUnits);
    for (auto &stack : mTextureMatrices)
    {
        stack.push_back(angle::Mat4());
    }

    mMaterial.ambient  = {0.2f, 0.2f, 0.2f, 1.0f};
    mMaterial.diffuse  = {0.8f, 0.8f, 0.8f, 1.0f};
    mMaterial.specular = {0.0f, 0.0f, 0.0f, 1.0f};
    mMaterial.emissive = {0.0f, 0.0f, 0.0f, 1.0f};

    mMaterial.specularExponent = 0.0f;

    mLightModel.color    = {0.2f, 0.2f, 0.2f, 1.0f};
    mLightModel.twoSided = false;

    mLights.resize(caps.maxLights);

    // GL_LIGHT0 is special and has default state that avoids all-black renderings.
    mLights[0].diffuse  = {1.0f, 1.0f, 1.0f, 1.0f};
    mLights[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};

    mFog.mode    = FogMode::Exp;
    mFog.density = 1.0f;
    mFog.start   = 0.0f;
    mFog.end     = 1.0f;

    mFog.color = {0.0f, 0.0f, 0.0f, 0.0f};

    mShadeModel = ShadingModel::Smooth;

    mAlphaTestFunc = AlphaTestFunc::AlwaysPass;
    mAlphaTestRef  = 0.0f;

    mLogicOp = LogicalOperation::Copy;

    mClipPlanes.resize(caps.maxClipPlanes,
                       ClipPlaneParameters(false, angle::Vector4(0.0f, 0.0f, 0.0f, 0.0f)));

    mLineSmoothHint            = HintSetting::DontCare;
    mPointSmoothHint           = HintSetting::DontCare;
    mPerspectiveCorrectionHint = HintSetting::DontCare;
    mFogHint                   = HintSetting::DontCare;

    // The user-specified point size, GL_POINT_SIZE_MAX,
    // is initially equal to the implementation maximum.
    mPointParameters.pointSizeMax = caps.maxAliasedPointSize;

    mDirtyBits.set();
}

void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref)
{
    setDirty(DIRTY_GLES1_ALPHA_TEST);
    mAlphaTestFunc = func;
    mAlphaTestRef  = ref;
}

void GLES1State::setClientTextureUnit(unsigned int unit)
{
    setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE);
    mClientActiveTexture = unit;
}

unsigned int GLES1State::getClientTextureUnit() const
{
    return mClientActiveTexture;
}

void GLES1State::setCurrentColor(const ColorF &color)
{
    setDirty(DIRTY_GLES1_CURRENT_VECTOR);
    mCurrentColor = color;

    // > When enabled, both the ambient (acm) and diffuse (dcm) properties of both the front and
    // > back material are immediately set to the value of the current color, and will track changes
    // > to the current color resulting from either the Color commands or drawing vertex arrays with
    // > the color array enabled.
    // > The replacements made to material properties are permanent; the replaced values remain
    // > until changed by either sending a new color or by setting a new material value when
    // > COLOR_MATERIAL is not currently enabled, to override that particular value.
    if (isColorMaterialEnabled())
    {
        mMaterial.ambient = color;
        mMaterial.diffuse = color;
    }
}

const ColorF &GLES1State::getCurrentColor() const
{
    return mCurrentColor;
}

void GLES1State::setCurrentNormal(const angle::Vector3 &normal)
{
    setDirty(DIRTY_GLES1_CURRENT_VECTOR);
    mCurrentNormal = normal;
}

const angle::Vector3 &GLES1State::getCurrentNormal() const
{
    return mCurrentNormal;
}

bool GLES1State::shouldHandleDirtyProgram()
{
    bool ret = isDirty(DIRTY_GLES1_PROGRAM);
    clearDirtyBits(DIRTY_GLES1_PROGRAM);
    return ret;
}

void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
{
    setDirty(DIRTY_GLES1_CURRENT_VECTOR);
    mCurrentTextureCoords[unit] = coords;
}

const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const
{
    return mCurrentTextureCoords[unit];
}

void GLES1State::setMatrixMode(MatrixType mode)
{
    setDirty(DIRTY_GLES1_MATRICES);
    mMatrixMode = mode;
}

MatrixType GLES1State::getMatrixMode() const
{
    return mMatrixMode;
}

GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const
{
    switch (queryType)
    {
        case GL_MODELVIEW_STACK_DEPTH:
            return clampCast<GLint>(mModelviewMatrices.size());
        case GL_PROJECTION_STACK_DEPTH:
            return clampCast<GLint>(mProjectionMatrices.size());
        case GL_TEXTURE_STACK_DEPTH:
            return clampCast<GLint>(mTextureMatrices[mGLState->getActiveSampler()].size());
        default:
            UNREACHABLE();
            return 0;
    }
}

void GLES1State::pushMatrix()
{
    setDirty(DIRTY_GLES1_MATRICES);
    auto &stack = currentMatrixStack();
    stack.push_back(stack.back());
}

void GLES1State::popMatrix()
{
    setDirty(DIRTY_GLES1_MATRICES);
    auto &stack = currentMatrixStack();
    stack.pop_back();
}

GLES1State::MatrixStack &GLES1State::currentMatrixStack()
{
    setDirty(DIRTY_GLES1_MATRICES);
    switch (mMatrixMode)
    {
        case MatrixType::Modelview:
            return mModelviewMatrices;
        case MatrixType::Projection:
            return mProjectionMatrices;
        case MatrixType::Texture:
            return mTextureMatrices[mGLState->getActiveSampler()];
        default:
            UNREACHABLE();
            return mModelviewMatrices;
    }
}

const angle::Mat4 &GLES1State::getModelviewMatrix() const
{
    return mModelviewMatrices.back();
}

const GLES1State::MatrixStack &GLES1State::getMatrixStack(MatrixType mode) const
{
    switch (mode)
    {
        case MatrixType::Modelview:
            return mModelviewMatrices;
        case MatrixType::Projection:
            return mProjectionMatrices;
        case MatrixType::Texture:
            return mTextureMatrices[mGLState->getActiveSampler()];
        default:
            UNREACHABLE();
            return mModelviewMatrices;
    }
}

const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
{
    return getMatrixStack(mMatrixMode);
}

void GLES1State::loadMatrix(const angle::Mat4 &m)
{
    setDirty(DIRTY_GLES1_MATRICES);
    currentMatrixStack().back() = m;
}

void GLES1State::multMatrix(const angle::Mat4 &m)
{
    setDirty(DIRTY_GLES1_MATRICES);
    angle::Mat4 currentMatrix   = currentMatrixStack().back();
    currentMatrixStack().back() = currentMatrix.product(m);
}

void GLES1State::setLogicOpEnabled(bool enabled)
{
    setDirty(DIRTY_GLES1_LOGIC_OP);
    mLogicOpEnabled = enabled;
}

void GLES1State::setLogicOp(LogicalOperation opcodePacked)
{
    setDirty(DIRTY_GLES1_LOGIC_OP);
    mLogicOp = opcodePacked;
}

void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
{
    setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
    switch (clientState)
    {
        case ClientVertexArrayType::Vertex:
            mVertexArrayEnabled = enable;
            break;
        case ClientVertexArrayType::Normal:
            mNormalArrayEnabled = enable;
            break;
        case ClientVertexArrayType::Color:
            mColorArrayEnabled = enable;
            break;
        case ClientVertexArrayType::PointSize:
            mPointSizeArrayEnabled = enable;
            break;
        case ClientVertexArrayType::TextureCoord:
            mTexCoordArrayEnabled[mClientActiveTexture] = enable;
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
{
    setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
    mTexCoordArrayEnabled[unit] = enable;
}

bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const
{
    switch (clientState)
    {
        case ClientVertexArrayType::Vertex:
            return mVertexArrayEnabled;
        case ClientVertexArrayType::Normal:
            return mNormalArrayEnabled;
        case ClientVertexArrayType::Color:
            return mColorArrayEnabled;
        case ClientVertexArrayType::PointSize:
            return mPointSizeArrayEnabled;
        case ClientVertexArrayType::TextureCoord:
            return mTexCoordArrayEnabled[mClientActiveTexture];
        default:
            UNREACHABLE();
            return false;
    }
}

bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const
{
    ASSERT(unit < mTexCoordArrayEnabled.size());
    return mTexCoordArrayEnabled[unit];
}

bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const
{
    if (mTexUnitEnables.empty())
    {
        return false;
    }
    return mTexUnitEnables[unit].test(type);
}

LightModelParameters &GLES1State::lightModelParameters()
{
    setDirty(DIRTY_GLES1_LIGHTS);
    return mLightModel;
}

const LightModelParameters &GLES1State::lightModelParameters() const
{
    return mLightModel;
}

LightParameters &GLES1State::lightParameters(unsigned int light)
{
    setDirty(DIRTY_GLES1_LIGHTS);
    return mLights[light];
}

const LightParameters &GLES1State::lightParameters(unsigned int light) const
{
    return mLights[light];
}

MaterialParameters &GLES1State::materialParameters()
{
    setDirty(DIRTY_GLES1_MATERIAL);
    return mMaterial;
}

const MaterialParameters &GLES1State::materialParameters() const
{
    return mMaterial;
}

bool GLES1State::isColorMaterialEnabled() const
{
    return mColorMaterialEnabled;
}

void GLES1State::setShadeModel(ShadingModel model)
{
    setDirty(DIRTY_GLES1_SHADE_MODEL);
    mShadeModel = model;
}

void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
{
    setDirty(DIRTY_GLES1_CLIP_PLANES);
    assert(plane < mClipPlanes.size());
    mClipPlanes[plane].equation[0] = equation[0];
    mClipPlanes[plane].equation[1] = equation[1];
    mClipPlanes[plane].equation[2] = equation[2];
    mClipPlanes[plane].equation[3] = equation[3];
}

void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
{
    assert(plane < mClipPlanes.size());
    equation[0] = mClipPlanes[plane].equation[0];
    equation[1] = mClipPlanes[plane].equation[1];
    equation[2] = mClipPlanes[plane].equation[2];
    equation[3] = mClipPlanes[plane].equation[3];
}

FogParameters &GLES1State::fogParameters()
{
    setDirty(DIRTY_GLES1_FOG);
    return mFog;
}

const FogParameters &GLES1State::fogParameters() const
{
    return mFog;
}

TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
{
    setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
    assert(unit < mTextureEnvironments.size());
    return mTextureEnvironments[unit];
}

const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const
{
    assert(unit < mTextureEnvironments.size());
    return mTextureEnvironments[unit];
}

bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
{
    return a.tie() == b.tie();
}

bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
{
    return !(a == b);
}

PointParameters &GLES1State::pointParameters()
{
    setDirty(DIRTY_GLES1_POINT_PARAMETERS);
    return mPointParameters;
}

const PointParameters &GLES1State::pointParameters() const
{
    return mPointParameters;
}

AttributesMask GLES1State::getVertexArraysAttributeMask() const
{
    AttributesMask attribsMask;

    ClientVertexArrayType nonTexcoordArrays[] = {
        ClientVertexArrayType::Vertex,
        ClientVertexArrayType::Normal,
        ClientVertexArrayType::Color,
        ClientVertexArrayType::PointSize,
    };

    for (const ClientVertexArrayType attrib : nonTexcoordArrays)
    {
        attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this),
                        isClientStateEnabled(attrib));
    }

    for (unsigned int i = 0; i < kTexUnitCount; i++)
    {
        attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i));
    }

    return attribsMask;
}

AttributesMask GLES1State::getActiveAttributesMask() const
{
    // The program always has 8 attributes enabled.
    return AttributesMask(0xFF);
}

void GLES1State::setHint(GLenum target, GLenum mode)
{
    setDirty(DIRTY_GLES1_HINT_SETTING);
    HintSetting setting = FromGLenum<HintSetting>(mode);
    switch (target)
    {
        case GL_PERSPECTIVE_CORRECTION_HINT:
            mPerspectiveCorrectionHint = setting;
            break;
        case GL_POINT_SMOOTH_HINT:
            mPointSmoothHint = setting;
            break;
        case GL_LINE_SMOOTH_HINT:
            mLineSmoothHint = setting;
            break;
        case GL_FOG_HINT:
            mFogHint = setting;
            break;
        default:
            UNREACHABLE();
    }
}

GLenum GLES1State::getHint(GLenum target) const
{
    switch (target)
    {
        case GL_PERSPECTIVE_CORRECTION_HINT:
            return ToGLenum(mPerspectiveCorrectionHint);
        case GL_POINT_SMOOTH_HINT:
            return ToGLenum(mPointSmoothHint);
        case GL_LINE_SMOOTH_HINT:
            return ToGLenum(mLineSmoothHint);
        case GL_FOG_HINT:
            return ToGLenum(mFogHint);
        default:
            UNREACHABLE();
            return 0;
    }
}

}  // namespace gl