summaryrefslogtreecommitdiffstats
path: root/chromium/ui/ozone/platform/dri/gbm_surface.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/ozone/platform/dri/gbm_surface.cc')
-rw-r--r--chromium/ui/ozone/platform/dri/gbm_surface.cc112
1 files changed, 112 insertions, 0 deletions
diff --git a/chromium/ui/ozone/platform/dri/gbm_surface.cc b/chromium/ui/ozone/platform/dri/gbm_surface.cc
new file mode 100644
index 00000000000..99f0ae7016f
--- /dev/null
+++ b/chromium/ui/ozone/platform/dri/gbm_surface.cc
@@ -0,0 +1,112 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/dri/gbm_surface.h"
+
+#include <gbm.h>
+
+#include "base/logging.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
+#include "ui/ozone/platform/dri/buffer_data.h"
+#include "ui/ozone/platform/dri/dri_buffer.h"
+#include "ui/ozone/platform/dri/dri_wrapper.h"
+#include "ui/ozone/platform/dri/hardware_display_controller.h"
+
+namespace ui {
+
+GbmSurface::GbmSurface(gbm_device* device,
+ DriWrapper* dri,
+ const gfx::Size& size)
+ : gbm_device_(device),
+ dri_(dri),
+ size_(size),
+ native_surface_(NULL),
+ buffers_(),
+ front_buffer_(0) {
+ for (size_t i = 0; i < arraysize(buffers_); ++i)
+ buffers_[i] = NULL;
+}
+
+GbmSurface::~GbmSurface() {
+ for (size_t i = 0; i < arraysize(buffers_); ++i) {
+ if (buffers_[i]) {
+ gbm_surface_release_buffer(native_surface_, buffers_[i]);
+ }
+ }
+
+ if (native_surface_)
+ gbm_surface_destroy(native_surface_);
+}
+
+bool GbmSurface::Initialize() {
+ // TODO(dnicoara) Check underlying system support for pixel format.
+ native_surface_ = gbm_surface_create(
+ gbm_device_,
+ size_.width(),
+ size_.height(),
+ GBM_BO_FORMAT_XRGB8888,
+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
+
+ if (!native_surface_)
+ return false;
+
+ dumb_buffer_.reset(new DriBuffer(dri_));
+ if (!dumb_buffer_->Initialize(SkImageInfo::MakeN32Premul(size_.width(),
+ size_.height())))
+ return false;
+
+ return true;
+}
+
+uint32_t GbmSurface::GetFramebufferId() const {
+ if (!buffers_[front_buffer_ ^ 1])
+ return dumb_buffer_->framebuffer();
+
+ BufferData* data = BufferData::GetData(buffers_[front_buffer_ ^ 1]);
+ CHECK(data);
+ return data->framebuffer();
+}
+
+uint32_t GbmSurface::GetHandle() const {
+ if (!buffers_[front_buffer_ ^ 1])
+ return dumb_buffer_->handle();
+
+ BufferData* data = BufferData::GetData(buffers_[front_buffer_ ^ 1]);
+ CHECK(data);
+ return data->handle();
+}
+
+gfx::Size GbmSurface::Size() const {
+ return size_;
+}
+
+void GbmSurface::SwapBuffers() {
+ // If there was a frontbuffer, is no longer active. Release it back to GBM.
+ if (buffers_[front_buffer_])
+ gbm_surface_release_buffer(native_surface_, buffers_[front_buffer_]);
+
+ // Update the index to the frontbuffer.
+ front_buffer_ ^= 1;
+ // We've just released it. Since GBM doesn't guarantee we'll get the same
+ // buffer back, we set it to NULL so we don't keep track of objects that may
+ // have been destroyed.
+ buffers_[front_buffer_ ^ 1] = NULL;
+}
+
+void GbmSurface::LockCurrentDrawable() {
+ CHECK(native_surface_);
+ // Lock the buffer we want to display.
+ buffers_[front_buffer_ ^ 1] = gbm_surface_lock_front_buffer(native_surface_);
+
+ BufferData* data = BufferData::GetData(buffers_[front_buffer_ ^ 1]);
+ // If it is a new buffer, it won't have any data associated with it. So we
+ // create it. On creation it will associate itself with the buffer and
+ // register the buffer.
+ if (!data) {
+ data = BufferData::CreateData(dri_, buffers_[front_buffer_ ^ 1]);
+ DCHECK(data) << "Failed to associate the buffer with the controller";
+ }
+}
+
+} // namespace ui