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"
45 /*****************************************************************************/
47 // numbers of buffers for page flipping
50 struct hwc_callback_entry
52 void (*callback
)(void *, private_handle_t
*);
56 typedef android::Vector
<struct hwc_callback_entry
> hwc_callback_queue_t
;
59 framebuffer_device_t device
;
62 /*****************************************************************************/
64 static int fb_setSwapInterval(struct framebuffer_device_t
* dev
,
67 fb_context_t
* ctx
= (fb_context_t
*)dev
;
68 if (interval
< dev
->minSwapInterval
|| interval
> dev
->maxSwapInterval
)
70 // FIXME: implement fb_setSwapInterval
74 static int fb_post(struct framebuffer_device_t
* dev
, buffer_handle_t buffer
)
76 if (private_handle_t::validate(buffer
) < 0)
79 private_handle_t
const* hnd
= reinterpret_cast<private_handle_t
const*>(buffer
);
80 private_module_t
* m
= reinterpret_cast<private_module_t
*>(dev
->common
.module
);
82 hwc_callback_queue_t
*queue
= reinterpret_cast<hwc_callback_queue_t
*>(m
->queue
);
83 pthread_mutex_lock(&m
->queue_lock
);
85 pthread_mutex_unlock(&m
->queue_lock
);
87 private_handle_t
*hnd
= private_handle_t::dynamicCast(buffer
);
88 struct hwc_callback_entry entry
= queue
->top();
90 pthread_mutex_unlock(&m
->queue_lock
);
91 entry
.callback(entry
.data
, hnd
);
97 /*****************************************************************************/
99 static int fb_close(struct hw_device_t
*dev
)
101 fb_context_t
* ctx
= (fb_context_t
*)dev
;
108 static void get_screen_res(const char *fbname
, int32_t *xres
, int32_t *yres
,
115 unsigned int _x
, _y
, _r
;
117 asprintf(&path
, "/sys/class/graphics/%s/modes", fbname
);
120 fd
= open(path
, O_RDONLY
);
123 ret
= read(fd
, buf
, sizeof(buf
));
126 buf
[sizeof(buf
)-1] = '\0';
128 ret
= sscanf(buf
, "U:%ux%up-%u", &_x
, &_y
, &_r
);
132 ALOGI("Using %ux%u %uHz resolution for '%s' from modes list\n",
137 *refresh
= (int32_t)_r
;
154 int init_fb(struct private_module_t
* module
)
156 char const * const device_template
[] = {
157 "/dev/graphics/fb%u",
166 fd
= open("/dev/graphics/fb0", O_RDWR
);
168 ALOGE("/dev/graphics/fb0 Open fail");
172 struct fb_fix_screeninfo finfo
;
173 if (ioctl(fd
, FBIOGET_FSCREENINFO
, &finfo
) == -1) {
174 ALOGE("Fail to get FB Screen Info");
178 struct fb_var_screeninfo info
;
179 if (ioctl(fd
, FBIOGET_VSCREENINFO
, &info
) == -1) {
180 ALOGE("First, Fail to get FB VScreen Info");
185 get_screen_res("fb0", &module
->xres
, &module
->yres
, &refreshRate
);
186 if (refreshRate
== 0)
187 refreshRate
= 60; /* 60 Hz */
189 float xdpi
= (module
->xres
* 25.4f
) / info
.width
;
190 float ydpi
= (module
->yres
* 25.4f
) / info
.height
;
192 ALOGI("using (id=%s)\n"
195 "width = %d mm (%f dpi)\n"
196 "height = %d mm (%f dpi)\n"
197 "refresh rate = %.2f Hz\n",
198 finfo
.id
, module
->xres
, module
->yres
, info
.width
, xdpi
, info
.height
,
199 ydpi
, (float)refreshRate
);
201 module
->line_length
= module
->xres
* 4;
204 module
->fps
= (float)refreshRate
;
209 int fb_device_open(hw_module_t
const* module
, const char* name
,
210 hw_device_t
** device
)
212 int status
= -EINVAL
;
213 #ifdef GRALLOC_16_BITS
214 int bits_per_pixel
= 16;
215 int format
= HAL_PIXEL_FORMAT_RGB_565
;
217 int bits_per_pixel
= 32;
218 int format
= HAL_PIXEL_FORMAT_RGBA_8888
;
221 alloc_device_t
* gralloc_device
;
222 status
= gralloc_open(module
, &gralloc_device
);
224 ALOGE("Fail to Open gralloc device");
228 framebuffer_device_t
*dev
= (framebuffer_device_t
*)malloc(sizeof(framebuffer_device_t
));
230 ALOGE("Failed to allocate memory for dev");
231 gralloc_close(gralloc_device
);
235 private_module_t
* m
= (private_module_t
*)module
;
238 ALOGE("Fail to init framebuffer");
240 gralloc_close(gralloc_device
);
244 /* initialize our state here */
245 memset(dev
, 0, sizeof(*dev
));
247 /* initialize the procs */
248 dev
->common
.tag
= HARDWARE_DEVICE_TAG
;
249 dev
->common
.version
= 0;
250 dev
->common
.module
= const_cast<hw_module_t
*>(module
);
251 dev
->common
.close
= fb_close
;
252 dev
->setSwapInterval
= 0;
254 dev
->setUpdateRect
= 0;
255 dev
->compositionComplete
= 0;
256 m
->queue
= new hwc_callback_queue_t
;
257 pthread_mutex_init(&m
->queue_lock
, NULL
);
259 int stride
= m
->line_length
/ (bits_per_pixel
>> 3);
260 const_cast<uint32_t&>(dev
->flags
) = 0;
261 const_cast<uint32_t&>(dev
->width
) = m
->xres
;
262 const_cast<uint32_t&>(dev
->height
) = m
->yres
;
263 const_cast<int&>(dev
->stride
) = stride
;
264 const_cast<int&>(dev
->format
) = format
;
265 const_cast<float&>(dev
->xdpi
) = m
->xdpi
;
266 const_cast<float&>(dev
->ydpi
) = m
->ydpi
;
267 const_cast<float&>(dev
->fps
) = m
->fps
;
268 const_cast<int&>(dev
->minSwapInterval
) = 1;
269 const_cast<int&>(dev
->maxSwapInterval
) = 1;
270 *device
= &dev
->common
;