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

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: 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 textureUniform =
Zhenyao Mo 2016/06/01 18:24:18 nit: texture_uniform.
Geoff Lang 2016/06/01 20:12:18 Done.
98 glGetUniformLocation(blit_program_, "u_source_texture");
99 glUseProgram(blit_program_);
100 glUniform1i(textureUniform, 0);
101
102 glGenTextures(scratch_textures_.size(), scratch_textures_.data());
103 glActiveTexture(GL_TEXTURE0);
Zhenyao Mo 2016/06/01 18:24:18 You don't care which active texture to use, so no
Zhenyao Mo 2016/06/01 18:26:48 Never mind, it's easier this way for RestoreTextur
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 glDeleteTextures(scratch_textures_.size(), scratch_textures_.data());
129 glDeleteFramebuffersEXT(1, &scratch_fbo_);
130 glDeleteVertexArraysOES(1, &vao_);
Zhenyao Mo 2016/06/01 18:26:48 Although you don't intend it to be re-initialized
Geoff Lang 2016/06/01 20:12:18 Done.
131
132 initialized_ = false;
133 }
134
135 void CopyTexImageResourceManager::DoCopyTexImage2DToLUMAComatabilityTexture(
136 const gles2::GLES2Decoder* decoder,
137 GLuint dest_texture,
138 GLenum dest_texture_target,
139 GLenum dest_target,
140 GLenum luma_format,
141 GLenum luma_type,
142 GLint level,
143 GLenum internal_format,
144 GLint x,
145 GLint y,
146 GLsizei width,
147 GLsizei height,
148 GLuint source_framebuffer,
149 GLenum source_framebuffer_internal_format) {
150 GLenum adjusted_internal_format =
151 gles2::TextureManager::AdjustTexInternalFormat(feature_info_.get(),
152 internal_format);
153 GLenum adjusted_format = gles2::TextureManager::AdjustTexFormat(
154 feature_info_.get(), internal_format);
155 glTexImage2D(dest_target, level, adjusted_internal_format, width, height, 0,
156 adjusted_format, luma_type, nullptr);
157 DoCopyTexSubImage2DToLUMAComatabilityTexture(
158 decoder, dest_texture, dest_texture_target, dest_target, luma_format,
159 luma_type, level, 0, 0, x, y, width, height, source_framebuffer,
160 source_framebuffer_internal_format);
161 }
162
163 void CopyTexImageResourceManager::DoCopyTexSubImage2DToLUMAComatabilityTexture(
164 const gles2::GLES2Decoder* decoder,
165 GLuint dest_texture,
166 GLenum dest_texture_target,
167 GLenum dest_target,
168 GLenum luma_format,
169 GLenum luma_type,
170 GLint level,
171 GLint xoffset,
172 GLint yoffset,
173 GLint x,
174 GLint y,
175 GLsizei width,
176 GLsizei height,
177 GLuint source_framebuffer,
178 GLenum source_framebuffer_internal_format) {
179 DCHECK(initialized_);
180
181 // Copy the framebuffer to the first scratch texture
182 // TODO(geofflang): This could be optimized further by detecting if the source
183 // framebuffer is copying from a texture and sample directly from that texture
184 // instead of doing an extra copy
185
186 glBindFramebufferEXT(GL_FRAMEBUFFER, source_framebuffer);
187 glActiveTexture(GL_TEXTURE0);
188 glBindTexture(GL_TEXTURE_2D, scratch_textures_[0]);
189 glCopyTexImage2D(GL_TEXTURE_2D, 0, source_framebuffer_internal_format, x, y,
190 width, height, 0);
191
192 // Set the swizzle of the scratch texture so that the channels sample into the
193 // correct emulated LUMA channels.
194 GLint swizzle[4] = {
195 (luma_format == GL_ALPHA) ? GL_ALPHA : GL_RED,
196 (luma_format == GL_LUMINANCE_ALPHA) ? GL_ALPHA : GL_ZERO, GL_ZERO,
197 GL_ZERO,
198 };
199 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzle);
200
201 // Make a temporary framebuffer using the second scratch texture to render the
202 // swizzled result to.
203 // TODO(geofflang): Could be optimized more by rendering directly to the
204 // destination texture but this isn't always possible because the destination
205 // may be an incomplete cube map
206 GLenum compatability_format =
207 gles2::TextureManager::AdjustTexFormat(feature_info_.get(), luma_format);
208 glBindTexture(GL_TEXTURE_2D, scratch_textures_[1]);
209 glTexImage2D(GL_TEXTURE_2D, 0, compatability_format, width, height, 0,
Zhenyao Mo 2016/06/01 18:24:18 You will need to glBindBuffer(GL_PIXEL_UNPACK_BUFF
Geoff Lang 2016/06/01 20:12:18 Ah, good point, fixed.
210 compatability_format, luma_type, nullptr);
211
212 glBindFramebufferEXT(GL_FRAMEBUFFER, scratch_fbo_);
213 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
214 scratch_textures_[1], 0);
215
216 // Render to the destination texture, sampling from the scratch texture
217 glUseProgram(blit_program_);
218 glViewport(0, 0, width, height);
219 glDisable(GL_SCISSOR_TEST);
220 glDisable(GL_DEPTH_TEST);
221 glDisable(GL_STENCIL_TEST);
222 glDisable(GL_CULL_FACE);
Zhenyao Mo 2016/06/01 18:24:18 Should we also disable GL_DITHER?
Geoff Lang 2016/06/01 20:12:18 Done.
223 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
224 glDepthMask(GL_FALSE);
225 glDisable(GL_BLEND);
226 glBindTexture(GL_TEXTURE_2D, scratch_textures_[0]);
227 glBindVertexArrayOES(vao_);
228
229 glDrawArrays(GL_TRIANGLES, 0, 6);
230
231 // Finally, copy the swizzled texture to the destination texture
232 glBindTexture(dest_texture_target, dest_texture);
233 glCopyTexSubImage2D(dest_target, level, xoffset, yoffset, 0, 0, width,
234 height);
235
236 // Restore state
237 decoder->RestoreAllAttributes();
238 decoder->RestoreTextureUnitBindings(0);
239 decoder->RestoreActiveTexture();
240 decoder->RestoreProgramBindings();
241 decoder->RestoreBufferBindings();
242 decoder->RestoreFramebufferBindings();
243 decoder->RestoreGlobalState();
244 }
245
246 // static
247 bool CopyTexImageResourceManager::CopyTexImageRequiresBlit(
248 const gles2::FeatureInfo* feature_info,
249 GLenum dest_texture_format) {
250 if (feature_info->gl_version_info().is_desktop_core_profile) {
251 switch (dest_texture_format) {
252 case GL_LUMINANCE:
253 case GL_ALPHA:
254 case GL_LUMINANCE_ALPHA:
255 return true;
256 }
257 }
258
259 return false;
260 }
261
262 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698