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/platform/dri/gbm_surface.h"
9 #include "base/logging.h"
10 #include "ui/ozone/platform/dri/dri_buffer.h"
11 #include "ui/ozone/platform/dri/dri_wrapper.h"
12 #include "ui/ozone/platform/dri/gbm_buffer_base.h"
13 #include "ui/ozone/platform/dri/scanout_buffer.h"
19 class GbmSurfaceBuffer : public GbmBufferBase {
21 static scoped_refptr<GbmSurfaceBuffer> CreateBuffer(DriWrapper* dri,
23 static scoped_refptr<GbmSurfaceBuffer> GetBuffer(gbm_bo* buffer);
26 GbmSurfaceBuffer(DriWrapper* dri, gbm_bo* bo);
27 virtual ~GbmSurfaceBuffer();
29 static void Destroy(gbm_bo* buffer, void* data);
31 // This buffer is special and is released by GBM at any point in time (as
32 // long as it isn't being used). Since GBM should be the only one to
33 // release this buffer, keep a self-reference in order to keep this alive.
34 // When GBM calls Destroy(..) the self-reference will dissapear and this will
36 scoped_refptr<GbmSurfaceBuffer> self_;
38 DISALLOW_COPY_AND_ASSIGN(GbmSurfaceBuffer);
41 GbmSurfaceBuffer::GbmSurfaceBuffer(DriWrapper* dri, gbm_bo* bo)
42 : GbmBufferBase(dri, bo, true) {
43 if (GetFramebufferId()) {
45 gbm_bo_set_user_data(bo, this, GbmSurfaceBuffer::Destroy);
49 GbmSurfaceBuffer::~GbmSurfaceBuffer() {}
52 scoped_refptr<GbmSurfaceBuffer> GbmSurfaceBuffer::CreateBuffer(
53 DriWrapper* dri, gbm_bo* buffer) {
54 scoped_refptr<GbmSurfaceBuffer> scoped_buffer(new GbmSurfaceBuffer(dri,
56 if (!scoped_buffer->GetFramebufferId())
63 scoped_refptr<GbmSurfaceBuffer> GbmSurfaceBuffer::GetBuffer(gbm_bo* buffer) {
64 return scoped_refptr<GbmSurfaceBuffer>(
65 static_cast<GbmSurfaceBuffer*>(gbm_bo_get_user_data(buffer)));
69 void GbmSurfaceBuffer::Destroy(gbm_bo* buffer, void* data) {
70 GbmSurfaceBuffer* scoped_buffer = static_cast<GbmSurfaceBuffer*>(data);
71 scoped_buffer->self_ = NULL;
76 GbmSurface::GbmSurface(
77 const base::WeakPtr<HardwareDisplayController>& controller,
80 : GbmSurfaceless(controller),
83 native_surface_(NULL),
84 current_buffer_(NULL) {}
86 GbmSurface::~GbmSurface() {
88 gbm_surface_release_buffer(native_surface_, current_buffer_);
91 gbm_surface_destroy(native_surface_);
94 bool GbmSurface::Initialize() {
95 // TODO(dnicoara) Check underlying system support for pixel format.
96 native_surface_ = gbm_surface_create(
98 controller_->get_mode().hdisplay,
99 controller_->get_mode().vdisplay,
100 GBM_BO_FORMAT_XRGB8888,
101 GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
103 if (!native_surface_)
106 size_.SetSize(controller_->get_mode().hdisplay,
107 controller_->get_mode().vdisplay);
111 intptr_t GbmSurface::GetNativeWindow() {
112 DCHECK(native_surface_);
113 return reinterpret_cast<intptr_t>(native_surface_);
116 bool GbmSurface::ResizeNativeWindow(const gfx::Size& viewport_size) {
117 if (size_ == viewport_size)
123 bool GbmSurface::OnSwapBuffers() {
124 DCHECK(native_surface_);
126 gbm_bo* pending_buffer = gbm_surface_lock_front_buffer(native_surface_);
127 scoped_refptr<GbmSurfaceBuffer> primary =
128 GbmSurfaceBuffer::GetBuffer(pending_buffer);
130 primary = GbmSurfaceBuffer::CreateBuffer(dri_, pending_buffer);
132 LOG(ERROR) << "Failed to associate the buffer with the controller";
137 // The primary buffer is a special case.
138 controller_->QueueOverlayPlane(OverlayPlane(primary));
140 if (!GbmSurfaceless::OnSwapBuffers())
143 // If there was a frontbuffer, it is no longer active. Release it back to GBM.
145 gbm_surface_release_buffer(native_surface_, current_buffer_);
147 current_buffer_ = pending_buffer;