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

Side by Side Diff: gpu/command_buffer/service/gles2_cmd_copy_tex_image.cc

Issue 2027703003: Support glCopyTex[Sub]Image to LUMA formats on the core profile. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Support glCopyTex[Sub]Image to LUMA formats on the core profile. Created 4 years, 6 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
OLDNEW
(Empty)
1 // Copyright (c) 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 "gpu/command_buffer/service/gles2_cmd_copy_tex_image.h"
6
7 #include "gpu/command_buffer/service/texture_manager.h"
8 #include "ui/gl/gl_version_info.h"
9
10 namespace {
11
12 void CompileShader(GLuint shader, const char* shader_source) {
13 glShaderSource(shader, 1, &shader_source, 0);
14 glCompileShader(shader);
15 #ifndef NDEBUG
16 GLint compile_status;
17 glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
18 if (GL_TRUE != compile_status)
19 DLOG(ERROR) << "CopyTexImage: shader compilation failure.";
20 #endif
21 }
22
23 } // anonymous namespace
24
25 namespace gpu {
26
27 CopyTexImageResourceManager::CopyTexImageResourceManager(
28 const gles2::FeatureInfo* feature_info)
29 : feature_info_(feature_info) {
30 DCHECK(feature_info->gl_version_info().is_desktop_core_profile);
31 }
32
33 CopyTexImageResourceManager::~CopyTexImageResourceManager() {}
34
35 void CopyTexImageResourceManager::Initialize(
36 const gles2::GLES2Decoder* decoder) {
37 if (initialized_) {
38 return;
39 }
40
41 blit_program_ = glCreateProgram();
42
43 // Compile the fragment shader
44 const char* vs_source =
45 "#version 150\n"
46 "out vec2 v_texcoord;\n"
47 "\n"
48 "void main()\n"
49 "{\n"
50 " const vec2 quad_positions[6] = vec2[6]\n"
51 " (\n"
52 " vec2(0.0f, 0.0f),\n"
53 " vec2(0.0f, 1.0f),\n"
54 " vec2(1.0f, 0.0f),\n"
55 "\n"
56 " vec2(0.0f, 1.0f),\n"
57 " vec2(1.0f, 0.0f),\n"
58 " vec2(1.0f, 1.0f)\n"
59 " );\n"
60 "\n"
61 " gl_Position = vec4((quad_positions[gl_VertexID] * 2.0) - 1.0, 0.0, "
62 "1.0);\n"
63 " v_texcoord = quad_positions[gl_VertexID];\n"
64 "}\n";
65
66 GLuint vs = glCreateShader(GL_VERTEX_SHADER);
67 CompileShader(vs, vs_source);
68 glAttachShader(blit_program_, vs);
69 glDeleteShader(vs);
70
71 // Compile the vertex shader
72 const char* fs_source =
73 "#version 150\n"
74 "uniform sampler2D u_source_texture;\n"
75 "in vec2 v_texcoord;\n"
76 "out vec4 output_color;\n"
77 "\n"
78 "void main()\n"
79 "{\n"
80 " output_color = texture(u_source_texture, v_texcoord);\n"
81 "}\n";
82
83 GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
84 CompileShader(fs, fs_source);
85 glAttachShader(blit_program_, fs);
86 glDeleteShader(fs);
87
88 glLinkProgram(blit_program_);
89 #ifndef NDEBUG
90 GLint linked = 0;
91 glGetProgramiv(blit_program_, GL_LINK_STATUS, &linked);
92 if (!linked) {
93 DLOG(ERROR) << "CopyTexImage: program link failure.";
94 }
95 #endif
96
97 GLuint texture_uniform =
98 glGetUniformLocation(blit_program_, "u_source_texture");
99 glUseProgram(blit_program_);
100 glUniform1i(texture_uniform, 0);
101
102 glGenTextures(scratch_textures_.size(), scratch_textures_.data());
103 glActiveTexture(GL_TEXTURE0);
104 for (auto scratch_texture : scratch_textures_) {
105 glBindTexture(GL_TEXTURE_2D, scratch_texture);
106
107 // Use nearest, non-mipmapped sampling with the scratch texture
108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
110 }
111
112 glGenFramebuffersEXT(1, &scratch_fbo_);
113 glGenVertexArraysOES(1, &vao_);
114
115 decoder->RestoreTextureUnitBindings(0);
116 decoder->RestoreActiveTexture();
117 decoder->RestoreProgramBindings();
118
119 initialized_ = true;
120 }
121
122 void CopyTexImageResourceManager::Destroy() {
123 if (!initialized_) {
124 return;
125 }
126
127 glDeleteProgram(blit_program_);
128 blit_program_ = 0;
129
130 glDeleteTextures(scratch_textures_.size(), scratch_textures_.data());
131 scratch_textures_.fill(0);
132
133 glDeleteFramebuffersEXT(1, &scratch_fbo_);
134 scratch_fbo_ = 0;
135
136 glDeleteVertexArraysOES(1, &vao_);
137 vao_ = 0;
138
139 initialized_ = false;
140 }
141
142 void CopyTexImageResourceManager::DoCopyTexImage2DToLUMAComatabilityTexture(
143 const gles2::GLES2Decoder* decoder,
144 GLuint dest_texture,
145 GLenum dest_texture_target,
146 GLenum dest_target,
147 GLenum luma_format,
148 GLenum luma_type,
149 GLint level,
150 GLenum internal_format,
151 GLint x,
152 GLint y,
153 GLsizei width,
154 GLsizei height,
155 GLuint source_framebuffer,
156 GLenum source_framebuffer_internal_format) {
157 GLenum adjusted_internal_format =
158 gles2::TextureManager::AdjustTexInternalFormat(feature_info_.get(),
159 internal_format);
160 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
161 GLenum adjusted_format = gles2::TextureManager::AdjustTexFormat(
162 feature_info_.get(), internal_format);
163 glTexImage2D(dest_target, level, adjusted_internal_format, width, height, 0,
164 adjusted_format, luma_type, nullptr);
165 DoCopyTexSubImage2DToLUMAComatabilityTexture(
166 decoder, dest_texture, dest_texture_target, dest_target, luma_format,
167 luma_type, level, 0, 0, x, y, width, height, source_framebuffer,
168 source_framebuffer_internal_format);
169 }
170
171 void CopyTexImageResourceManager::DoCopyTexSubImage2DToLUMAComatabilityTexture(
172 const gles2::GLES2Decoder* decoder,
173 GLuint dest_texture,
174 GLenum dest_texture_target,
175 GLenum dest_target,
176 GLenum luma_format,
177 GLenum luma_type,
178 GLint level,
179 GLint xoffset,
180 GLint yoffset,
181 GLint x,
182 GLint y,
183 GLsizei width,
184 GLsizei height,
185 GLuint source_framebuffer,
186 GLenum source_framebuffer_internal_format) {
187 DCHECK(initialized_);
188
189 // Copy the framebuffer to the first scratch texture
190 // TODO(geofflang): This could be optimized further by detecting if the source
191 // framebuffer is copying from a texture and sample directly from that texture
192 // instead of doing an extra copy
193
194 glBindFramebufferEXT(GL_FRAMEBUFFER, source_framebuffer);
195 glActiveTexture(GL_TEXTURE0);
196 glBindTexture(GL_TEXTURE_2D, scratch_textures_[0]);
197 glCopyTexImage2D(GL_TEXTURE_2D, 0, source_framebuffer_internal_format, x, y,
198 width, height, 0);
199
200 // Set the swizzle of the scratch texture so that the channels sample into the
201 // correct emulated LUMA channels.
202 GLint swizzle[4] = {
203 (luma_format == GL_ALPHA) ? GL_ALPHA : GL_RED,
204 (luma_format == GL_LUMINANCE_ALPHA) ? GL_ALPHA : GL_ZERO, GL_ZERO,
205 GL_ZERO,
206 };
207 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
208
209 // Make a temporary framebuffer using the second scratch texture to render the
210 // swizzled result to.
211 // TODO(geofflang): Could be optimized more by rendering directly to the
212 // destination texture but this isn't always possible because the destination
213 // may be an incomplete cube map
214 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
215 GLenum compatability_format =
216 gles2::TextureManager::AdjustTexFormat(feature_info_.get(), luma_format);
217 glBindTexture(GL_TEXTURE_2D, scratch_textures_[1]);
218 glTexImage2D(GL_TEXTURE_2D, 0, compatability_format, width, height, 0,
219 compatability_format, luma_type, nullptr);
220
221 glBindFramebufferEXT(GL_FRAMEBUFFER, scratch_fbo_);
222 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
223 scratch_textures_[1], 0);
224
225 // Render to the destination texture, sampling from the scratch texture
226 glUseProgram(blit_program_);
227 glViewport(0, 0, width, height);
228 glDisable(GL_SCISSOR_TEST);
229 glDisable(GL_DEPTH_TEST);
230 glDisable(GL_STENCIL_TEST);
231 glDisable(GL_CULL_FACE);
232 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
233 glDepthMask(GL_FALSE);
234 glDisable(GL_BLEND);
235 glDisable(GL_DITHER);
236
237 glBindTexture(GL_TEXTURE_2D, scratch_textures_[0]);
238 glBindVertexArrayOES(vao_);
239
240 glDrawArrays(GL_TRIANGLES, 0, 6);
241
242 // Finally, copy the swizzled texture to the destination texture
243 glBindTexture(dest_texture_target, dest_texture);
244 glCopyTexSubImage2D(dest_target, level, xoffset, yoffset, 0, 0, width,
245 height);
246
247 // Restore state
248 decoder->RestoreAllAttributes();
249 decoder->RestoreTextureUnitBindings(0);
250 decoder->RestoreActiveTexture();
251 decoder->RestoreProgramBindings();
252 decoder->RestoreBufferBindings();
253 decoder->RestoreFramebufferBindings();
254 decoder->RestoreGlobalState();
255 }
256
257 // static
258 bool CopyTexImageResourceManager::CopyTexImageRequiresBlit(
259 const gles2::FeatureInfo* feature_info,
260 GLenum dest_texture_format) {
261 if (feature_info->gl_version_info().is_desktop_core_profile) {
262 switch (dest_texture_format) {
263 case GL_LUMINANCE:
264 case GL_ALPHA:
265 case GL_LUMINANCE_ALPHA:
266 return true;
267 }
268 }
269
270 return false;
271 }
272
273 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/gles2_cmd_copy_tex_image.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698