Home | History | Annotate | Download | only in dri
      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.
      4 
      5 #include "ui/ozone/platform/dri/gbm_surface_factory.h"
      6 
      7 #include <EGL/egl.h>
      8 #include <gbm.h>
      9 
     10 #include "base/files/file_path.h"
     11 #include "ui/ozone/platform/dri/buffer_data.h"
     12 #include "ui/ozone/platform/dri/dri_vsync_provider.h"
     13 #include "ui/ozone/platform/dri/gbm_surface.h"
     14 #include "ui/ozone/platform/dri/hardware_display_controller.h"
     15 #include "ui/ozone/platform/dri/scanout_surface.h"
     16 #include "ui/ozone/platform/dri/screen_manager.h"
     17 #include "ui/ozone/public/surface_ozone_egl.h"
     18 
     19 namespace ui {
     20 
     21 namespace {
     22 
     23 class GbmSurfaceAdapter : public ui::SurfaceOzoneEGL {
     24  public:
     25   GbmSurfaceAdapter(const base::WeakPtr<HardwareDisplayController>& controller);
     26   virtual ~GbmSurfaceAdapter();
     27 
     28   // SurfaceOzoneEGL:
     29   virtual intptr_t GetNativeWindow() OVERRIDE;
     30   virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) OVERRIDE;
     31   virtual bool OnSwapBuffers() OVERRIDE;
     32   virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() OVERRIDE;
     33 
     34  private:
     35   base::WeakPtr<HardwareDisplayController> controller_;
     36 
     37   DISALLOW_COPY_AND_ASSIGN(GbmSurfaceAdapter);
     38 };
     39 
     40 GbmSurfaceAdapter::GbmSurfaceAdapter(
     41     const base::WeakPtr<HardwareDisplayController>& controller)
     42     : controller_(controller) {}
     43 
     44 GbmSurfaceAdapter::~GbmSurfaceAdapter() {}
     45 
     46 intptr_t GbmSurfaceAdapter::GetNativeWindow() {
     47   if (!controller_)
     48     return 0;
     49 
     50   return reinterpret_cast<intptr_t>(
     51       static_cast<GbmSurface*>(controller_->surface())->native_surface());
     52 }
     53 
     54 bool GbmSurfaceAdapter::ResizeNativeWindow(const gfx::Size& viewport_size) {
     55   NOTIMPLEMENTED();
     56   return false;
     57 }
     58 
     59 bool GbmSurfaceAdapter::OnSwapBuffers() {
     60   if (!controller_)
     61     return false;
     62 
     63   static_cast<GbmSurface*>(controller_->surface())->LockCurrentDrawable();
     64   if (controller_->SchedulePageFlip()) {
     65     controller_->WaitForPageFlipEvent();
     66     return true;
     67   }
     68 
     69   return false;
     70 }
     71 
     72 scoped_ptr<gfx::VSyncProvider> GbmSurfaceAdapter::CreateVSyncProvider() {
     73   return scoped_ptr<gfx::VSyncProvider>(new DriVSyncProvider(controller_));
     74 }
     75 
     76 }  // namespace
     77 
     78 GbmSurfaceFactory::GbmSurfaceFactory(DriWrapper* dri,
     79                                      gbm_device* device,
     80                                      ScreenManager* screen_manager)
     81     : DriSurfaceFactory(dri, screen_manager),
     82       device_(device) {}
     83 
     84 GbmSurfaceFactory::~GbmSurfaceFactory() {}
     85 
     86 intptr_t GbmSurfaceFactory::GetNativeDisplay() {
     87   CHECK(state_ == INITIALIZED);
     88   return reinterpret_cast<intptr_t>(device_);
     89 }
     90 
     91 const int32* GbmSurfaceFactory::GetEGLSurfaceProperties(
     92     const int32* desired_list) {
     93   static const int32 kConfigAttribs[] = {
     94     EGL_BUFFER_SIZE, 32,
     95     EGL_ALPHA_SIZE, 8,
     96     EGL_BLUE_SIZE, 8,
     97     EGL_GREEN_SIZE, 8,
     98     EGL_RED_SIZE, 8,
     99     EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
    100     EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
    101     EGL_NONE
    102   };
    103 
    104   return kConfigAttribs;
    105 }
    106 
    107 bool GbmSurfaceFactory::LoadEGLGLES2Bindings(
    108       AddGLLibraryCallback add_gl_library,
    109       SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
    110   base::NativeLibraryLoadError error;
    111   base::NativeLibrary gles_library = base::LoadNativeLibrary(
    112       base::FilePath("libGLESv2.so.2"),
    113       &error);
    114   if (!gles_library) {
    115     LOG(WARNING) << "Failed to load GLES library: " << error.ToString();
    116     return false;
    117   }
    118 
    119   base::NativeLibrary egl_library = base::LoadNativeLibrary(
    120       base::FilePath("libEGL.so.1"),
    121       &error);
    122   if (!egl_library) {
    123     LOG(WARNING) << "Failed to load EGL library: " << error.ToString();
    124     base::UnloadNativeLibrary(gles_library);
    125     return false;
    126   }
    127 
    128   GLGetProcAddressProc get_proc_address =
    129       reinterpret_cast<GLGetProcAddressProc>(
    130           base::GetFunctionPointerFromNativeLibrary(
    131               egl_library, "eglGetProcAddress"));
    132   if (!get_proc_address) {
    133     LOG(ERROR) << "eglGetProcAddress not found.";
    134     base::UnloadNativeLibrary(egl_library);
    135     base::UnloadNativeLibrary(gles_library);
    136     return false;
    137   }
    138 
    139   set_gl_get_proc_address.Run(get_proc_address);
    140   add_gl_library.Run(egl_library);
    141   add_gl_library.Run(gles_library);
    142 
    143   return true;
    144 }
    145 
    146 scoped_ptr<ui::SurfaceOzoneEGL> GbmSurfaceFactory::CreateEGLSurfaceForWidget(
    147     gfx::AcceleratedWidget w) {
    148   CHECK(state_ == INITIALIZED);
    149   ResetCursor(w);
    150 
    151   return scoped_ptr<ui::SurfaceOzoneEGL>(
    152       new GbmSurfaceAdapter(screen_manager_->GetDisplayController(w)));
    153 }
    154 
    155 gfx::NativeBufferOzone GbmSurfaceFactory::CreateNativeBuffer(
    156     gfx::Size size,
    157     BufferFormat format) {
    158   uint32_t gbm_format = 0;
    159   switch (format) {
    160     case SurfaceFactoryOzone::UNKNOWN:
    161       return 0;
    162     // TODO(alexst): Setting this to XRGB for now to allow presentation
    163     // as a primary plane but disallowing overlay transparency. Address this
    164     // to allow both use cases.
    165     case SurfaceFactoryOzone::RGBA_8888:
    166       gbm_format = GBM_FORMAT_XRGB8888;
    167       break;
    168     case SurfaceFactoryOzone::RGB_888:
    169       gbm_format = GBM_FORMAT_RGB888;
    170       break;
    171   }
    172   gbm_bo* buffer_object =
    173       gbm_bo_create(device_,
    174                     size.width(),
    175                     size.height(),
    176                     gbm_format,
    177                     GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
    178   if (!buffer_object)
    179     return 0;
    180 
    181   BufferData* data = BufferData::CreateData(drm_, buffer_object);
    182   DCHECK(data) << "Failed to associate the buffer with the controller";
    183 
    184   return reinterpret_cast<gfx::NativeBufferOzone>(buffer_object);
    185 }
    186 
    187 }  // namespace ui
    188