xref: /aosp_15_r20/external/cronet/third_party/quic_trace/src/tools/render/rectangle_renderer.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2018 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "tools/render/rectangle_renderer.h"
16 
17 #include <array>
18 
19 #include "absl/algorithm/container.h"
20 
21 namespace quic_trace {
22 namespace render {
23 
24 namespace {
25 
26 const char* kVertexShader = R"(
27 in vec2 coord;
28 in vec4 color_in;
29 out vec4 color_mid;
30 
31 void main(void) {
32   gl_Position = windowToGl(coord);
33   color_mid = color_in;
34 }
35 )";
36 
37 const char* kFragmentShader = R"(
38 in vec4 color_mid;
39 out vec4 color_out;
40 
41 void main(void) {
42   color_out = color_mid;
43 }
44 )";
45 
46 const char* kLineFragmentShader = R"(
47 out vec4 color_out;
48 void main(void) {
49   color_out = vec4(0, 0, 0, 1);
50 }
51 )";
52 
53 }  // namespace
54 
RectangleRenderer(const ProgramState * state)55 RectangleRenderer::RectangleRenderer(const ProgramState* state)
56     : state_(state),
57       shader_(kVertexShader, kFragmentShader),
58       line_shader_(kVertexShader, kLineFragmentShader) {}
59 
AddRectangle(Box box,uint32_t rgba)60 void RectangleRenderer::AddRectangle(Box box, uint32_t rgba) {
61   rgba = __builtin_bswap32(rgba);
62   // This looks like this:
63   //   2  3
64   //   0  1
65   points_.push_back(Point{box.origin.x, box.origin.y, rgba});               // 0
66   points_.push_back(Point{box.origin.x + box.size.x, box.origin.y, rgba});  // 1
67   points_.push_back(Point{box.origin.x, box.origin.y + box.size.y, rgba});  // 2
68   points_.push_back(
69       Point{box.origin.x + box.size.x, box.origin.y + box.size.y, rgba});  // 3
70 }
71 
AddRectangleWithBorder(Box box,uint32_t rgba)72 void RectangleRenderer::AddRectangleWithBorder(Box box, uint32_t rgba) {
73   const size_t point_buffer_offset = points_.size();
74   AddRectangle(box, rgba);
75 
76   const std::array<uint16_t, 8> lines = {0, 1, 1, 3, 3, 2, 2, 0};
77   line_indices_.resize(line_indices_.size() + 8);
78   absl::c_transform(lines, line_indices_.end() - 8,
79                     [=](uint16_t i) { return i + point_buffer_offset; });
80 }
81 
Render()82 void RectangleRenderer::Render() {
83   GlVertexBuffer point_buffer;
84   glBufferData(GL_ARRAY_BUFFER, points_.size() * sizeof(Point), points_.data(),
85                GL_STREAM_DRAW);
86 
87   const size_t rectangle_count = points_.size() / 4;
88   const size_t point_count = rectangle_count * 6;
89   CHECK(point_count < std::numeric_limits<uint16_t>::max());
90 
91   // Transform points of each rectangle into a pair of triangles.
92   auto indices = std::make_unique<uint16_t[]>(point_count);
93   for (int i = 0; i < rectangle_count; i++) {
94     indices[6 * i + 0] = 4 * i + 0;
95     indices[6 * i + 1] = 4 * i + 1;
96     indices[6 * i + 2] = 4 * i + 2;
97     indices[6 * i + 3] = 4 * i + 2;
98     indices[6 * i + 4] = 4 * i + 3;
99     indices[6 * i + 5] = 4 * i + 1;
100   }
101 
102   glUseProgram(*shader_);
103   state_->Bind(shader_);
104 
105   {
106     GlVertexArray array;
107     glBindVertexArray(*array);
108 
109     GlElementBuffer index_buffer;
110     glBufferData(GL_ELEMENT_ARRAY_BUFFER, point_count * sizeof(indices[0]),
111                  indices.get(), GL_STREAM_DRAW);
112 
113     GlVertexArrayAttrib coord(shader_, "coord");
114     glVertexAttribPointer(*coord, 2, GL_FLOAT, GL_FALSE, sizeof(Point), 0);
115     GlVertexArrayAttrib color(shader_, "color_in");
116     glVertexAttribPointer(*color, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Point),
117                           (void*)offsetof(Point, rgba));
118 
119     glDrawElements(GL_TRIANGLES, point_count, GL_UNSIGNED_SHORT, nullptr);
120     points_.clear();
121   }
122 
123   glUseProgram(*line_shader_);
124   state_->Bind(line_shader_);
125   {
126     GlVertexArray array;
127     glBindVertexArray(*array);
128 
129     GlElementBuffer index_buffer;
130     glBufferData(GL_ELEMENT_ARRAY_BUFFER,
131                  line_indices_.size() * sizeof(line_indices_[0]),
132                  line_indices_.data(), GL_STREAM_DRAW);
133 
134     GlVertexArrayAttrib coord(shader_, "coord");
135     glVertexAttribPointer(*coord, 2, GL_FLOAT, GL_FALSE, sizeof(Point), 0);
136 
137     glDrawElements(GL_LINES, line_indices_.size(), GL_UNSIGNED_SHORT, nullptr);
138     line_indices_.clear();
139   }
140 }
141 
142 }  // namespace render
143 }  // namespace quic_trace
144