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
3 // found in the LICENSE file.
5 #include "ui/ozone/demo/surfaceless_gl_renderer.h"
8 #include "ui/gl/gl_bindings.h"
9 #include "ui/gl/gl_context.h"
10 #include "ui/gl/gl_image.h"
11 #include "ui/gl/gl_surface.h"
12 #include "ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h"
16 SurfacelessGlRenderer::BufferWrapper::BufferWrapper() {
19 SurfacelessGlRenderer::BufferWrapper::~BufferWrapper() {
21 glDeleteFramebuffersEXT(1, &gl_fb_
);
24 image_
->ReleaseTexImage(GL_TEXTURE_2D
);
25 glDeleteTextures(1, &gl_tex_
);
26 image_
->Destroy(true);
30 bool SurfacelessGlRenderer::BufferWrapper::Initialize(
31 GpuMemoryBufferFactoryOzoneNativePixmap
* buffer_factory
,
32 gfx::AcceleratedWidget widget
,
33 const gfx::Size
& size
) {
34 glGenFramebuffersEXT(1, &gl_fb_
);
35 glGenTextures(1, &gl_tex_
);
37 static int buffer_id_generator
= 1;
38 int id
= buffer_id_generator
++;
40 buffer_factory
->CreateGpuMemoryBuffer(
41 id
, size
, gfx::GpuMemoryBuffer::RGBX_8888
, gfx::GpuMemoryBuffer::SCANOUT
,
43 image_
= buffer_factory
->CreateImageForGpuMemoryBuffer(
44 id
, size
, gfx::GpuMemoryBuffer::RGBX_8888
, GL_RGB
, 1);
45 // Now that we have a reference to |image_|; we can just remove it from the
47 buffer_factory
->DestroyGpuMemoryBuffer(id
, widget
);
50 LOG(ERROR
) << "Failed to create GL image";
54 glBindFramebufferEXT(GL_FRAMEBUFFER
, gl_fb_
);
55 glBindTexture(GL_TEXTURE_2D
, gl_tex_
);
56 image_
->BindTexImage(GL_TEXTURE_2D
);
58 glFramebufferTexture2DEXT(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
,
60 if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER
) != GL_FRAMEBUFFER_COMPLETE
) {
61 LOG(ERROR
) << "Failed to create framebuffer "
62 << glCheckFramebufferStatusEXT(GL_FRAMEBUFFER
);
72 void SurfacelessGlRenderer::BufferWrapper::BindFramebuffer() {
73 glBindFramebufferEXT(GL_FRAMEBUFFER
, gl_fb_
);
76 void SurfacelessGlRenderer::BufferWrapper::SchedulePlane() {
77 image_
->ScheduleOverlayPlane(widget_
, 0, gfx::OVERLAY_TRANSFORM_NONE
,
78 gfx::Rect(size_
), gfx::RectF(0, 0, 1, 1));
81 SurfacelessGlRenderer::SurfacelessGlRenderer(
82 gfx::AcceleratedWidget widget
,
83 const gfx::Size
& size
,
84 GpuMemoryBufferFactoryOzoneNativePixmap
* buffer_factory
)
85 : GlRenderer(widget
, size
),
86 buffer_factory_(buffer_factory
),
87 weak_ptr_factory_(this) {}
89 SurfacelessGlRenderer::~SurfacelessGlRenderer() {
90 // Need to make current when deleting the framebuffer resources allocated in
92 context_
->MakeCurrent(surface_
.get());
95 bool SurfacelessGlRenderer::Initialize() {
96 if (!GlRenderer::Initialize())
99 for (size_t i
= 0; i
< arraysize(buffers_
); ++i
)
100 if (!buffers_
[i
].Initialize(buffer_factory_
, widget_
, size_
))
103 PostRenderFrameTask(gfx::SwapResult::SWAP_ACK
);
107 void SurfacelessGlRenderer::RenderFrame() {
108 float fraction
= NextFraction();
110 context_
->MakeCurrent(surface_
.get());
111 buffers_
[back_buffer_
].BindFramebuffer();
113 glViewport(0, 0, size_
.width(), size_
.height());
114 glClearColor(1 - fraction
, 0.0, fraction
, 1.0);
115 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
117 buffers_
[back_buffer_
].SchedulePlane();
119 if (!surface_
->SwapBuffersAsync(base::Bind(&GlRenderer::PostRenderFrameTask
,
120 weak_ptr_factory_
.GetWeakPtr())))
121 LOG(FATAL
) << "Failed to swap buffers";
124 scoped_refptr
<gfx::GLSurface
> SurfacelessGlRenderer::CreateSurface() {
125 return gfx::GLSurface::CreateSurfacelessViewGLSurface(widget_
);