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

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: Created 5 years, 10 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
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/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/ref_counted.h" 8 #include "base/memory/ref_counted.h"
9 #include "ui/gfx/native_widget_types.h" 9 #include "ui/gfx/native_widget_types.h"
10 #include "ui/gl/gl_context.h" 10 #include "ui/gl/gl_context.h"
11 #include "ui/gl/gl_image.h" 11 #include "ui/gl/gl_image.h"
12 #include "ui/gl/gl_image_linux_dma_buffer.h"
12 #include "ui/gl/gl_implementation.h" 13 #include "ui/gl/gl_implementation.h"
13 #include "ui/gl/gl_surface_egl.h" 14 #include "ui/gl/gl_surface_egl.h"
14 #include "ui/gl/gl_surface_osmesa.h" 15 #include "ui/gl/gl_surface_osmesa.h"
15 #include "ui/gl/gl_surface_stub.h" 16 #include "ui/gl/gl_surface_stub.h"
16 #include "ui/gl/scoped_make_current.h" 17 #include "ui/gl/scoped_make_current.h"
18 #include "ui/ozone/public/native_pixmap.h"
17 #include "ui/ozone/public/surface_factory_ozone.h" 19 #include "ui/ozone/public/surface_factory_ozone.h"
18 #include "ui/ozone/public/surface_ozone_egl.h" 20 #include "ui/ozone/public/surface_ozone_egl.h"
19 21
20 namespace gfx { 22 namespace gfx {
21 23
22 namespace { 24 namespace {
23 25
24 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow 26 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow
25 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { 27 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL {
26 public: 28 public:
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 return ozone_surface_->OnSwapBuffersAsync(callback); 152 return ozone_surface_->OnSwapBuffersAsync(callback);
151 } 153 }
152 bool PostSubBufferAsync(int x, 154 bool PostSubBufferAsync(int x,
153 int y, 155 int y,
154 int width, 156 int width,
155 int height, 157 int height,
156 const SwapCompletionCallback& callback) override { 158 const SwapCompletionCallback& callback) override {
157 return SwapBuffersAsync(callback); 159 return SwapBuffersAsync(callback);
158 } 160 }
159 161
160 private: 162 protected:
161 ~GLSurfaceOzoneSurfaceless() override { 163 ~GLSurfaceOzoneSurfaceless() override {
162 Destroy(); // EGL surface must be destroyed before SurfaceOzone 164 Destroy(); // EGL surface must be destroyed before SurfaceOzone
163 } 165 }
164 166
165 bool Flush() { 167 bool Flush() {
166 glFlush(); 168 glFlush();
167 // TODO: the following should be replaced by a per surface flush as it gets 169 // TODO: the following should be replaced by a per surface flush as it gets
168 // implemented in GL drivers. 170 // implemented in GL drivers.
169 if (has_implicit_external_sync_) { 171 if (has_implicit_external_sync_) {
170 const EGLint attrib_list[] = { 172 const EGLint attrib_list[] = {
(...skipping 16 matching lines...) Expand all
187 } 189 }
188 190
189 // The native surface. Deleting this is allowed to free the EGLNativeWindow. 191 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
190 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; 192 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
191 AcceleratedWidget widget_; 193 AcceleratedWidget widget_;
192 scoped_ptr<VSyncProvider> vsync_provider_; 194 scoped_ptr<VSyncProvider> vsync_provider_;
193 bool has_implicit_external_sync_; 195 bool has_implicit_external_sync_;
194 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); 196 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
195 }; 197 };
196 198
199 // This provides surface-like semantics implemented through surfaceless.
200 // A framebuffer is bound automatically and re-bound at each swap.
201 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
202 : public GLSurfaceOzoneSurfaceless {
203 public:
204 GLSurfaceOzoneSurfacelessSurfaceImpl(
205 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface,
206 AcceleratedWidget widget)
207 : GLSurfaceOzoneSurfaceless(ozone_surface.Pass(), widget),
208 fbo_(0),
209 current_surface_(0) {
210 textures_[0] = 0;
211 textures_[1] = 0;
212 }
213
214 unsigned int GetBackingFrameBufferObject() override { return fbo_; }
215
216 bool OnMakeCurrent(GLContext* context) override {
217 if (!fbo_) {
218 glGenFramebuffersEXT(1, &fbo_);
219 if (!fbo_)
220 return false;
221 glGenTextures(2, textures_);
222 // Create and bind our pixmaps.
223 if (!ResizePixmaps())
224 return false;
225 }
226 BindFramebuffer();
227 return SurfacelessEGL::OnMakeCurrent(context);
228 }
229
230 bool Resize(const gfx::Size& size) override {
231 return GLSurfaceOzoneSurfaceless::Resize(size) && ResizePixmaps();
232 }
233
234 bool SupportsPostSubBuffer() override { return false; }
235
236 bool SwapBuffers() override {
237 bool ret = images_[current_surface_]->ScheduleOverlayPlane(
238 widget_, 0, OverlayTransform::OVERLAY_TRANSFORM_NONE,
239 gfx::Rect(GetSize()), gfx::RectF(1, 1)) &&
240 GLSurfaceOzoneSurfaceless::SwapBuffers();
241 current_surface_ ^= 1;
242 BindFramebuffer();
243 return ret;
244 }
245
246 void Destroy() override {
247 GLContext* current_context = GLContext::GetCurrent();
248 DCHECK(current_context && current_context->IsCurrent(this));
249 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
250 if (fbo_) {
251 glDeleteTextures(2, textures_);
252 glDeleteFramebuffersEXT(1, &fbo_);
253 }
254 for (int i = 0; i < 2; i++) {
255 if (images_[i])
256 images_[i]->Destroy(true);
257 }
258 }
259
260 private:
261 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override {}
262
263 void BindFramebuffer() {
264 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_);
265 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
266 GL_TEXTURE_2D, textures_[current_surface_], 0);
267 }
268
269 bool ResizePixmaps() {
270 if (!fbo_)
271 return true;
272 for (int i = 0; i < 2; i++) {
273 scoped_refptr<ui::NativePixmap> pixmap =
274 ui::SurfaceFactoryOzone::GetInstance()->CreateNativePixmap(
275 widget_, GetSize(), ui::SurfaceFactoryOzone::RGBA_8888,
276 ui::SurfaceFactoryOzone::SCANOUT);
277 if (!pixmap)
278 return false;
279 scoped_refptr<GLImageLinuxDMABuffer> image =
280 new GLImageLinuxDMABuffer(GetSize(), GL_RGBA);
281 base::FileDescriptor handle(pixmap->GetDmaBufFd(), false);
282 if (!image->Initialize(handle, gfx::GpuMemoryBuffer::Format::BGRA_8888,
283 pixmap->GetDmaBufPitch()))
284 return false;
285 images_[i] = image;
286 pixmaps_[i] = pixmap;
287 // Bind image to texture.
288 glBindTexture(GL_TEXTURE_2D, textures_[i]);
289 if (!images_[i]->BindTexImage(GL_TEXTURE_2D))
290 return false;
291 }
292 return true;
293 }
294
295 GLuint fbo_;
296 GLuint textures_[2];
297 scoped_refptr<GLImage> images_[2];
298 scoped_refptr<ui::NativePixmap> pixmaps_[2];
299 int current_surface_;
300 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl);
301 };
302
197 } // namespace 303 } // namespace
198 304
199 // static 305 // static
200 bool GLSurface::InitializeOneOffInternal() { 306 bool GLSurface::InitializeOneOffInternal() {
201 switch (GetGLImplementation()) { 307 switch (GetGLImplementation()) {
202 case kGLImplementationEGLGLES2: 308 case kGLImplementationEGLGLES2:
203 if (!GLSurfaceEGL::InitializeOneOff()) { 309 if (!GLSurfaceEGL::InitializeOneOff()) {
204 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed."; 310 LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
205 return false; 311 return false;
206 } 312 }
207 313
208 return true; 314 return true;
209 case kGLImplementationOSMesaGL: 315 case kGLImplementationOSMesaGL:
210 case kGLImplementationMockGL: 316 case kGLImplementationMockGL:
211 return true; 317 return true;
212 default: 318 default:
213 return false; 319 return false;
214 } 320 }
215 } 321 }
216 322
217 // static 323 // static
324 scoped_refptr<GLSurface> GLSurface::CreateSurfacelessViewGLSurface(
325 gfx::AcceleratedWidget window) {
326 if (GetGLImplementation() == kGLImplementationEGLGLES2 &&
327 window != kNullAcceleratedWidget &&
328 GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
329 ui::SurfaceFactoryOzone::GetInstance()->CanShowPrimaryPlaneAsOverlay()) {
330 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
331 ui::SurfaceFactoryOzone::GetInstance()
332 ->CreateSurfacelessEGLSurfaceForWidget(window);
333 if (!surface_ozone)
334 return nullptr;
335 scoped_refptr<GLSurface> surface;
336 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window);
337 if (surface->Initialize())
338 return surface;
339 }
340
341 return nullptr;
342 }
343
344 // static
218 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( 345 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface(
219 gfx::AcceleratedWidget window) { 346 gfx::AcceleratedWidget window) {
220 if (GetGLImplementation() == kGLImplementationOSMesaGL) { 347 if (GetGLImplementation() == kGLImplementationOSMesaGL) {
221 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless()); 348 scoped_refptr<GLSurface> surface(new GLSurfaceOSMesaHeadless());
222 if (!surface->Initialize()) 349 if (!surface->Initialize())
223 return NULL; 350 return NULL;
224 return surface; 351 return surface;
225 } 352 }
226 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2); 353 DCHECK(GetGLImplementation() == kGLImplementationEGLGLES2);
227 if (window != kNullAcceleratedWidget) { 354 if (window != kNullAcceleratedWidget) {
228 scoped_refptr<GLSurface> surface; 355 scoped_refptr<GLSurface> surface;
229 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() && 356 if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
230 ui::SurfaceFactoryOzone::GetInstance() 357 ui::SurfaceFactoryOzone::GetInstance()
231 ->CanShowPrimaryPlaneAsOverlay()) { 358 ->CanShowPrimaryPlaneAsOverlay()) {
232 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 359 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
233 ui::SurfaceFactoryOzone::GetInstance() 360 ui::SurfaceFactoryOzone::GetInstance()
234 ->CreateSurfacelessEGLSurfaceForWidget(window); 361 ->CreateSurfacelessEGLSurfaceForWidget(window);
235 if (!surface_ozone) 362 if (!surface_ozone)
236 return NULL; 363 return NULL;
237 surface = new GLSurfaceOzoneSurfaceless(surface_ozone.Pass(), window); 364 surface = new GLSurfaceOzoneSurfacelessSurfaceImpl(surface_ozone.Pass(),
365 window);
238 } else { 366 } else {
239 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone = 367 scoped_ptr<ui::SurfaceOzoneEGL> surface_ozone =
240 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget( 368 ui::SurfaceFactoryOzone::GetInstance()->CreateEGLSurfaceForWidget(
241 window); 369 window);
242 if (!surface_ozone) 370 if (!surface_ozone)
243 return NULL; 371 return NULL;
244 372
245 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window); 373 surface = new GLSurfaceOzoneEGL(surface_ozone.Pass(), window);
246 } 374 }
247 if (!surface->Initialize()) 375 if (!surface->Initialize())
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 NOTREACHED(); 411 NOTREACHED();
284 return NULL; 412 return NULL;
285 } 413 }
286 } 414 }
287 415
288 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { 416 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
289 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); 417 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay();
290 } 418 }
291 419
292 } // namespace gfx 420 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698