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

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

Issue 180723023: gpu: Mailbox emulation with EGLImage (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014 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/texture_definition.h"
6
7 #include "gpu/command_buffer/service/texture_manager.h"
8 #include "ui/gl/gl_fence.h"
9 #include "ui/gl/gl_image.h"
10 #include "ui/gl/gl_implementation.h"
11 #include "ui/gl/gl_surface_egl.h"
12 #include "ui/gl/scoped_binders.h"
13
14 namespace gpu {
15 namespace gles2 {
16
17 namespace {
18
19 class GLImageSync : public gfx::GLImage {
20 public:
21 explicit GLImageSync(
22 const scoped_refptr<const NativeImageBuffer>& buffer,
23 const scoped_refptr<const SharedGLFence>& fence);
24
25 // Implement GLImage.
26 virtual void Destroy() OVERRIDE;
27 virtual gfx::Size GetSize() OVERRIDE;
28 virtual bool BindTexImage(unsigned target) OVERRIDE;
29 virtual void ReleaseTexImage(unsigned target) OVERRIDE;
30 virtual void WillUseTexImage() OVERRIDE;
31 virtual void DidUseTexImage() OVERRIDE;
32 virtual void SetReleaseAfterUse() OVERRIDE;
33
34 protected:
35 virtual ~GLImageSync();
36
37 private:
38 scoped_refptr<const NativeImageBuffer> buffer_;
39 scoped_refptr<const SharedGLFence> fence_;
40
41 DISALLOW_COPY_AND_ASSIGN(GLImageSync);
42 };
43
44 GLImageSync::GLImageSync(const scoped_refptr<const NativeImageBuffer>& buffer,
45 const scoped_refptr<const SharedGLFence>& fence)
46 : buffer_(buffer), fence_(fence) {}
47
48 GLImageSync::~GLImageSync() {}
49
50 void GLImageSync::Destroy() {}
51
52 gfx::Size GLImageSync::GetSize() {
53 NOTREACHED();
54 return gfx::Size();
55 }
56
57 bool GLImageSync::BindTexImage(unsigned target) {
58 NOTREACHED();
59 return false;
60 }
61
62 void GLImageSync::ReleaseTexImage(unsigned target) {
63 NOTREACHED();
64 }
65
66 void GLImageSync::WillUseTexImage() {
67 if (fence_.get()) {
68 fence_->GpuWaitSync();
69 fence_ = NULL;
70 }
71 }
72
73 void GLImageSync::DidUseTexImage() {}
74
75 void GLImageSync::SetReleaseAfterUse() {
76 NOTREACHED();
77 }
78
79 class NativeImageBufferEGL : public NativeImageBuffer {
80 public:
81 static NativeImageBufferEGL* Create(GLuint texture_id);
82
83 private:
84 explicit NativeImageBufferEGL(EGLDisplay display, EGLImageKHR image);
85 virtual ~NativeImageBufferEGL();
86 virtual void BindToTexture(GLenum target) OVERRIDE;
87
88 EGLDisplay egl_display_;
89 EGLImageKHR egl_image_;
90
91 DISALLOW_COPY_AND_ASSIGN(NativeImageBufferEGL);
92 };
93
94 NativeImageBufferEGL* NativeImageBufferEGL::Create(GLuint texture_id) {
95 EGLDisplay egl_display = gfx::GLSurfaceEGL::GetHardwareDisplay();
96 EGLContext egl_context = eglGetCurrentContext();
97
98 if (egl_context == EGL_NO_CONTEXT || egl_display == EGL_NO_DISPLAY ||
99 !glIsTexture(texture_id)) {
100 return NULL;
101 }
102
103 if (!gfx::g_driver_egl.ext.b_EGL_KHR_image_base ||
104 !gfx::g_driver_gl.ext.b_GL_OES_EGL_image) {
105 return NULL;
106 }
107
108 const EGLint egl_attrib_list[] = {
109 EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE};
110 EGLClientBuffer egl_buffer = reinterpret_cast<EGLClientBuffer>(texture_id);
111 EGLenum egl_target = EGL_GL_TEXTURE_2D_KHR; // TODO
112
113 EGLImageKHR egl_image = eglCreateImageKHR(
114 egl_display, egl_context, egl_target, egl_buffer, egl_attrib_list);
115
116 if (egl_image == EGL_NO_IMAGE_KHR)
117 return NULL;
118
119 return new NativeImageBufferEGL(egl_display, egl_image);
120 }
121
122 NativeImageBufferEGL::NativeImageBufferEGL(EGLDisplay display,
123 EGLImageKHR image)
124 : egl_display_(display), egl_image_(image) {
125 DCHECK(egl_display_ != EGL_NO_DISPLAY);
126 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR);
127 }
128
129 NativeImageBufferEGL::~NativeImageBufferEGL() {
130 if (egl_image_ != EGL_NO_IMAGE_KHR)
131 eglDestroyImageKHR(egl_display_, egl_image_);
132 }
133
134 void NativeImageBufferEGL::BindToTexture(GLenum target) {
135 DCHECK(egl_image_ != EGL_NO_IMAGE_KHR);
136 glEGLImageTargetTexture2DOES(target, egl_image_);
137 DCHECK_EQ(EGL_SUCCESS, (EGLint)eglGetError());
138 DCHECK_EQ(GL_NO_ERROR, (GLint)glGetError());
139 }
140
141 } // anonymous namespace
142
143 // static
144 NativeImageBuffer* NativeImageBuffer::Create(GLuint texture_id) {
145 switch (gfx::GetGLImplementation()) {
146 case gfx::kGLImplementationEGLGLES2:
147 return NativeImageBufferEGL::Create(texture_id);
148 case gfx::kGLImplementationMockGL:
149 default:
150 NOTREACHED();
151 return NULL;
152 }
153 }
154
155 SharedGLFence::SharedGLFence() : fence_(gfx::GLFence::Create()) {}
156
157 SharedGLFence::~SharedGLFence() {}
158
159 void SharedGLFence::GpuWaitSync() const {
160 fence_->ServerWait();
161 }
162
163 TextureDefinition::LevelInfo::LevelInfo(GLenum target,
164 GLenum internal_format,
165 GLsizei width,
166 GLsizei height,
167 GLsizei depth,
168 GLint border,
169 GLenum format,
170 GLenum type,
171 bool cleared)
172 : target(target),
173 internal_format(internal_format),
174 width(width),
175 height(height),
176 depth(depth),
177 border(border),
178 format(format),
179 type(type),
180 cleared(cleared) {}
181
182 TextureDefinition::LevelInfo::~LevelInfo() {}
183
184 TextureDefinition::TextureDefinition(GLenum target,
185 Texture* texture,
186 NativeImageBuffer* image,
187 const scoped_refptr<SharedGLFence>& fence)
188 : target_(target),
189 image_(image ? image : NativeImageBuffer::Create(texture->service_id())),
190 fence_(fence),
191 min_filter_(texture->min_filter()),
192 mag_filter_(texture->mag_filter()),
193 wrap_s_(texture->wrap_s()),
194 wrap_t_(texture->wrap_t()),
195 usage_(texture->usage()),
196 immutable_(texture->IsImmutable()) {
197
198 // TODO
199 DCHECK(!texture->level_infos_.empty());
200 DCHECK(!texture->level_infos_[0].empty());
201 DCHECK(!texture->NeedsMips());
202 DCHECK(texture->level_infos_[0][0].width);
203 DCHECK(texture->level_infos_[0][0].height);
204
205 // TODO: If the texture is not complete, we should defer creating the image
206 // until the next sync after it becomes complete.
207 scoped_refptr<gfx::GLImage> gl_image(new GLImageSync(image, fence));
208 texture->SetLevelImage(NULL, target, 0, gl_image);
209
210 // TODO: all levels
211 level_infos_.clear();
212 const Texture::LevelInfo& level = texture->level_infos_[0][0];
213 LevelInfo info(level.target,
214 level.internal_format,
215 level.width,
216 level.height,
217 level.depth,
218 level.border,
219 level.format,
220 level.type,
221 level.cleared);
222 std::vector<LevelInfo> infos;
223 infos.push_back(info);
224 level_infos_.push_back(infos);
225
226 }
227
228 TextureDefinition::~TextureDefinition() {
229 }
230
231 Texture* TextureDefinition::CreateTexture() const {
232 if (!image_)
233 return NULL;
234
235 GLuint texture_id;
236 glGenTextures(1, &texture_id);
237
238 Texture* texture(new Texture(texture_id));
239 UpdateTexture(texture);
240
241 return texture;
242 }
243
244 void TextureDefinition::UpdateTexture(Texture* texture) const {
245 gfx::ScopedTextureBinder texture_binder(target_, texture->service_id());
246 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_);
247 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_);
248 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_);
249 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_);
250 DCHECK(image_);
251 if (image_)
252 image_->BindToTexture(target_);
253 glFlush();
254
255 texture->level_infos_.resize(1);
256 for (size_t i = 0; i < level_infos_.size(); i++) {
257 const LevelInfo& base_info = level_infos_[i][0];
258 const size_t levels_needed = TextureManager::ComputeMipMapCount(
259 base_info.target, base_info.width, base_info.height, base_info.depth);
260 DCHECK(level_infos_.size() <= levels_needed);
261 texture->level_infos_[0].resize(levels_needed);
262 for (size_t n = 0; n < level_infos_.size(); n++) {
263 const LevelInfo& info = level_infos_[i][n];
264 texture->SetLevelInfo(NULL,
265 info.target,
266 i,
267 info.internal_format,
268 info.width,
269 info.height,
270 info.depth,
271 info.border,
272 info.format,
273 info.type,
274 info.cleared);
275 }
276 }
277 if (image_)
278 texture->SetLevelImage(NULL, target_, 0, new GLImageSync(image_, fence_));
279
280 texture->target_ = target_;
281 texture->SetImmutable(immutable_);
282 texture->min_filter_ = min_filter_;
283 texture->mag_filter_ = mag_filter_;
284 texture->wrap_s_ = wrap_s_;
285 texture->wrap_t_ = wrap_t_;
286 texture->usage_ = usage_;
287 }
288
289 } // namespace gles2
290 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698