OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "gpu/command_buffer/common/types.h" | |
9 #include "gpu/command_buffer/service/gl_utils.h" | |
10 | |
11 #define SHADER0(Src) #Src | |
12 #define SHADER(Src) SHADER0(Src) | |
13 | |
14 namespace { | |
15 | |
16 const GLfloat kQuadVertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, | |
17 1.0f, -1.0f, 0.0f, 1.0f, | |
18 1.0f, 1.0f, 0.0f, 1.0f, | |
19 -1.0f, 1.0f, 0.0f, 1.0f }; | |
20 | |
21 const GLfloat kTextureCoords[] = { 0.0f, 0.0f, | |
22 1.0f, 0.0f, | |
23 1.0f, 1.0f, | |
24 0.0f, 1.0f }; | |
25 | |
26 const int kNumShaders = 5; | |
27 enum ShaderId { | |
28 VERTEX_SHADER_POS_TEX, | |
29 FRAGMENT_SHADER_TEX, | |
30 FRAGMENT_SHADER_TEX_FLIP_Y, | |
31 FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA, | |
32 FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y | |
33 }; | |
34 | |
35 enum ProgramId { | |
36 PROGRAM_COPY_TEXTURE, | |
37 PROGRAM_COPY_TEXTURE_FLIP_Y, | |
38 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA, | |
39 PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY | |
40 }; | |
41 | |
42 // Returns the correct program to evaluate the copy operation for | |
43 // the CHROMIUM_flipy and premultiply alpha pixel store settings. | |
44 ProgramId GetProgram(bool flip_y, bool premultiply_alpha) { | |
45 if (flip_y && premultiply_alpha) | |
46 return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA_FLIPY; | |
47 | |
48 if (flip_y) | |
49 return PROGRAM_COPY_TEXTURE_FLIP_Y; | |
50 | |
51 if (premultiply_alpha) | |
52 return PROGRAM_COPY_TEXTURE_PREMULTIPLY_ALPHA; | |
53 | |
54 return PROGRAM_COPY_TEXTURE; | |
55 } | |
56 | |
57 const char* GetShaderSource(ShaderId shader) { | |
58 switch (shader) { | |
59 case VERTEX_SHADER_POS_TEX: | |
60 return SHADER( | |
61 precision mediump float; | |
62 attribute vec4 a_position; | |
63 attribute vec2 a_texCoord; | |
64 varying vec2 v_uv; | |
65 void main(void) { | |
66 gl_Position = a_position; | |
67 v_uv = a_texCoord; | |
68 }); | |
69 case FRAGMENT_SHADER_TEX: | |
70 return SHADER( | |
71 precision mediump float; | |
72 uniform sampler2D u_texSampler; | |
73 varying vec2 v_uv; | |
74 void main(void) { | |
75 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
76 }); | |
77 case FRAGMENT_SHADER_TEX_FLIP_Y: | |
78 return SHADER( | |
79 precision mediump float; | |
80 uniform sampler2D u_texSampler; | |
81 varying vec2 v_uv; | |
82 void main(void) { | |
83 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
84 }); | |
85 case FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA: | |
86 return SHADER( | |
87 precision mediump float; | |
88 uniform sampler2D u_texSampler; | |
89 varying vec2 v_uv; | |
90 void main(void) { | |
91 gl_FragColor = texture2D(u_texSampler, v_uv.st); | |
92 gl_FragColor.rgb *= gl_FragColor.a; | |
93 }); | |
94 case FRAGMENT_SHADER_TEX_PREMULTIPLY_ALPHA_FLIP_Y: | |
95 return SHADER( | |
96 precision mediump float; | |
97 uniform sampler2D u_texSampler; | |
98 varying vec2 v_uv; | |
99 void main(void) { | |
100 gl_FragColor = texture2D(u_texSampler, vec2(v_uv.s, 1.0 - v_uv.t)); | |
101 gl_FragColor.rgb *= gl_FragColor.a; | |
102 }); | |
103 default: | |
104 return 0; | |
105 } | |
106 } | |
107 | |
108 } // namespace | |
109 | |
110 void CopyTextureCHROMIUMResourceManager::Initialize() { | |
111 COMPILE_ASSERT( | |
112 kVertexPositionAttrib == 0u || kVertexTextureAttrib == 0u, | |
113 CopyTexture_One_of_these_attribs_must_be_0); | |
114 | |
115 // Initialize all of the GPU resources required to perform the copy. | |
116 glGenBuffersARB(2, buffer_ids_); | |
117 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | |
118 glBufferData(GL_ARRAY_BUFFER, sizeof(kQuadVertices), kQuadVertices, | |
119 GL_STATIC_DRAW); | |
120 | |
121 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | |
122 glBufferData(GL_ARRAY_BUFFER, sizeof(kTextureCoords), kTextureCoords, | |
123 GL_STATIC_DRAW); | |
124 | |
125 glGenFramebuffersEXT(1, &framebuffer_); | |
126 | |
127 GLuint shaders[kNumShaders]; | |
128 for (int shader = 0; shader < kNumShaders; ++shader) { | |
129 shaders[shader] = glCreateShader( | |
130 shader == 0 ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER); | |
131 const char* shader_source = GetShaderSource(static_cast<ShaderId>(shader)); | |
132 glShaderSource(shaders[shader], 1, &shader_source, 0); | |
133 glCompileShader(shaders[shader]); | |
134 #ifndef NDEBUG | |
135 GLint compile_status; | |
136 glGetShaderiv(shaders[shader], GL_COMPILE_STATUS, &compile_status); | |
137 if (GL_TRUE != compile_status) | |
138 DLOG(ERROR) << "CopyTextureCHROMIUM: shader compilation failure."; | |
139 #endif | |
140 } | |
141 | |
142 for (int program = 0; program < kNumPrograms; ++program) { | |
143 programs_[program] = glCreateProgram(); | |
144 glAttachShader(programs_[program], shaders[0]); | |
145 glAttachShader(programs_[program], shaders[program + 1]); | |
146 | |
147 glBindAttribLocation(programs_[program], kVertexPositionAttrib, | |
148 "a_position"); | |
149 glBindAttribLocation(programs_[program], kVertexTextureAttrib, | |
150 "a_texCoord"); | |
151 | |
152 glLinkProgram(programs_[program]); | |
153 #ifndef NDEBUG | |
154 GLint linked; | |
155 glGetProgramiv(programs_[program], GL_LINK_STATUS, &linked); | |
156 if (!linked) | |
157 DLOG(ERROR) << "CopyTextureCHROMIUM: program link failure."; | |
158 #endif | |
159 | |
160 sampler_locations_[program] = glGetUniformLocation(programs_[program], | |
161 "u_texSampler"); | |
162 | |
163 } | |
164 | |
165 for (int shader = 0; shader < kNumShaders; ++shader) | |
166 glDeleteShader(shaders[shader]); | |
167 | |
168 initialized_ = true; | |
169 } | |
170 | |
171 void CopyTextureCHROMIUMResourceManager::Destroy() { | |
172 if (!initialized_) | |
173 return; | |
174 | |
175 glDeleteFramebuffersEXT(1, &framebuffer_); | |
176 | |
177 for (int program = 0; program < kNumPrograms; ++program) | |
178 glDeleteProgram(programs_[program]); | |
179 | |
180 glDeleteBuffersARB(2, buffer_ids_); | |
181 } | |
182 | |
183 void CopyTextureCHROMIUMResourceManager::DoCopyTexture( | |
184 GLenum target, | |
185 GLuint source_id, | |
186 GLuint dest_id, | |
187 GLint level, | |
188 bool flip_y, | |
189 bool premultiply_alpha) { | |
190 if (!initialized_) { | |
191 DLOG(ERROR) << "CopyTextureCHROMIUM: Uninitialized manager."; | |
192 return; | |
193 } | |
194 | |
195 GLuint program = GetProgram(flip_y, premultiply_alpha); | |
196 glUseProgram(programs_[program]); | |
197 | |
198 #ifndef NDEBUG | |
199 glValidateProgram(programs_[program]); | |
200 GLint validation_status; | |
201 glGetProgramiv(programs_[program], GL_VALIDATE_STATUS, &validation_status); | |
202 if (GL_TRUE != validation_status) { | |
203 DLOG(ERROR) << "CopyTextureCHROMIUM: Invalid shader."; | |
204 return; | |
205 } | |
206 #endif | |
207 | |
208 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer_); | |
209 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, | |
210 dest_id, level); | |
211 | |
212 #ifndef NDEBUG | |
213 GLenum fb_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | |
214 if (GL_FRAMEBUFFER_COMPLETE != fb_status) { | |
215 DLOG(ERROR) << "CopyTextureCHROMIUM: Incomplete framebuffer."; | |
216 return; | |
217 } | |
218 #endif | |
219 | |
220 glEnableVertexAttribArray(kVertexPositionAttrib); | |
221 glEnableVertexAttribArray(kVertexTextureAttrib); | |
222 | |
223 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[0]); | |
224 glVertexAttribPointer(kVertexPositionAttrib, 4, GL_FLOAT, GL_FALSE, | |
225 4 * sizeof(GLfloat), 0); | |
226 | |
227 glBindBuffer(GL_ARRAY_BUFFER, buffer_ids_[1]); | |
228 glVertexAttribPointer(kVertexTextureAttrib, 2, GL_FLOAT, GL_FALSE, | |
229 2 * sizeof(GLfloat), 0); | |
230 | |
231 glActiveTexture(GL_TEXTURE0); | |
232 glUniform1i(sampler_locations_[program], 0); | |
233 | |
234 glBindTexture(GL_TEXTURE_2D, source_id); | |
235 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
236 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
238 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
239 | |
240 glDisable(GL_DEPTH_TEST); | |
241 glDisable(GL_SCISSOR_TEST); | |
242 glDisable(GL_STENCIL_TEST); | |
243 glDisable(GL_CULL_FACE); | |
244 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | |
245 glDepthMask(GL_FALSE); | |
246 glDisable(GL_BLEND); | |
247 | |
248 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); | |
249 } | |
250 | |
OLD | NEW |