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_buffer.h"
16 SurfacelessGlRenderer::BufferWrapper::BufferWrapper()
17 : widget_(gfx::kNullAcceleratedWidget
), gl_fb_(0), gl_tex_(0) {
20 SurfacelessGlRenderer::BufferWrapper::~BufferWrapper() {
22 glDeleteFramebuffersEXT(1, &gl_fb_
);
25 image_
->ReleaseTexImage(GL_TEXTURE_2D
);
26 glDeleteTextures(1, &gl_tex_
);
27 image_
->Destroy(true);
31 bool SurfacelessGlRenderer::BufferWrapper::Initialize(
32 GpuMemoryBufferFactoryOzoneNativeBuffer
* buffer_factory
,
33 gfx::AcceleratedWidget widget
,
34 const gfx::Size
& size
) {
35 glGenFramebuffersEXT(1, &gl_fb_
);
36 glGenTextures(1, &gl_tex_
);
38 static int buffer_id_generator
= 1;
39 int id
= buffer_id_generator
++;
41 buffer_factory
->CreateGpuMemoryBuffer(
42 id
, size
, gfx::GpuMemoryBuffer::RGBX_8888
, gfx::GpuMemoryBuffer::SCANOUT
,
44 image_
= buffer_factory
->CreateImageForGpuMemoryBuffer(
45 id
, size
, gfx::GpuMemoryBuffer::RGBX_8888
, GL_RGB
, 1);
46 // Now that we have a reference to |image_|; we can just remove it from the
48 buffer_factory
->DestroyGpuMemoryBuffer(id
, widget
);
51 LOG(ERROR
) << "Failed to create GL image";
55 glBindFramebufferEXT(GL_FRAMEBUFFER
, gl_fb_
);
56 glBindTexture(GL_TEXTURE_2D
, gl_tex_
);
57 image_
->BindTexImage(GL_TEXTURE_2D
);
59 glFramebufferTexture2DEXT(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
, GL_TEXTURE_2D
,
61 if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER
) != GL_FRAMEBUFFER_COMPLETE
) {
62 LOG(ERROR
) << "Failed to create framebuffer "
63 << glCheckFramebufferStatusEXT(GL_FRAMEBUFFER
);
73 void SurfacelessGlRenderer::BufferWrapper::BindFramebuffer() {
74 glBindFramebufferEXT(GL_FRAMEBUFFER
, gl_fb_
);
77 void SurfacelessGlRenderer::BufferWrapper::SchedulePlane() {
78 image_
->ScheduleOverlayPlane(widget_
, 0, gfx::OVERLAY_TRANSFORM_NONE
,
79 gfx::Rect(size_
), gfx::RectF(0, 0, 1, 1));
82 SurfacelessGlRenderer::SurfacelessGlRenderer(
83 gfx::AcceleratedWidget widget
,
84 const gfx::Size
& size
,
85 GpuMemoryBufferFactoryOzoneNativeBuffer
* buffer_factory
)
86 : GlRenderer(widget
, size
),
87 buffer_factory_(buffer_factory
),
89 is_swapping_buffers_(false),
90 weak_ptr_factory_(this) {
93 SurfacelessGlRenderer::~SurfacelessGlRenderer() {
94 // Need to make current when deleting the framebuffer resources allocated in
96 context_
->MakeCurrent(surface_
.get());
99 bool SurfacelessGlRenderer::Initialize() {
100 if (!GlRenderer::Initialize())
103 for (size_t i
= 0; i
< arraysize(buffers_
); ++i
)
104 if (!buffers_
[i
].Initialize(buffer_factory_
, widget_
, size_
))
110 void SurfacelessGlRenderer::RenderFrame() {
111 if (is_swapping_buffers_
)
114 float fraction
= NextFraction();
116 context_
->MakeCurrent(surface_
.get());
117 buffers_
[back_buffer_
].BindFramebuffer();
119 glViewport(0, 0, size_
.width(), size_
.height());
120 glClearColor(1 - fraction
, fraction
, 0.0, 1.0);
121 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
123 buffers_
[back_buffer_
].SchedulePlane();
124 is_swapping_buffers_
= true;
125 if (!surface_
->SwapBuffersAsync(
126 base::Bind(&SurfacelessGlRenderer::OnSwapBuffersAck
,
127 weak_ptr_factory_
.GetWeakPtr())))
128 LOG(FATAL
) << "Failed to swap buffers";
131 void SurfacelessGlRenderer::OnSwapBuffersAck() {
132 is_swapping_buffers_
= false;
136 scoped_refptr
<gfx::GLSurface
> SurfacelessGlRenderer::CreateSurface() {
137 return gfx::GLSurface::CreateSurfacelessViewGLSurface(widget_
);