aboutsummaryrefslogtreecommitdiff
path: root/src/scene-conditionals.cpp
blob: 778cb337fd8d88a3524116b6d986aba63361dee8 (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
/*
 * Copyright © 2010-2011 Linaro Limited
 *
 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
 *
 * glmark2 is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * glmark2.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *  Alexandros Frantzis (glmark2)
 */
#include "scene.h"
#include "mat.h"
#include "stack.h"
#include "vec.h"
#include "log.h"
#include "shader-source.h"
#include "util.h"

#include <cmath>

static const std::string shader_file_base(GLMARK_DATA_PATH"/shaders/conditionals");

static const std::string vtx_file(shader_file_base + ".vert");
static const std::string frg_file(shader_file_base + ".frag");
static const std::string step_conditional_file(shader_file_base + "-step-conditional.all");
static const std::string step_simple_file(shader_file_base + "-step-simple.all");

SceneConditionals::SceneConditionals(Canvas &pCanvas) :
    SceneGrid(pCanvas, "conditionals")
{
    options_["fragment-steps"] = Scene::Option("fragment-steps", "1",
            "The number of computational steps in the fragment shader");
    options_["fragment-conditionals"] = Scene::Option("fragment-conditionals", "true",
            "Whether each computational step includes an if-else clause", "false,true");
    options_["vertex-steps"] = Scene::Option("vertex-steps", "1",
            "The number of computational steps in the vertex shader");
    options_["vertex-conditionals"] = Scene::Option("vertex-conditionals", "true",
            "Whether each computational step includes an if-else clause", "false,true");
}

SceneConditionals::~SceneConditionals()
{
}

static std::string
get_vertex_shader_source(int steps, bool conditionals)
{
    ShaderSource source(vtx_file);
    ShaderSource source_main;

    for (int i = 0; i < steps; i++) {
        if (conditionals)
            source_main.append_file(step_conditional_file);
        else
            source_main.append_file(step_simple_file);
    }

    source.replace("$MAIN$", source_main.str());

    return source.str();
}

static std::string
get_fragment_shader_source(int steps, bool conditionals)
{
    ShaderSource source(frg_file);
    ShaderSource source_main;

    for (int i = 0; i < steps; i++) {
        if (conditionals)
            source_main.append_file(step_conditional_file);
        else
            source_main.append_file(step_simple_file);
    }

    source.replace("$MAIN$", source_main.str());

    return source.str();
}

bool
SceneConditionals::setup()
{
    if (!SceneGrid::setup())
        return false;

    /* Parse options */
    bool vtx_conditionals = options_["vertex-conditionals"].value == "true";
    bool frg_conditionals = options_["fragment-conditionals"].value == "true";
    int vtx_steps(Util::fromString<int>(options_["vertex-steps"].value));
    int frg_steps(Util::fromString<int>(options_["fragment-steps"].value));
    /* Load shaders */
    std::string vtx_shader(get_vertex_shader_source(vtx_steps, vtx_conditionals));
    std::string frg_shader(get_fragment_shader_source(frg_steps, frg_conditionals));

    if (!Scene::load_shaders_from_strings(program_, vtx_shader, frg_shader))
        return false;

    program_.start();

    std::vector<GLint> attrib_locations;
    attrib_locations.push_back(program_["position"].location());
    mesh_.set_attrib_locations(attrib_locations);

    running_ = true;
    startTime_ = Util::get_timestamp_us() / 1000000.0;
    lastUpdateTime_ = startTime_;

    return true;
}

Scene::ValidationResult
SceneConditionals::validate()
{
    static const double radius_3d(std::sqrt(3.0 * 5.0 * 5.0));

    bool frg_conditionals = options_["fragment-conditionals"].value == "true";
    int frg_steps(Util::fromString<int>(options_["fragment-steps"].value));

    if (!frg_conditionals)
        return Scene::ValidationUnknown;

    Canvas::Pixel ref;

    if (frg_steps == 0)
        ref = Canvas::Pixel(0xa0, 0xa0, 0xa0, 0xff);
    else if (frg_steps == 5)
        ref = Canvas::Pixel(0x25, 0x25, 0x25, 0xff);
    else
        return Scene::ValidationUnknown;

    Canvas::Pixel pixel = canvas_.read_pixel(293, 89);

    double dist = pixel.distance_rgb(ref);
    if (dist < radius_3d + 0.01) {
        return Scene::ValidationSuccess;
    }
    else {
        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
                    ref.to_le32(), pixel.to_le32(), dist);
        return Scene::ValidationFailure;
    }

    return Scene::ValidationUnknown;
}