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

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

Issue 938873002: Add a new API to create a surfaceless GLSurface for Ozone (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: dont need to modify vsync update path with synchronous swapbuffers now 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.h ('k') | no next file » | 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: crbug.com/462360 the following should be replaced by a per surface 171 // TODO: crbug.com/462360 the following should be replaced by a per surface
168 // flush as it gets 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[] = {
(...skipping 18 matching lines...) Expand all
189 } 193 }
190 194
191 // The native surface. Deleting this is allowed to free the EGLNativeWindow. 195 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
192 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; 196 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
193 AcceleratedWidget widget_; 197 AcceleratedWidget widget_;
194 scoped_ptr<VSyncProvider> vsync_provider_; 198 scoped_ptr<VSyncProvider> vsync_provider_;
195 bool has_implicit_external_sync_; 199 bool has_implicit_external_sync_;
196 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); 200 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
197 }; 201 };
198 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 scoped_refptr<ui::NativePixmap> pixmap_;
309 };
310
311 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override {
312 DCHECK(!fbo_);
313 for (size_t i = 0; i < arraysize(textures_); i++)
314 DCHECK(!textures_[i]) << "texture " << i << " not released";
315 }
316
317 void BindFramebuffer() {
318 ScopedFrameBufferBinder fb(fbo_);
319 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
320 GL_TEXTURE_2D, textures_[current_surface_], 0);
321 }
322
323 bool CreatePixmaps() {
324 if (!fbo_)
325 return true;
326 for (size_t i = 0; i < arraysize(textures_); i++) {
327 scoped_refptr<ui::NativePixmap> pixmap =
328 ui::SurfaceFactoryOzone::GetInstance()->CreateNativePixmap(
329 widget_, GetSize(), ui::SurfaceFactoryOzone::RGBA_8888,
330 ui::SurfaceFactoryOzone::SCANOUT);
331 if (!pixmap)
332 return false;
333 scoped_refptr<SurfaceImage> image = new SurfaceImage(GetSize(), GL_RGBA);
334 if (!image->Initialize(pixmap, gfx::GpuMemoryBuffer::Format::BGRA_8888))
335 return false;
336 images_[i] = image;
337 // Bind image to texture.
338 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]);
339 if (!images_[i]->BindTexImage(GL_TEXTURE_2D))
340 return false;
341 }
342 return true;
343 }
344
345 GLuint fbo_;
346 GLuint textures_[2];
347 scoped_refptr<GLImage> images_[2];
348 int current_surface_;
349 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl);
350 };
351
199 } // namespace 352 } // namespace
200 353
201 // static 354 // static
202 bool GLSurface::InitializeOneOffInternal() { 355 bool GLSurface::InitializeOneOffInternal() {
203 switch (GetGLImplementation()) { 356 switch (GetGLImplementation()) {
204 case kGLImplementationEGLGLES2: 357 case kGLImplementationEGLGLES2:
205 if (!GLSurfaceEGL::InitializeOneOff()) { 358 if (!GLSurfaceEGL::InitializeOneOff()) {
206 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; 359 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
207 return false; 360 return false;
208 } 361 }
209 362
210 return true; 363 return true;
211 case kGLImplementationOSMesaGL: 364 case kGLImplementationOSMesaGL:
212 case kGLImplementationMockGL: 365 case kGLImplementationMockGL:
213 return true; 366 return true;
214 default: 367 default:
215 return false; 368 return false;
216 } 369 }
217 } 370 }
218 371
219 // static 372 // static
373 scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface(
374 gfx::AcceleratedWidget window) {
375 if (GetGLImplementation() == kGLImplementationEGLGLES2 &&
376 window != kNullAcceleratedWidget &&
377 GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
378 ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) {
379 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
380 ui::SurfaceFactoryOzone::GetInstance()
381 ->CreateSurfacelessEGLSurfaceForWidget(window);
382 if (!surface_ozone)
383 return nullptr;
384 scoped_refptr<GLSurface> surface;
385 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window);
386 if (surface->Initialize())
387 return surface;
388 }
389
390 return nullptr;
391 }
392
393 // static
220 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( 394 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
221 gfx::AcceleratedWidget window) { 395 gfx::AcceleratedWidget window) {
222 if (GetGLImplementation() == kGLImplementationOSMesaGL) { 396 if (GetGLImplementation() == kGLImplementationOSMesaGL) {
223 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless()); 397 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless());
224 if (!surface->Initialize()) 398 if (!surface->Initialize())
225 return NULL; 399 return NULL;
226 return surface; 400 return surface;
227 } 401 }
228 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); 402 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2);
229 if (window != kNullAcceleratedWidget) { 403 if (window != kNullAcceleratedWidget) {
230 scoped_refptr<GLSurface> surface; 404 scoped_refptr<GLSurface> surface;
231 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && 405 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
232 ui::SurfaceFactoryOzone::GetInstance() 406 ui::SurfaceFactoryOzone::GetInstance()
233 ->CanShowPrimaryPlaneAsOverlay()) { 407 ->CanShowPrimaryPlaneAsOverlay()) {
234 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 408 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
235 ui::SurfaceFactoryOzone::GetInstance() 409 ui::SurfaceFactoryOzone::GetInstance()
236 ->CreateSurfacelessEGLSurfaceForWidget(window); 410 ->CreateSurfacelessEGLSurfaceForWidget(window);
237 if (!surface_ozone) 411 if (!surface_ozone)
238 return NULL; 412 return NULL;
239 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window); 413 surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(),
414 window);
240 } else { 415 } else {
241 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 416 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
242 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget( 417 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
243 window); 418 window);
244 if (!surface_ozone) 419 if (!surface_ozone)
245 return NULL; 420 return NULL;
246 421
247 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window); 422 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window);
248 } 423 }
249 if (!surface->Initialize()) 424 if (!surface->Initialize())
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 NOTREACHED(); 460 NOTREACHED();
286 return NULL; 461 return NULL;
287 } 462 }
288 } 463 }
289 464
290 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { 465 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
291 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); 466 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay();
292 } 467 }
293 468
294 } // namespace gfx 469 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/gl_surface.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698