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

Side by Side Diff: ui/gfx/ozone/dri/gbm_surface_factory.cc

Issue 132543002: Not for review. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 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/gfx/ozone/dri/gbm_surface_factory.h"
6
7 #include <drm.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <xf86drm.h>
11
12 //#include <EGL/egl.h>
13 //#include <EGL/eglext.h>
14
15 #include "base/files/file_path.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/native_library.h"
18 #include "third_party/khronos/EGL/egl.h"
19 #include "third_party/khronos/EGL/eglext.h"
20 #include "third_party/mesa/src/src/gbm/main/gbm.h"
21 #include "third_party/skia/include/core/SkBitmapDevice.h"
22 #include "third_party/skia/include/core/SkCanvas.h"
23 #include "ui/gfx/ozone/dri/dri_wrapper.h"
24 #include "ui/gfx/ozone/dri/gbm_surface.h"
25 #include "ui/gfx/ozone/dri/hardware_display_controller.h"
26 #include "ui/gfx/ozone/dri/scanout_surface.h"
27
28 namespace gfx {
29
30 namespace {
31
32 typedef EGLBoolean (*eglSwapBuffersProc)(EGLDisplay dpy, EGLSurface surface);
33
34 static eglSwapBuffersProc g_native_egl_swap_buffers;
35
36 EGLBoolean CustomEglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
37 EGLBoolean ret = g_native_egl_swap_buffers(dpy, surface);
38
39 // TODO(dnicoara) Once we support multiple displays we need to keep a mapping
40 // between |surface| and AcceleratedWidgets such that we can select the
41 // widget based on the |surface|.
42 if (ret)
43 gfx::SurfaceFactoryOzone::GetInstance()->SchedulePageFlip(1);
44
45 return ret;
46 }
47
48 struct NativeBufferInfo {
49 gfx::Size size;
50 uint32_t fb;
51 };
52
53 void NativeBufferInfoDestroy(gbm_bo* buffer, void* data) {
54 NativeBufferInfo* bd = static_cast<NativeBufferInfo*>(data);
55 delete bd;
56 }
57
58 } // namespace
59
60 GbmSurfaceFactory::GbmSurfaceFactory()
61 : DriSurfaceFactory(),
62 device_(NULL) {
63 }
64
65 GbmSurfaceFactory::~GbmSurfaceFactory() {
66 if (state_ == INITIALIZED)
67 ShutdownHardware();
68 }
69
70 SurfaceFactoryOzone::HardwareState
71 GbmSurfaceFactory::InitializeHardware() {
72 CHECK(state_ == UNINITIALIZED);
73
74 if (DriSurfaceFactory::InitializeHardware() != INITIALIZED)
75 return state_;
76
77 device_ = gbm_create_device(drm_->get_fd());
78
79 if (!device_) {
80 LOG(ERROR) << "Cannot create GBM device";
81 state_ = FAILED;
82 return state_;
83 }
84
85 // TODO(dnicoara) Figure out where this initialization needs to be done.
86 if (!controller_.get())
87 controller_.reset(new HardwareDisplayController());
88
89 state_ = INITIALIZED;
90 return state_;
91 }
92
93 void GbmSurfaceFactory::ShutdownHardware() {
94 CHECK(state_ == INITIALIZED);
95
96 gbm_device_destroy(device_);
97 DriSurfaceFactory::ShutdownHardware();
98 }
99
100 intptr_t GbmSurfaceFactory::GetNativeDisplay() {
101 CHECK(state_ == INITIALIZED);
102 return reinterpret_cast<intptr_t>(device_);
103 }
104
105 const int32* GbmSurfaceFactory::GetEGLSurfaceProperties(
106 const int32* desired_list) {
107 static const int32 kConfigAttribs[] = {
108 EGL_BUFFER_SIZE, 32,
109 EGL_ALPHA_SIZE, 8,
110 EGL_BLUE_SIZE, 8,
111 EGL_GREEN_SIZE, 8,
112 EGL_RED_SIZE, 8,
113 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
114 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
115 EGL_NONE
116 };
117
118 return kConfigAttribs;
119 }
120
121 bool GbmSurfaceFactory::LoadEGLGLES2Bindings(
122 AddGLLibraryCallback add_gl_library,
123 SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
124 std::string error;
125 base::NativeLibrary gles_library = base::LoadNativeLibrary(
126 base::FilePath("libGLESv2.so.2"),
127 &error);
128 if (!gles_library) {
129 LOG(WARNING) << "Failed to load GLES library: " << error;
130 return false;
131 }
132
133 base::NativeLibrary egl_library = base::LoadNativeLibrary(
134 base::FilePath("libEGL.so.1"),
135 &error);
136 if (!egl_library) {
137 LOG(WARNING) << "Failed to load EGL library: " << error;
138 base::UnloadNativeLibrary(gles_library);
139 return false;
140 }
141
142 GLGetProcAddressProc get_proc_address =
143 reinterpret_cast<GLGetProcAddressProc>(
144 base::GetFunctionPointerFromNativeLibrary(
145 egl_library, "eglGetProcAddress"));
146 if (!get_proc_address) {
147 LOG(ERROR) << "eglGetProcAddress not found.";
148 base::UnloadNativeLibrary(egl_library);
149 base::UnloadNativeLibrary(gles_library);
150 return false;
151 }
152
153 set_gl_get_proc_address.Run(get_proc_address);
154 add_gl_library.Run(egl_library);
155 add_gl_library.Run(gles_library);
156
157 return true;
158 }
159
160 bool GbmSurfaceFactory::AttemptToResizeAcceleratedWidget(
161 gfx::AcceleratedWidget w,
162 const gfx::Rect& bounds) {
163 return false;
164 }
165
166 bool GbmSurfaceFactory::SchedulePageFlip(gfx::AcceleratedWidget w) {
167 CHECK(state_ == INITIALIZED);
168
169 // TODO(dnicoara) Once we can handle multiple displays this needs to be
170 // changed.
171 CHECK(w == 1);
172
173 static_cast<GbmSurface*>(controller_->get_surface())
174 ->LockCurrentDrawable();
175 return DriSurfaceFactory::SchedulePageFlip(w);
176 }
177
178 void* GbmSurfaceFactory::GetFunctionPointerFromNativeLibrary(
179 base::NativeLibrary library,
180 const char* name) {
181 void* function = SurfaceFactoryOzone::GetFunctionPointerFromNativeLibrary(
182 library,
183 name);
184
185 if (strcmp(name, "eglSwapBuffers") == 0) {
186 g_native_egl_swap_buffers = reinterpret_cast<eglSwapBuffersProc>(function);
187 function = reinterpret_cast<void*>(CustomEglSwapBuffers);
188 }
189
190 return function;
191 }
192
193 gfx::VSyncProvider* GbmSurfaceFactory::GetVSyncProvider(
194 gfx::AcceleratedWidget w) {
195 return NULL;
196 }
197
198 gfx::AcceleratedWidget GbmSurfaceFactory::CreateNativeBuffer(
199 gfx::Size size,
200 unsigned internalformat) {
201 gbm_bo* bo = gbm_bo_create(device_,
202 size.width(),
203 size.height(),
204 // GBM_BO_FORMAT_XRGB8888,
205 GBM_FORMAT_ARGB8888,
206 GBM_BO_USE_SCANOUT |
207 // GBM_BO_USE_CURSOR_64X64 |
208 GBM_BO_USE_RENDERING |
209 // GBM_BO_USE_WRITE |
210 0);
211 NativeBufferInfo* info = new NativeBufferInfo;
212 info->size = size;
213 uint32_t bo_handle = gbm_bo_get_handle(bo).u32;
214 uint32_t stride = gbm_bo_get_stride(bo);
215 controller_->AddFramebuffer(24, 32, stride, bo_handle, &info->fb);
216 gbm_bo_set_user_data(bo, info, NativeBufferInfoDestroy);
217
218 return reinterpret_cast<gfx::AcceleratedWidget>(bo);
219 }
220
221 void GbmSurfaceFactory::SetOverlayPlane(int plane_id,
222 gfx::AcceleratedWidget handle,
223 const gfx::Rect& bounds) {
224 gbm_bo* bo = reinterpret_cast<gbm_bo*>(handle);
225 NativeBufferInfo* info =
226 static_cast<NativeBufferInfo*>(gbm_bo_get_user_data(bo));
227
228 controller_->SetOverlayPlaneInfo(bounds, info->size, info->fb);
229 }
230
231
232 void GbmSurfaceFactory::CheckOverlaySupport(SurfaceCandidateList* surfaces) {
233 if ((surfaces->size() == 1 || surfaces->size() == 2) &&
234 (surfaces->at(0).format == RGBA || surfaces->at(0).format == RGBA)) {
235 surfaces->at(0).overlay_handled = true;
236 }
237 }
238
239 ////////////////////////////////////////////////////////////////////////////////
240 // DriSurfaceFactory private
241
242 ScanoutSurface* GbmSurfaceFactory::CreateSurface(
243 HardwareDisplayController* controller) {
244 return new GbmSurface(controller_.get(), device_);
245 }
246
247 gfx::AcceleratedWidget GbmSurfaceFactory::GetNativeWidget(
248 ScanoutSurface* surface) {
249 return reinterpret_cast<gfx::AcceleratedWidget>(
250 static_cast<GbmSurface*>(surface)->get_native_surface());
251 }
252
253 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698