2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <cutils/ashmem.h>
22 #include <cutils/log.h>
24 #include <hardware/hardware.h>
25 #include <hardware/gralloc.h>
29 #include <sys/ioctl.h>
33 #include <utils/Vector.h>
35 #include <cutils/log.h>
36 #include <cutils/atomic.h>
42 #include "gralloc_priv.h"
44 /*****************************************************************************/
46 // numbers of buffers for page flipping
49 struct hwc_callback_entry
51 void (*callback
)(void *, private_handle_t
*);
55 typedef android::Vector
<struct hwc_callback_entry
> hwc_callback_queue_t
;
58 framebuffer_device_t device
;
61 /*****************************************************************************/
63 static int fb_setSwapInterval(struct framebuffer_device_t
* dev
,
66 fb_context_t
* ctx
= (fb_context_t
*)dev
;
67 if (interval
< dev
->minSwapInterval
|| interval
> dev
->maxSwapInterval
)
69 // FIXME: implement fb_setSwapInterval
73 static int fb_post(struct framebuffer_device_t
* dev
, buffer_handle_t buffer
)
75 if (private_handle_t::validate(buffer
) < 0)
78 private_handle_t
const* hnd
= reinterpret_cast<private_handle_t
const*>(buffer
);
79 private_module_t
* m
= reinterpret_cast<private_module_t
*>(dev
->common
.module
);
81 hwc_callback_queue_t
*queue
= reinterpret_cast<hwc_callback_queue_t
*>(m
->queue
);
82 pthread_mutex_lock(&m
->queue_lock
);
84 pthread_mutex_unlock(&m
->queue_lock
);
86 private_handle_t
*hnd
= private_handle_t::dynamicCast(buffer
);
87 struct hwc_callback_entry entry
= queue
->top();
89 pthread_mutex_unlock(&m
->queue_lock
);
90 entry
.callback(entry
.data
, hnd
);
96 /*****************************************************************************/
98 static int fb_close(struct hw_device_t
*dev
)
100 fb_context_t
* ctx
= (fb_context_t
*)dev
;
107 static void get_screen_res(const char *fbname
, int32_t *xres
, int32_t *yres
,
114 unsigned int _x
, _y
, _r
;
116 asprintf(&path
, "/sys/class/graphics/%s/modes", fbname
);
119 fd
= open(path
, O_RDONLY
);
122 ret
= read(fd
, buf
, sizeof(buf
));
125 buf
[sizeof(buf
)-1] = '\0';
127 ret
= sscanf(buf
, "U:%ux%up-%u", &_x
, &_y
, &_r
);
131 ALOGI("Using %ux%u %uHz resolution for '%s' from modes list\n",
136 *refresh
= (int32_t)_r
;
153 int init_fb(struct private_module_t
* module
)
155 char const * const device_template
[] = {
156 "/dev/graphics/fb%u",
165 fd
= open("/dev/graphics/fb0", O_RDWR
);
167 ALOGE("/dev/graphics/fb0 Open fail");
171 struct fb_fix_screeninfo finfo
;
172 if (ioctl(fd
, FBIOGET_FSCREENINFO
, &finfo
) == -1) {
173 ALOGE("Fail to get FB Screen Info");
177 struct fb_var_screeninfo info
;
178 if (ioctl(fd
, FBIOGET_VSCREENINFO
, &info
) == -1) {
179 ALOGE("First, Fail to get FB VScreen Info");
184 get_screen_res("fb0", &module
->xres
, &module
->yres
, &refreshRate
);
185 if (refreshRate
== 0)
186 refreshRate
= 60; /* 60 Hz */
188 float xdpi
= (module
->xres
* 25.4f
) / info
.width
;
189 float ydpi
= (module
->yres
* 25.4f
) / info
.height
;
191 ALOGI("using (id=%s)\n"
194 "width = %d mm (%f dpi)\n"
195 "height = %d mm (%f dpi)\n"
196 "refresh rate = %.2f Hz\n",
197 finfo
.id
, module
->xres
, module
->yres
, info
.width
, xdpi
, info
.height
,
198 ydpi
, (float)refreshRate
);
200 module
->line_length
= module
->xres
* 4;
203 module
->fps
= (float)refreshRate
;
208 int fb_device_open(hw_module_t
const* module
, const char* name
,
209 hw_device_t
** device
)
211 int status
= -EINVAL
;
212 #ifdef GRALLOC_16_BITS
213 int bits_per_pixel
= 16;
214 int format
= HAL_PIXEL_FORMAT_RGB_565
;
216 int bits_per_pixel
= 32;
217 int format
= HAL_PIXEL_FORMAT_RGBA_8888
;
220 alloc_device_t
* gralloc_device
;
221 status
= gralloc_open(module
, &gralloc_device
);
223 ALOGE("Fail to Open gralloc device");
227 framebuffer_device_t
*dev
= (framebuffer_device_t
*)malloc(sizeof(framebuffer_device_t
));
229 ALOGE("Failed to allocate memory for dev");
230 gralloc_close(gralloc_device
);
234 private_module_t
* m
= (private_module_t
*)module
;
237 ALOGE("Fail to init framebuffer");
239 gralloc_close(gralloc_device
);
243 /* initialize our state here */
244 memset(dev
, 0, sizeof(*dev
));
246 /* initialize the procs */
247 dev
->common
.tag
= HARDWARE_DEVICE_TAG
;
248 dev
->common
.version
= 0;
249 dev
->common
.module
= const_cast<hw_module_t
*>(module
);
250 dev
->common
.close
= fb_close
;
251 dev
->setSwapInterval
= 0;
253 dev
->setUpdateRect
= 0;
254 dev
->compositionComplete
= 0;
255 m
->queue
= new hwc_callback_queue_t
;
256 pthread_mutex_init(&m
->queue_lock
, NULL
);
258 int stride
= m
->line_length
/ (bits_per_pixel
>> 3);
259 const_cast<uint32_t&>(dev
->flags
) = 0;
260 const_cast<uint32_t&>(dev
->width
) = m
->xres
;
261 const_cast<uint32_t&>(dev
->height
) = m
->yres
;
262 const_cast<int&>(dev
->stride
) = stride
;
263 const_cast<int&>(dev
->format
) = format
;
264 const_cast<float&>(dev
->xdpi
) = m
->xdpi
;
265 const_cast<float&>(dev
->ydpi
) = m
->ydpi
;
266 const_cast<float&>(dev
->fps
) = m
->fps
;
267 const_cast<int&>(dev
->minSwapInterval
) = 1;
268 const_cast<int&>(dev
->maxSwapInterval
) = 1;
269 *device
= &dev
->common
;