Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(671)

Side by Side Diff: remoting/client/gl_render_layer.cc

Issue 2614443003: Moving the GL implementation details into a sub folder for client display. (Closed)
Patch Set: Adding deps restriction on r/c/display; Moving sys_opengl.h Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « remoting/client/gl_render_layer.h ('k') | remoting/client/gl_renderer.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "remoting/client/gl_render_layer.h"
6
7 #include "base/logging.h"
8 #include "remoting/client/gl_canvas.h"
9 #include "remoting/client/gl_helpers.h"
10
11
12 namespace remoting {
13
14 namespace {
15
16 // Assign texture coordinates to buffers for use in shader program.
17 const float kVertices[] = {
18 // Points order: upper-left, bottom-left, upper-right, bottom-right.
19
20 // Positions to draw the texture on the normalized canvas coordinate.
21 0, 0, 0, 0, 0, 0, 0, 0,
22
23 // Region of the texture to be used (normally the whole texture).
24 0, 0, 0, 1, 1, 0, 1, 1};
25
26 const int kDefaultUpdateBufferCapacity =
27 2048 * 2048 * GlRenderLayer::kBytesPerPixel;
28
29 void PackDirtyRegion(uint8_t* dest,
30 const uint8_t* source,
31 int width,
32 int height,
33 int stride) {
34 for (int i = 0; i < height; i++) {
35 memcpy(dest, source, width * GlRenderLayer::kBytesPerPixel);
36 source += stride;
37 dest += GlRenderLayer::kBytesPerPixel * width;
38 }
39 }
40
41 } // namespace
42
43 GlRenderLayer::GlRenderLayer(int texture_id, GlCanvas* canvas)
44 : texture_id_(texture_id), canvas_(canvas) {
45 texture_handle_ = CreateTexture();
46 buffer_handle_ = CreateBuffer(kVertices, sizeof(kVertices));
47 }
48
49 GlRenderLayer::~GlRenderLayer() {
50 DCHECK(thread_checker_.CalledOnValidThread());
51 glDeleteBuffers(1, &buffer_handle_);
52 glDeleteTextures(1, &texture_handle_);
53 }
54
55 void GlRenderLayer::SetTexture(const uint8_t* texture,
56 int width,
57 int height,
58 int stride) {
59 DCHECK(thread_checker_.CalledOnValidThread());
60 CHECK(width > 0 && height > 0);
61 texture_set_ = true;
62 glActiveTexture(GL_TEXTURE0 + texture_id_);
63 glBindTexture(GL_TEXTURE_2D, texture_handle_);
64
65 bool should_reset_row_length;
66 const void* buffer_to_update = PrepareTextureBuffer(
67 texture, width, height, stride, &should_reset_row_length);
68
69 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
70 GL_UNSIGNED_BYTE, buffer_to_update);
71
72 if (should_reset_row_length) {
73 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
74 }
75
76 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
77 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
78 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
79 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
80
81 glBindTexture(GL_TEXTURE_2D, 0);
82 }
83
84 void GlRenderLayer::UpdateTexture(const uint8_t* subtexture,
85 int offset_x,
86 int offset_y,
87 int width,
88 int height,
89 int stride) {
90 DCHECK(thread_checker_.CalledOnValidThread());
91 DCHECK(texture_set_);
92 DCHECK(width > 0 && height > 0);
93 glActiveTexture(GL_TEXTURE0 + texture_id_);
94 glBindTexture(GL_TEXTURE_2D, texture_handle_);
95
96 bool should_reset_row_length;
97 const void* buffer_to_update = PrepareTextureBuffer(
98 subtexture, width, height, stride, &should_reset_row_length);
99
100 glTexSubImage2D(GL_TEXTURE_2D, 0, offset_x, offset_y, width, height, GL_RGBA,
101 GL_UNSIGNED_BYTE, buffer_to_update);
102
103 if (should_reset_row_length) {
104 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
105 }
106
107 glBindTexture(GL_TEXTURE_2D, 0);
108 }
109
110 void GlRenderLayer::SetVertexPositions(const std::array<float, 8>& positions) {
111 DCHECK(thread_checker_.CalledOnValidThread());
112 glBindBuffer(GL_ARRAY_BUFFER, buffer_handle_);
113 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(kVertices) / 2, positions.data());
114 glBindBuffer(GL_ARRAY_BUFFER, 0);
115 vertex_position_set_ = true;
116 }
117
118 void GlRenderLayer::SetTextureVisibleArea(
119 const std::array<float, 8>& positions) {
120 DCHECK(thread_checker_.CalledOnValidThread());
121 glBindBuffer(GL_ARRAY_BUFFER, buffer_handle_);
122 glBufferSubData(GL_ARRAY_BUFFER, sizeof(kVertices) / 2, sizeof(kVertices) / 2,
123 positions.data());
124 glBindBuffer(GL_ARRAY_BUFFER, 0);
125 }
126
127 void GlRenderLayer::Draw(float alpha_multiplier) {
128 DCHECK(thread_checker_.CalledOnValidThread());
129 DCHECK(texture_set_ && vertex_position_set_);
130 canvas_->DrawTexture(texture_id_, texture_handle_, buffer_handle_,
131 alpha_multiplier);
132 }
133
134 const uint8_t* GlRenderLayer::PrepareTextureBuffer(
135 const uint8_t* data,
136 int width,
137 int height,
138 int stride,
139 bool* should_reset_row_length) {
140 *should_reset_row_length = false;
141
142 bool stride_multiple_of_bytes_per_pixel = stride % kBytesPerPixel == 0;
143 bool loosely_packed = !stride_multiple_of_bytes_per_pixel ||
144 (stride > 0 && stride != kBytesPerPixel * width);
145
146 if (!loosely_packed) {
147 return data;
148 }
149
150 if (stride_multiple_of_bytes_per_pixel && canvas_->GetGlVersion() >= 3) {
151 glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / kBytesPerPixel);
152 *should_reset_row_length = true;
153 return data;
154 }
155
156 // Doesn't support GL_UNPACK_ROW_LENGTH or stride not multiple of
157 // kBytesPerPixel. Manually pack the data.
158 int required_size = width * height * kBytesPerPixel;
159 if (update_buffer_size_ < required_size) {
160 if (required_size < kDefaultUpdateBufferCapacity) {
161 update_buffer_size_ = kDefaultUpdateBufferCapacity;
162 } else {
163 update_buffer_size_ = required_size;
164 }
165 update_buffer_.reset(new uint8_t[update_buffer_size_]);
166 }
167 PackDirtyRegion(update_buffer_.get(), data, width, height, stride);
168 return update_buffer_.get();
169 }
170
171 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/client/gl_render_layer.h ('k') | remoting/client/gl_renderer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698