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

Side by Side Diff: ui/gl/gl_surface_ozone.cc

Issue 988693005: Chromium roll (https://codereview.chromium.org/976353002) (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: fixed bad android build patch Created 5 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
« no previous file with comments | « ui/gl/gl_surface_egl.cc ('k') | ui/gl/gl_switches.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gl/gl_surface.h" 5 #include "ui/gl/gl_surface.h"
6 6
7 #include "base/bind.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
8 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
9 #include "ui/gfx/native_widget_types.h" 10 #include "ui/gfx/native_widget_types.h"
10 #include "ui/gl/gl_context.h" 11 #include "ui/gl/gl_context.h"
11 #include "ui/gl/gl_image.h" 12 #include "ui/gl/gl_image.h"
13 #include "ui/gl/gl_image_linux_dma_buffer.h"
12 #include "ui/gl/gl_implementation.h" 14 #include "ui/gl/gl_implementation.h"
13 #include "ui/gl/gl_surface_egl.h" 15 #include "ui/gl/gl_surface_egl.h"
14 #include "ui/gl/gl_surface_osmesa.h" 16 #include "ui/gl/gl_surface_osmesa.h"
15 #include "ui/gl/gl_surface_stub.h" 17 #include "ui/gl/gl_surface_stub.h"
18 #include "ui/gl/scoped_binders.h"
16 #include "ui/gl/scoped_make_current.h" 19 #include "ui/gl/scoped_make_current.h"
20 #include "ui/ozone/public/native_pixmap.h"
17 #include "ui/ozone/public/surface_factory_ozone.h" 21 #include "ui/ozone/public/surface_factory_ozone.h"
18 #include "ui/ozone/public/surface_ozone_egl.h" 22 #include "ui/ozone/public/surface_ozone_egl.h"
19 23
20 namespace gfx { 24 namespace gfx {
21 25
22 namespace { 26 namespace {
23 27
24 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow 28 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow
25 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { 29 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL {
26 public: 30 public:
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 return ozone_surface_->OnSwapBuffersAsync(callback); 154 return ozone_surface_->OnSwapBuffersAsync(callback);
151 } 155 }
152 bool PostSubBufferAsync(int x, 156 bool PostSubBufferAsync(int x,
153 int y, 157 int y,
154 int width, 158 int width,
155 int height, 159 int height,
156 const SwapCompletionCallback& callback) override { 160 const SwapCompletionCallback& callback) override {
157 return SwapBuffersAsync(callback); 161 return SwapBuffersAsync(callback);
158 } 162 }
159 163
160 private: 164 protected:
161 ~GLSurfaceOzoneSurfaceless() override { 165 ~GLSurfaceOzoneSurfaceless() override {
162 Destroy(); // EGL surface must be destroyed before SurfaceOzone 166 Destroy(); // EGL surface must be destroyed before SurfaceOzone
163 } 167 }
164 168
165 bool Flush() { 169 bool Flush() {
166 glFlush(); 170 glFlush();
167 // TODO: the following should be replaced by a per surface flush as it gets 171 // TODO: crbug.com/462360 the following should be replaced by a per surface
168 // implemented in GL drivers. 172 // flush as it gets implemented in GL drivers.
169 if (has_implicit_external_sync_) { 173 if (has_implicit_external_sync_) {
170 const EGLint attrib_list[] = { 174 const EGLint attrib_list[] = {
171 EGL_SYNC_CONDITION_KHR, 175 EGL_SYNC_CONDITION_KHR,
172 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, 176 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM,
173 EGL_NONE}; 177 EGL_NONE};
174 EGLSyncKHR fence = 178 EGLSyncKHR fence =
175 eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); 179 eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list);
176 if (fence) { 180 if (fence) {
177 // TODO(dbehr): piman@ suggests we could improve here by moving 181 // TODO(dbehr): piman@ suggests we could improve here by moving
178 // following wait to right before drmModePageFlip crbug.com/456417. 182 // following wait to right before drmModePageFlip crbug.com/456417.
179 eglClientWaitSyncKHR(GetDisplay(), fence, 183 eglClientWaitSyncKHR(GetDisplay(), fence,
180 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); 184 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR);
181 eglDestroySyncKHR(GetDisplay(), fence); 185 eglDestroySyncKHR(GetDisplay(), fence);
182 } else { 186 } else {
183 return false; 187 return false;
184 } 188 }
189 } else if (ozone_surface_->IsUniversalDisplayLinkDevice()) {
190 glFinish();
185 } 191 }
186 return true; 192 return true;
187 } 193 }
188 194
189 // The native surface. Deleting this is allowed to free the EGLNativeWindow. 195 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
190 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; 196 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
191 AcceleratedWidget widget_; 197 AcceleratedWidget widget_;
192 scoped_ptr<VSyncProvider> vsync_provider_; 198 scoped_ptr<VSyncProvider> vsync_provider_;
193 bool has_implicit_external_sync_; 199 bool has_implicit_external_sync_;
194 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); 200 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
195 }; 201 };
196 202
203 // This provides surface-like semantics implemented through surfaceless.
204 // A framebuffer is bound automatically.
205 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
206 : public GLSurfaceOzoneSurfaceless {
207 public:
208 GLSurfaceOzoneSurfacelessSurfaceImpl(
209 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
210 AcceleratedWidget widget)
211 : GLSurfaceOzoneSurfaceless(ozone_surface.Pass(), widget),
212 fbo_(0),
213 current_surface_(0) {
214 for (auto& texture : textures_)
215 texture = 0;
216 }
217
218 unsigned int GetBackingFrameBufferObject() override { return fbo_; }
219
220 bool OnMakeCurrent(GLContext* context) override {
221 if (!fbo_) {
222 glGenFramebuffersEXT(1, &fbo_);
223 if (!fbo_)
224 return false;
225 glGenTextures(arraysize(textures_), textures_);
226 if (!CreatePixmaps())
227 return false;
228 }
229 BindFramebuffer();
230 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_);
231 return SurfacelessEGL::OnMakeCurrent(context);
232 }
233
234 bool Resize(const gfx::Size& size) override {
235 if (size == GetSize())
236 return true;
237 return GLSurfaceOzoneSurfaceless::Resize(size) && CreatePixmaps();
238 }
239
240 bool SupportsPostSubBuffer() override { return false; }
241
242 bool SwapBuffers() override {
243 if (!images_[current_surface_]->ScheduleOverlayPlane(
244 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
245 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
246 return false;
247 if (!GLSurfaceOzoneSurfaceless::SwapBuffers())
248 return false;
249 current_surface_ ^= 1;
250 BindFramebuffer();
251 return true;
252 }
253
254 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override {
255 if (!images_[current_surface_]->ScheduleOverlayPlane(
256 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
257 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
258 return false;
259 if (!GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback))
260 return false;
261 current_surface_ ^= 1;
262 BindFramebuffer();
263 return true;
264 }
265
266 void Destroy() override {
267 GLContext* current_context = GLContext::GetCurrent();
268 DCHECK(current_context && current_context->IsCurrent(this));
269 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
270 if (fbo_) {
271 glDeleteTextures(arraysize(textures_), textures_);
272 for (auto& texture : textures_)
273 texture = 0;
274 glDeleteFramebuffersEXT(1, &fbo_);
275 fbo_ = 0;
276 }
277 for (auto image : images_) {
278 if (image)
279 image->Destroy(true);
280 }
281 }
282
283 private:
284 class SurfaceImage : public GLImageLinuxDMABuffer {
285 public:
286 SurfaceImage(const gfx::Size& size, unsigned internalformat)
287 : GLImageLinuxDMABuffer(size, internalformat) {}
288
289 bool Initialize(scoped_refptr<ui::NativePixmap> pixmap,
290 gfx::GpuMemoryBuffer::Format format) {
291 base::FileDescriptor handle(pixmap->GetDmaBufFd(), false);
292 if (!GLImageLinuxDMABuffer::Initialize(handle, format,
293 pixmap->GetDmaBufPitch()))
294 return false;
295 pixmap_ = pixmap;
296 return true;
297 }
298 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
299 int z_order,
300 gfx::OverlayTransform transform,
301 const gfx::Rect& bounds_rect,
302 const gfx::RectF& crop_rect) override {
303 return ui::SurfaceFactoryOzone::GetInstance()->ScheduleOverlayPlane(
304 widget, z_order, transform, pixmap_, bounds_rect, crop_rect);
305 }
306
307 private:
308 ~SurfaceImage() override {}
309
310 scoped_refptr<ui::NativePixmap> pixmap_;
311 };
312
313 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override {
314 DCHECK(!fbo_);
315 for (size_t i = 0; i < arraysize(textures_); i++)
316 DCHECK(!textures_[i]) << "texture " << i << " not released";
317 }
318
319 void BindFramebuffer() {
320 ScopedFrameBufferBinder fb(fbo_);
321 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
322 GL_TEXTURE_2D, textures_[current_surface_], 0);
323 }
324
325 bool CreatePixmaps() {
326 if (!fbo_)
327 return true;
328 for (size_t i = 0; i < arraysize(textures_); i++) {
329 scoped_refptr<ui::NativePixmap> pixmap =
330 ui::SurfaceFactoryOzone::GetInstance()->CreateNativePixmap(
331 widget_, GetSize(), ui::SurfaceFactoryOzone::RGBA_8888,
332 ui::SurfaceFactoryOzone::SCANOUT);
333 if (!pixmap)
334 return false;
335 scoped_refptr<SurfaceImage> image = new SurfaceImage(GetSize(), GL_RGBA);
336 if (!image->Initialize(pixmap, gfx::GpuMemoryBuffer::Format::BGRA_8888))
337 return false;
338 images_[i] = image;
339 // Bind image to texture.
340 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]);
341 if (!images_[i]->BindTexImage(GL_TEXTURE_2D))
342 return false;
343 }
344 return true;
345 }
346
347 GLuint fbo_;
348 GLuint textures_[2];
349 scoped_refptr<GLImage> images_[2];
350 int current_surface_;
351 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl);
352 };
353
197 } // namespace 354 } // namespace
198 355
199 // static 356 // static
200 bool GLSurface::InitializeOneOffInternal() { 357 bool GLSurface::InitializeOneOffInternal() {
201 switch (GetGLImplementation()) { 358 switch (GetGLImplementation()) {
202 case kGLImplementationEGLGLES2: 359 case kGLImplementationEGLGLES2:
203 if (!GLSurfaceEGL::InitializeOneOff()) { 360 if (!GLSurfaceEGL::InitializeOneOff()) {
204 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; 361 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
205 return false; 362 return false;
206 } 363 }
207 364
208 return true; 365 return true;
209 case kGLImplementationOSMesaGL: 366 case kGLImplementationOSMesaGL:
210 case kGLImplementationMockGL: 367 case kGLImplementationMockGL:
211 return true; 368 return true;
212 default: 369 default:
213 return false; 370 return false;
214 } 371 }
215 } 372 }
216 373
217 // static 374 // static
375 scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface(
376 gfx::AcceleratedWidget window) {
377 if (GetGLImplementation() == kGLImplementationEGLGLES2 &&
378 window != kNullAcceleratedWidget &&
379 GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
380 ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) {
381 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
382 ui::SurfaceFactoryOzone::GetInstance()
383 ->CreateSurfacelessEGLSurfaceForWidget(window);
384 if (!surface_ozone)
385 return nullptr;
386 scoped_refptr<GLSurface> surface;
387 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window);
388 if (surface->Initialize())
389 return surface;
390 }
391
392 return nullptr;
393 }
394
395 // static
218 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( 396 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
219 gfx::AcceleratedWidget window) { 397 gfx::AcceleratedWidget window) {
220 if (GetGLImplementation() == kGLImplementationOSMesaGL) { 398 if (GetGLImplementation() == kGLImplementationOSMesaGL) {
221 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless()); 399 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless());
222 if (!surface->Initialize()) 400 if (!surface->Initialize())
223 return NULL; 401 return NULL;
224 return surface; 402 return surface;
225 } 403 }
226 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); 404 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2);
227 if (window != kNullAcceleratedWidget) { 405 if (window != kNullAcceleratedWidget) {
228 scoped_refptr<GLSurface> surface; 406 scoped_refptr<GLSurface> surface;
229 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && 407 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
230 ui::SurfaceFactoryOzone::GetInstance() 408 ui::SurfaceFactoryOzone::GetInstance()
231 ->CanShowPrimaryPlaneAsOverlay()) { 409 ->CanShowPrimaryPlaneAsOverlay()) {
232 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 410 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
233 ui::SurfaceFactoryOzone::GetInstance() 411 ui::SurfaceFactoryOzone::GetInstance()
234 ->CreateSurfacelessEGLSurfaceForWidget(window); 412 ->CreateSurfacelessEGLSurfaceForWidget(window);
235 if (!surface_ozone) 413 if (!surface_ozone)
236 return NULL; 414 return NULL;
237 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window); 415 surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(),
416 window);
238 } else { 417 } else {
239 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 418 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
240 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget( 419 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
241 window); 420 window);
242 if (!surface_ozone) 421 if (!surface_ozone)
243 return NULL; 422 return NULL;
244 423
245 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window); 424 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window);
246 } 425 }
247 if (!surface->Initialize()) 426 if (!surface->Initialize())
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 NOTREACHED(); 462 NOTREACHED();
284 return NULL; 463 return NULL;
285 } 464 }
286 } 465 }
287 466
288 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { 467 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
289 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); 468 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay();
290 } 469 }
291 470
292 } // namespace gfx 471 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/gl_surface_egl.cc ('k') | ui/gl/gl_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698