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

Unified Diff: ui/gfx/ozone/dri/gbm_surface_factory.cc

Issue 106633002: GBM Ozone implementation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased Created 6 years, 10 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
Index: ui/gfx/ozone/dri/gbm_surface_factory.cc
diff --git a/ui/gfx/ozone/dri/gbm_surface_factory.cc b/ui/gfx/ozone/dri/gbm_surface_factory.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c7d569d99694c0527ceca884741c26d9e232ebde
--- /dev/null
+++ b/ui/gfx/ozone/dri/gbm_surface_factory.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/gfx/ozone/dri/gbm_surface_factory.h"
+
+#include <drm.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <xf86drm.h>
+
+#include "base/files/file_path.h"
+#include "base/message_loop/message_loop.h"
+#include "base/native_library.h"
+#include "third_party/khronos/EGL/egl.h"
+#include "third_party/khronos/EGL/eglext.h"
+#include "third_party/mesa/src/src/gbm/main/gbm.h"
+#include "third_party/skia/include/core/SkBitmapDevice.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "ui/gfx/ozone/dri/dri_wrapper.h"
+#include "ui/gfx/ozone/dri/gbm_surface.h"
+#include "ui/gfx/ozone/dri/hardware_display_controller.h"
+#include "ui/gfx/ozone/dri/scanout_surface.h"
+
+namespace gfx {
+
+namespace {
+
+typedef EGLBoolean (*eglSwapBuffersProc)(EGLDisplay dpy, EGLSurface surface);
+
+static eglSwapBuffersProc g_native_egl_swap_buffers;
+
+EGLBoolean CustomEglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
+ EGLBoolean ret = g_native_egl_swap_buffers(dpy, surface);
+
+ // TODO(dnicoara) Once we support multiple displays we need to keep a mapping
+ // between |surface| and AcceleratedWidgets such that we can select the
+ // widget based on the |surface|.
+ if (ret)
+ gfx::SurfaceFactoryOzone::GetInstance()->SchedulePageFlip(1);
+
+ return ret;
+}
+
+} // namespace
+
+GbmSurfaceFactory::GbmSurfaceFactory()
+ : DriSurfaceFactory(),
+ device_(NULL) {
+}
+
+GbmSurfaceFactory::~GbmSurfaceFactory() {
+ if (state_ == INITIALIZED)
+ ShutdownHardware();
+}
+
+SurfaceFactoryOzone::HardwareState
+GbmSurfaceFactory::InitializeHardware() {
+ CHECK(state_ == UNINITIALIZED);
+
+ if (DriSurfaceFactory::InitializeHardware() != INITIALIZED)
+ return state_;
+
+ device_ = gbm_create_device(drm_->get_fd());
+
+ if (!device_) {
+ LOG(ERROR) << "Cannot create GBM device";
+ state_ = FAILED;
+ return state_;
+ }
+
+ // TODO(dnicoara) Figure out where this initialization needs to be done.
+ if (!controller_.get())
+ controller_.reset(new HardwareDisplayController());
+
+ state_ = INITIALIZED;
+ return state_;
+}
+
+void GbmSurfaceFactory::ShutdownHardware() {
+ CHECK(state_ == INITIALIZED);
+
+ gbm_device_destroy(device_);
+ DriSurfaceFactory::ShutdownHardware();
+}
+
+intptr_t GbmSurfaceFactory::GetNativeDisplay() {
+ CHECK(state_ == INITIALIZED);
+ return reinterpret_cast<intptr_t>(device_);
+}
+
+const int32* GbmSurfaceFactory::GetEGLSurfaceProperties(
+ const int32* desired_list) {
+ static const int32 kConfigAttribs[] = {
+ EGL_BUFFER_SIZE, 32,
+ EGL_ALPHA_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_NONE
+ };
+
+ return kConfigAttribs;
+}
+
+bool GbmSurfaceFactory::LoadEGLGLES2Bindings(
+ AddGLLibraryCallback add_gl_library,
+ SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
+ std::string error;
+ base::NativeLibrary gles_library = base::LoadNativeLibrary(
+ base::FilePath("libGLESv2.so.2"),
+ &error);
+ if (!gles_library) {
+ LOG(WARNING) << "Failed to load GLES library: " << error;
+ return false;
+ }
+
+ base::NativeLibrary egl_library = base::LoadNativeLibrary(
+ base::FilePath("libEGL.so.1"),
+ &error);
+ if (!egl_library) {
+ LOG(WARNING) << "Failed to load EGL library: " << error;
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(
+ egl_library, "eglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "eglGetProcAddress not found.";
+ base::UnloadNativeLibrary(egl_library);
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ set_gl_get_proc_address.Run(get_proc_address);
+ add_gl_library.Run(egl_library);
+ add_gl_library.Run(gles_library);
+
+ return true;
+}
+
+bool GbmSurfaceFactory::AttemptToResizeAcceleratedWidget(
+ gfx::AcceleratedWidget w,
+ const gfx::Rect& bounds) {
+ return false;
+}
+
+SkCanvas* GbmSurfaceFactory::GetCanvasForWidget(
+ gfx::AcceleratedWidget w) {
+ CHECK(state_ == INITIALIZED);
+ // TODO(dnicoara) Figure out how this is used and unhack.
+ static SkBitmapDevice* device = new SkBitmapDevice(
+ SkBitmap::kARGB_8888_Config,
+ controller_->get_mode().hdisplay,
+ controller_->get_mode().vdisplay);
+ static SkCanvas canvas(device);
+ return &canvas;
+}
+
+bool GbmSurfaceFactory::SchedulePageFlip(gfx::AcceleratedWidget w) {
+ CHECK(state_ == INITIALIZED);
+
+ // TODO(dnicoara) Once we can handle multiple displays this needs to be
+ // changed.
+ CHECK(w == 1);
+
+ static_cast<GbmSurface*>(controller_->get_surface())
+ ->LockCurrentDrawable();
+ return DriSurfaceFactory::SchedulePageFlip(w);
+}
+
+void* GbmSurfaceFactory::GetFunctionPointerFromNativeLibrary(
+ base::NativeLibrary library,
+ const char* name) {
+ void* function = SurfaceFactoryOzone::GetFunctionPointerFromNativeLibrary(
+ library,
+ name);
+
+ if (strcmp(name, "eglSwapBuffers") == 0) {
+ g_native_egl_swap_buffers = reinterpret_cast<eglSwapBuffersProc>(function);
+ function = reinterpret_cast<void*>(CustomEglSwapBuffers);
+ }
+
+ return function;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// DriSurfaceFactory private
+
+ScanoutSurface* GbmSurfaceFactory::CreateSurface(
+ HardwareDisplayController* controller) {
+ return new GbmSurface(controller_.get(), device_);
+}
+
+gfx::AcceleratedWidget GbmSurfaceFactory::GetNativeWidget(
+ ScanoutSurface* surface) {
+ return reinterpret_cast<gfx::AcceleratedWidget>(
+ static_cast<GbmSurface*>(surface)->get_native_surface());
+}
+
+} // namespace gfx

Powered by Google App Engine
This is Rietveld 408576698