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

Side by Side Diff: chrome/gpu/gpu_video_layer_glx.cc

Issue 4399003: Deleted code associated with --enable-gpu-rendering and... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « chrome/gpu/gpu_video_layer_glx.h ('k') | chrome/gpu/gpu_view_win.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 (c) 2010 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 "chrome/gpu/gpu_video_layer_glx.h"
6
7 #include "app/gfx/gl/gl_bindings.h"
8 #include "chrome/common/gpu_messages.h"
9 #include "chrome/gpu/gpu_thread.h"
10 #include "chrome/gpu/gpu_view_x.h"
11
12 // Handy constants for addressing YV12 data.
13 static const int kYUVPlanes = 3;
14 static const int kYPlane = 0;
15 static const int kUPlane = 1;
16 static const int kVPlane = 2;
17
18 // Buffer size for shader compile errors.
19 static const unsigned int kErrorSize = 4096;
20
21 // Matrix used for the YUV to RGB conversion.
22 static const float kYUV2RGB[9] = {
23 1.f, 0.f, 1.403f,
24 1.f, -.344f, -.714f,
25 1.f, 1.772f, 0.f,
26 };
27
28 // Texture coordinates mapping the entire texture.
29 static const float kTextureCoords[8] = {
30 0, 0,
31 0, 1,
32 1, 0,
33 1, 1,
34 };
35
36 #define I915_WORKAROUND
37
38 // Pass-through vertex shader.
39 static const char kVertexShader[] =
40 "varying vec2 interp_tc;\n"
41 "\n"
42 "attribute vec4 in_pos;\n"
43 "attribute vec2 in_tc;\n"
44 "\n"
45 "void main() {\n"
46 #if defined(I915_WORKAROUND)
47 " gl_TexCoord[0].st = in_tc;\n"
48 #else
49 " interp_tc = in_tc;\n"
50 #endif
51 " gl_Position = in_pos;\n"
52 "}\n";
53
54 // YUV to RGB pixel shader. Loads a pixel from each plane and pass through the
55 // matrix.
56 static const char kFragmentShader[] =
57 "varying vec2 interp_tc;\n"
58 "\n"
59 "uniform sampler2D y_tex;\n"
60 "uniform sampler2D u_tex;\n"
61 "uniform sampler2D v_tex;\n"
62 "uniform mat3 yuv2rgb;\n"
63 "\n"
64 "void main() {\n"
65 #if defined(I915_WORKAROUND)
66 " float y = texture2D(y_tex, gl_TexCoord[0].st).x;\n"
67 " float u = texture2D(u_tex, gl_TexCoord[0].st).r - .5;\n"
68 " float v = texture2D(v_tex, gl_TexCoord[0].st).r - .5;\n"
69 " float r = y + v * 1.403;\n"
70 " float g = y - u * 0.344 - v * 0.714;\n"
71 " float b = y + u * 1.772;\n"
72 " gl_FragColor = vec4(r, g, b, 1);\n"
73 #else
74 " float y = texture2D(y_tex, interp_tc).x;\n"
75 " float u = texture2D(u_tex, interp_tc).r - .5;\n"
76 " float v = texture2D(v_tex, interp_tc).r - .5;\n"
77 " vec3 rgb = yuv2rgb * vec3(y, u, v);\n"
78 " gl_FragColor = vec4(rgb, 1);\n"
79 #endif
80 "}\n";
81
82
83 // Assume that somewhere along the line, someone will do width * height * 4
84 // with signed numbers. If the maximum value is 2**31, then 2**31 / 4 =
85 // 2**29 and floor(sqrt(2**29)) = 23170.
86
87 // Max height and width for layers
88 static const int kMaxVideoLayerSize = 23170;
89
90 GpuVideoLayerGLX::GpuVideoLayerGLX(GpuViewX* view,
91 GpuThread* gpu_thread,
92 int32 routing_id,
93 const gfx::Size& size)
94 : view_(view),
95 gpu_thread_(gpu_thread),
96 routing_id_(routing_id),
97 native_size_(size),
98 program_(0) {
99 memset(textures_, 0, sizeof(textures_));
100
101 // Load identity vertices.
102 gfx::Rect identity(0, 0, 1, 1);
103 CalculateVertices(identity.size(), identity, target_vertices_);
104
105 gpu_thread_->AddRoute(routing_id_, this);
106
107 view_->BindContext(); // Must do this before issuing OpenGl.
108
109 // TODO(apatrick): These functions are not available in GLES2.
110 // glMatrixMode(GL_MODELVIEW);
111
112 // Create 3 textures, one for each plane, and bind them to different
113 // texture units.
114 glGenTextures(kYUVPlanes, textures_);
115
116 glBindTexture(GL_TEXTURE_2D, textures_[kYPlane]);
117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
119
120 glBindTexture(GL_TEXTURE_2D, textures_[kUPlane]);
121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
123
124 glBindTexture(GL_TEXTURE_2D, textures_[kVPlane]);
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
127
128 // Create our YUV->RGB shader.
129 program_ = glCreateProgram();
130 GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
131 const char* vs_source = kVertexShader;
132 int vs_size = sizeof(kVertexShader);
133 glShaderSource(vertex_shader, 1, &vs_source, &vs_size);
134 glCompileShader(vertex_shader);
135 int result = GL_FALSE;
136 glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &result);
137 if (!result) {
138 char log[kErrorSize];
139 int len;
140 glGetShaderInfoLog(vertex_shader, kErrorSize - 1, &len, log);
141 log[kErrorSize - 1] = 0;
142 LOG(FATAL) << log;
143 }
144 glAttachShader(program_, vertex_shader);
145 glDeleteShader(vertex_shader);
146
147 GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
148 const char* ps_source = kFragmentShader;
149 int ps_size = sizeof(kFragmentShader);
150 glShaderSource(fragment_shader, 1, &ps_source, &ps_size);
151 glCompileShader(fragment_shader);
152 result = GL_FALSE;
153 glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &result);
154 if (!result) {
155 char log[kErrorSize];
156 int len;
157 glGetShaderInfoLog(fragment_shader, kErrorSize - 1, &len, log);
158 log[kErrorSize - 1] = 0;
159 LOG(FATAL) << log;
160 }
161 glAttachShader(program_, fragment_shader);
162 glDeleteShader(fragment_shader);
163
164 glLinkProgram(program_);
165 result = GL_FALSE;
166 glGetProgramiv(program_, GL_LINK_STATUS, &result);
167 if (!result) {
168 char log[kErrorSize];
169 int len;
170 glGetProgramInfoLog(program_, kErrorSize - 1, &len, log);
171 log[kErrorSize - 1] = 0;
172 LOG(FATAL) << log;
173 }
174 }
175
176 GpuVideoLayerGLX::~GpuVideoLayerGLX() {
177 // TODO(scherkus): this seems like a bad idea.. we might be better off with
178 // separate Initialize()/Teardown() calls instead.
179 view_->BindContext();
180 if (program_) {
181 glDeleteProgram(program_);
182 }
183
184 gpu_thread_->RemoveRoute(routing_id_);
185 }
186
187 void GpuVideoLayerGLX::Render(const gfx::Size& viewport_size) {
188 // Nothing to do if we're not visible or have no YUV data.
189 if (target_rect_.IsEmpty()) {
190 return;
191 }
192
193 // Calculate the position of our quad.
194 CalculateVertices(viewport_size, target_rect_, target_vertices_);
195
196 // Bind Y, U and V textures to texture units.
197 glActiveTexture(GL_TEXTURE0);
198 glBindTexture(GL_TEXTURE_2D, textures_[kYPlane]);
199 glActiveTexture(GL_TEXTURE1);
200 glBindTexture(GL_TEXTURE_2D, textures_[kUPlane]);
201 glActiveTexture(GL_TEXTURE2);
202 glBindTexture(GL_TEXTURE_2D, textures_[kVPlane]);
203
204 // Bind vertex/fragment shader program.
205 glUseProgram(program_);
206
207 // Bind parameters.
208 glUniform1i(glGetUniformLocation(program_, "y_tex"), 0);
209 glUniform1i(glGetUniformLocation(program_, "u_tex"), 1);
210 glUniform1i(glGetUniformLocation(program_, "v_tex"), 2);
211
212 #if !defined(I915_WORKAROUND)
213 int yuv2rgb_location = glGetUniformLocation(program_, "yuv2rgb");
214 glUniformMatrix3fv(yuv2rgb_location, 1, GL_TRUE, kYUV2RGB);
215 #endif
216
217 // TODO(scherkus): instead of calculating and loading a geometry each time,
218 // we should store a constant geometry in a VBO and use a vertex shader.
219 int pos_location = glGetAttribLocation(program_, "in_pos");
220 glEnableVertexAttribArray(pos_location);
221 glVertexAttribPointer(pos_location, 2, GL_FLOAT, GL_FALSE, 0,
222 target_vertices_);
223
224 int tc_location = glGetAttribLocation(program_, "in_tc");
225 glEnableVertexAttribArray(tc_location);
226 glVertexAttribPointer(tc_location, 2, GL_FLOAT, GL_FALSE, 0,
227 kTextureCoords);
228
229 // Render!
230 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
231
232 // Reset back to original state.
233 glDisableVertexAttribArray(pos_location);
234 glDisableVertexAttribArray(tc_location);
235 glActiveTexture(GL_TEXTURE0);
236 glUseProgram(0);
237 }
238
239 void GpuVideoLayerGLX::OnMessageReceived(const IPC::Message& msg) {
240 IPC_BEGIN_MESSAGE_MAP(GpuVideoLayerGLX, msg)
241 IPC_MESSAGE_HANDLER(GpuMsg_PaintToVideoLayer, OnPaintToVideoLayer)
242 IPC_END_MESSAGE_MAP_EX()
243 }
244
245 void GpuVideoLayerGLX::OnChannelConnected(int32 peer_pid) {
246 }
247
248 void GpuVideoLayerGLX::OnChannelError() {
249 // FIXME(brettw) does this mean we aren't getting any more messages and we
250 // should delete outselves?
251 NOTIMPLEMENTED();
252 }
253
254 void GpuVideoLayerGLX::OnPaintToVideoLayer(base::ProcessId source_process_id,
255 TransportDIB::Id id,
256 const gfx::Rect& bitmap_rect) {
257 // TODO(scherkus): |native_size_| is set in constructor, so perhaps this check
258 // should be a DCHECK().
259 const int width = native_size_.width();
260 const int height = native_size_.height();
261 const int stride = width;
262
263 if (width <= 0 || width > kMaxVideoLayerSize ||
264 height <= 0 || height > kMaxVideoLayerSize)
265 return;
266
267 TransportDIB* dib = TransportDIB::Map(id);
268 if (!dib)
269 return;
270
271 // Everything looks good, update our target position and size.
272 target_rect_ = bitmap_rect;
273
274 // Perform colour space conversion.
275 uint8* planes[kYUVPlanes];
276 planes[kYPlane] = reinterpret_cast<uint8*>(dib->memory());
277 planes[kUPlane] = planes[kYPlane] + width * height;
278 planes[kVPlane] = planes[kUPlane] + ((width * height) >> 2);
279
280 view_->BindContext(); // Must do this before issuing OpenGl.
281
282 // Assume YV12 format.
283 for (int i = 0; i < kYUVPlanes; ++i) {
284 int plane_width = (i == kYPlane ? width : width / 2);
285 int plane_height = (i == kYPlane ? height : height / 2);
286 int plane_stride = (i == kYPlane ? stride : stride / 2);
287
288 // Ensure that we will not read outside the shared mem region.
289 if (planes[i] >= planes[kYPlane] &&
290 (dib->size() - (planes[kYPlane] - planes[i])) >=
291 static_cast<unsigned int>(plane_width * plane_height)) {
292 glActiveTexture(GL_TEXTURE0 + i);
293 glBindTexture(GL_TEXTURE_2D, textures_[i]);
294 glPixelStorei(GL_UNPACK_ROW_LENGTH, plane_stride);
295 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, plane_width, plane_height, 0,
296 GL_LUMINANCE, GL_UNSIGNED_BYTE, planes[i]);
297 }
298 }
299
300 // Reset back to original state.
301 glActiveTexture(GL_TEXTURE0);
302 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
303 glFlush();
304
305 // TODO(scherkus): we may not need to ACK video layer updates at all.
306 gpu_thread_->Send(new GpuHostMsg_PaintToVideoLayer_ACK(routing_id_));
307 }
308
309 // static
310 void GpuVideoLayerGLX::CalculateVertices(const gfx::Size& world,
311 const gfx::Rect& object,
312 float* vertices) {
313 // Don't forget GL has a flipped Y-axis!
314 float width = world.width();
315 float height = world.height();
316
317 // Top left.
318 vertices[0] = 2.0f * (object.x() / width) - 1.0f;
319 vertices[1] = -2.0f * (object.y() / height) + 1.0f;
320
321 // Bottom left.
322 vertices[2] = 2.0f * (object.x() / width) - 1.0f;
323 vertices[3] = -2.0f * (object.bottom() / height) + 1.0f;
324
325 // Top right.
326 vertices[4] = 2.0f * (object.right() / width) - 1.0f;
327 vertices[5] = -2.0f * (object.y() / height) + 1.0f;
328
329 // Bottom right.
330 vertices[6] = 2.0f * (object.right() / width) - 1.0f;
331 vertices[7] = -2.0f * (object.bottom() / height) + 1.0f;
332 }
OLDNEW
« no previous file with comments | « chrome/gpu/gpu_video_layer_glx.h ('k') | chrome/gpu/gpu_view_win.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698