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

Unified Diff: ui/ozone/platform/dri/gbm_surface.cc

Issue 106633002: GBM Ozone implementation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/ozone/platform/dri/gbm_surface.h ('k') | ui/ozone/platform/dri/gbm_surface_factory.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/ozone/platform/dri/gbm_surface.cc
diff --git a/ui/ozone/platform/dri/gbm_surface.cc b/ui/ozone/platform/dri/gbm_surface.cc
new file mode 100644
index 0000000000000000000000000000000000000000..61f5fb751269fc4a7c1e95a3bbb74fac511558f1
--- /dev/null
+++ b/ui/ozone/platform/dri/gbm_surface.cc
@@ -0,0 +1,206 @@
+// Copyright 2013 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/dri_buffer.h"
+#include "ui/ozone/platform/dri/dri_wrapper.h"
+#include "ui/ozone/platform/dri/gbm_surface.h"
+#include "ui/ozone/platform/dri/hardware_display_controller.h"
+
+namespace ui {
+
+namespace {
+
+// Pixel configuration for the current buffer format.
+// TODO(dnicoara) These will need to change once we'll query the hardware for
+// supported configurations.
+const uint8_t kColorDepth = 24;
+const uint8_t kPixelDepth = 32;
+
+class BufferData {
+ public:
+ // When we create the BufferData we need to register the buffer. Once
+ // successfully registered, the |framebuffer_| field will hold the ID of the
+ // buffer. The controller will use this ID when scanning out the buffer. On
+ // creation we will also associate the BufferData with the buffer.
+ static BufferData* CreateData(DriWrapper* dri, gbm_bo* buffer);
+
+ // Callback used by GBM to destory the BufferData associated with a buffer.
+ static void Destroy(gbm_bo* buffer, void* data);
+
+ // Returns the BufferData associated with |buffer|. NULL if no data is
+ // associated.
+ static BufferData* GetData(gbm_bo* buffer);
+
+ uint32_t framebuffer() const { return framebuffer_; }
+ uint32_t handle() const { return handle_; }
+
+ private:
+ BufferData(DriWrapper* dri, gbm_bo* buffer);
+ ~BufferData();
+
+ DriWrapper* dri_;
+
+ uint32_t handle_;
+
+ // ID provided by the controller when the buffer is registered. This ID is
+ // used when scanning out the buffer.
+ uint32_t framebuffer_;
+
+ DISALLOW_COPY_AND_ASSIGN(BufferData);
+};
+
+BufferData::BufferData(DriWrapper* dri, gbm_bo* buffer)
+ : dri_(dri),
+ handle_(gbm_bo_get_handle(buffer).u32),
+ framebuffer_(0) {
+ // Register the buffer with the controller. This will allow us to scan out the
+ // buffer once we're done drawing into it. If we can't register the buffer
+ // then there's no point in having BufferData associated with it.
+ if (!dri_->AddFramebuffer(gbm_bo_get_width(buffer),
+ gbm_bo_get_height(buffer),
+ kColorDepth,
+ kPixelDepth,
+ gbm_bo_get_stride(buffer),
+ handle_,
+ &framebuffer_)) {
+ LOG(ERROR) << "Failed to register buffer";
+ }
+}
+
+BufferData::~BufferData() {
+ if (framebuffer_)
+ dri_->RemoveFramebuffer(framebuffer_);
+}
+
+// static
+BufferData* BufferData::CreateData(DriWrapper* dri,
+ gbm_bo* buffer) {
+ BufferData* data = new BufferData(dri, buffer);
+ if (!data->framebuffer()) {
+ delete data;
+ return NULL;
+ }
+
+ // GBM can destroy the buffers at any time as long as they aren't locked. This
+ // sets a callback such that we can clean up all our state when GBM destroys
+ // the buffer.
+ gbm_bo_set_user_data(buffer, data, BufferData::Destroy);
+
+ return data;
+}
+
+// static
+void BufferData::Destroy(gbm_bo* buffer, void* data) {
+ BufferData* bd = static_cast<BufferData*>(data);
+ delete bd;
+}
+
+// static
+BufferData* BufferData::GetData(gbm_bo* buffer) {
+ return static_cast<BufferData*>(gbm_bo_get_user_data(buffer));
+}
+
+} // namespace
+
+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
« no previous file with comments | « ui/ozone/platform/dri/gbm_surface.h ('k') | ui/ozone/platform/dri/gbm_surface_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698