Compare commits

..
8 Commits
5 changed files with 293 additions and 153 deletions
+2
View File
@@ -32,3 +32,5 @@ m4/*.m4
/src/sysres/font_list
/src/sysres/license/dat_files/
/configure~
.cache
compile_commands.json
+2 -2
View File
@@ -166,7 +166,7 @@ static unsigned short iso8859_68x_unicode_map [] =
0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, /*0xF1~0xF4*/
0xFECB, 0xFECF, 0xFED3, 0xFED7, /*0xF5~0xF8*/
0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, /*0xF9~0xFC*/
0xFEEB, 0xFEF3, 0xFFFF, /*0xFD~0xFF*/
0xFEEB, 0xFEF4, 0xFFFF, /*0xFD~0xFF*/
0xFEC4, 0xFEC6, 0xFE82, 0xFE84, /*0x100~0x103*/
0xFE86, 0xFE88, 0xFE8C, 0xFE8E, /*0x104~0x107*/
@@ -576,7 +576,7 @@ static BidiType __mg_iso8859_6_bidi_char_type_map[] = {
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_ON,
/*0xf0~0xff*/
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
+9 -110
View File
@@ -286,7 +286,7 @@ static TYPERUN* get_runtype_link (const CHARSETOPS* charset_ops, Achar32* achars
last = list;
for (i = 0; i < len; i++){
if ((type = charset_ops->bidi_char_type (REAL_ACHAR(achars[i]))) != last->type){
if ((type = charset_ops->bidi_char_type (achars[i])) != last->type){
link = calloc(1, sizeof(TYPERUN));
link->type = type;
link->pos = i;
@@ -456,7 +456,7 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, Uint32 base_dir)
prev_type_org = TYPE(pp);
}
compact_list (type_rl_list);
compact_neutrals (type_rl_list);
#ifdef BIDI_DEBUG
print_run_types(type_rl_list);
@@ -469,115 +469,19 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, Uint32 base_dir)
#define BIDI_EMBEDDING_DIR(list) BIDI_LEVEL_TO_DIR(LEVEL(list))
/* 4.Resolving Neutral Types */
static void bidi_resolveNeutrals(const CHARSETOPS* charset_ops, Achar32* achars, int len,
TYPERUN **ptype_rl_list, Uint32 base_bir)
static void bidi_resolveNeutrals(TYPERUN **ptype_rl_list, Uint32 base_bir)
{
TYPERUN *type_rl_list = *ptype_rl_list, *pp = NULL;
Uint32* bracket_types = NULL;
int i;
if (charset_ops->bidi_mirror_char && achars && len > 0) {
typedef struct {
int pos;
Achar32 mirror;
} BRSTACK;
BRSTACK* stack = NULL;
int top = 0;
bracket_types = calloc(len, sizeof(Uint32));
stack = calloc(len, sizeof(BRSTACK));
if (bracket_types && stack) {
for (i = 0; i < len; i++) {
Achar32 ch = REAL_ACHAR(achars[i]);
Achar32 mirrored;
if (!charset_ops->bidi_mirror_char(ch, &mirrored))
continue;
if (ch < mirrored) {
stack[top].pos = i;
stack[top].mirror = mirrored;
top++;
}
else {
if (top > 0 && stack[top - 1].mirror == ch) {
int open_pos = stack[top - 1].pos;
int close_pos = i;
Uint32 found_dir = BIDI_TYPE_ON;
int k;
for (k = open_pos + 1; k < close_pos; k++) {
Uint32 t = charset_ops->bidi_char_type(REAL_ACHAR(achars[k]));
if (t == BIDI_TYPE_AL)
t = BIDI_TYPE_RTL;
if (BIDI_IS_LETTER(t)) {
found_dir = BIDI_IS_RTL(t) ? BIDI_TYPE_RTL : BIDI_TYPE_LTR;
break;
}
}
if (found_dir != BIDI_TYPE_ON) {
bracket_types[open_pos] = found_dir;
bracket_types[close_pos] = found_dir;
}
top--;
}
}
}
}
if (stack)
free(stack);
}
if (bracket_types) {
for (pp = type_rl_list->next; pp->next; pp = pp->next) {
if (BIDI_IS_NEUTRAL(TYPE(pp))) {
int start = POS(pp);
int end = start + LEN(pp);
Uint32 forced = BIDI_TYPE_ON;
if (end > len)
end = len;
for (i = start; i < end; i++) {
if (bracket_types[i] == BIDI_TYPE_RTL) {
forced = BIDI_TYPE_RTL;
break;
}
if (bracket_types[i] == BIDI_TYPE_LTR) {
forced = BIDI_TYPE_LTR;
}
}
if (forced != BIDI_TYPE_ON) {
TYPE(pp) = forced;
}
}
}
compact_list (type_rl_list);
}
DBGLOG ("\n4.Resolving neutral types\n");
for (pp = type_rl_list->next; pp->next; pp = pp->next)
{
Uint32 prev_type, this_type, next_type;
TYPERUN* prev = NULL;
TYPERUN* next = NULL;
prev = pp->prev;
while (prev && BIDI_IS_NEUTRAL(TYPE(prev)) && !BIDI_IS_SENTINEL(TYPE(prev)))
prev = prev->prev;
prev_type = (!prev || BIDI_IS_SENTINEL(TYPE(prev))) ? base_bir : TYPE(prev);
prev_type = TYPE(pp->prev);
this_type = TYPE(pp);
next = pp->next;
while (next && BIDI_IS_NEUTRAL(TYPE(next)) && !BIDI_IS_SENTINEL(TYPE(next)))
next = next->next;
next_type = (!next || BIDI_IS_SENTINEL(TYPE(next))) ? base_bir : TYPE(next);
next_type = (pp->next) ? TYPE(pp->next) : this_type;
/* "European and arabic numbers are treated as though they were R, NUMBER_TO_RTL does this. */
this_type = BIDI_NUMBER_TO_RTL(this_type);
prev_type = BIDI_NUMBER_TO_RTL(prev_type);
@@ -594,9 +498,6 @@ static void bidi_resolveNeutrals(const CHARSETOPS* charset_ops, Achar32* achars,
print_resolved_levels (type_rl_list);
print_resolved_types (type_rl_list);
#endif
if (bracket_types)
free(bracket_types);
}
/* 5.Resolving implicit levels. */
@@ -648,13 +549,10 @@ bidi_resolveMirrorChar (const CHARSETOPS* charset_ops, Achar32* achars, int len,
int i;
for (i = POS (pp); i < POS (pp) + LEN (pp); i++)
{
Achar32 ch = achars[i];
Achar32 real_ch = REAL_ACHAR(ch);
Achar32 mirrored_ch;
if (charset_ops->bidi_mirror_char &&
charset_ops->bidi_mirror_char (real_ch, &mirrored_ch)) {
achars[i] = IS_MBCHV(ch) ? SET_MBCHV(mirrored_ch) : mirrored_ch;
}
charset_ops->bidi_mirror_char (achars[i], &mirrored_ch))
achars[i] = mirrored_ch;
}
}
}
@@ -695,7 +593,7 @@ static void bidi_resolve_string (const CHARSETOPS* charset_ops,
bidi_resolveWeak(&type_rl_list, base_dir);
/* 4.Resolving Neutral Types */
bidi_resolveNeutrals(charset_ops, achars, len, &type_rl_list, base_dir);
bidi_resolveNeutrals(&type_rl_list, base_dir);
/* 5.Resolving implicit levels. */
*pmax_level = bidi_resolveImplicit(&type_rl_list, base_level);
@@ -928,3 +826,4 @@ Uint32 __mg_legacy_bidi_str_base_dir (const CHARSETOPS* charset_ops,
return base_dir;
}
+274 -41
View File
@@ -837,6 +837,9 @@ static DrmSurfaceBuffer *drm_create_dumb_buffer(DrmVideoData* vdata,
static void drm_destroy_dumb_buffer(DrmVideoData* vdata,
DrmSurfaceBuffer *surface_buffer);
static void drm_destroy_flip_buffer(DrmVideoData* vdata,
DrmSurfaceBuffer *flip_buffer);
/*
* The following helpers derived from DRM HOWTO by David Herrmann.
*
@@ -909,6 +912,12 @@ static void drm_cleanup(DrmVideoData* vdata)
}
#endif /* _MGSCHEMA_COMPOSITING */
/* Clean up flip buffer used for page flipping */
if (vdata->flip_buff) {
drm_destroy_flip_buffer(vdata, vdata->flip_buff);
vdata->flip_buff = NULL;
}
if (vdata->scanout_buff_id) {
/* remove frame buffer */
drmModeRmFB(vdata->dev_fd, vdata->scanout_buff_id);
@@ -940,12 +949,22 @@ static void drm_cleanup(DrmVideoData* vdata)
static void DRM_DeleteDevice(GAL_VideoDevice *device)
{
if (device->hidden->real_screen) {
/* FIXME */
DrmSurfaceBuffer *surface_buffer =
(DrmSurfaceBuffer *)device->hidden->real_screen->hwdata;
if (surface_buffer && !device->hidden->driver) {
drm_destroy_dumb_buffer(device->hidden, surface_buffer);
device->hidden->real_screen->hwdata = NULL;
}
GAL_FreeSurface(device->hidden->real_screen);
device->hidden->real_screen = NULL;
}
drm_cleanup(device->hidden);
if (device->hidden->dev_name)
free (device->hidden->dev_name);
@@ -1663,6 +1682,9 @@ static int DRM_VideoInit(_THIS, GAL_PixelFormat *vformat)
}
#endif
/* Initialize page flipping capability */
this->hidden->flip_buff = NULL;
if (this->hidden->driver) {
if (this->hidden->driver_ops->fill_rect) {
this->info.blit_fill = 1;
@@ -2169,6 +2191,50 @@ err_destroy:
return NULL;
}
/* Create flip buffer for page flipping */
static DrmSurfaceBuffer *drm_create_flip_buffer(DrmVideoData *vdata,
uint32_t drm_format, int width, int height)
{
DrmSurfaceBuffer *flip_buffer = NULL;
int ret;
uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};
flip_buffer = drm_create_dumb_buffer(vdata, drm_format, 0, width, height);
if (flip_buffer == NULL) {
_ERR_PRINTF("NEWGAL>DRM: Failed to create flip buffer\n");
goto error_exit;
}
/* Add framebuffer */
if (flip_buffer->fb_id == 0) {
/* Setup handles, pitches and offsets for FB2 */
handles[0] = flip_buffer->handle;
pitches[0] = flip_buffer->pitch;
offsets[0] = flip_buffer->offset;
/* Use drmModeAddFB2 for better format support */
ret = drmModeAddFB2(vdata->dev_fd, flip_buffer->width,
flip_buffer->height, flip_buffer->drm_format,
handles, pitches, offsets, &flip_buffer->fb_id, 0);
if (ret) {
_ERR_PRINTF(
"NEWGAL>DRM: Failed to add framebuffer for flip buffer: %m\n");
goto error_cleanup;
}
}
_DBG_PRINTF("NEWGAL>DRM: Created flip buffer: fb_id(%u)\n",
flip_buffer->fb_id);
return flip_buffer;
error_cleanup:
drm_destroy_dumb_buffer(vdata, flip_buffer);
error_exit:
return NULL;
}
static DrmSurfaceBuffer *drm_create_dumb_buffer_from_handle(DrmVideoData* vdata,
uint32_t handle, size_t size)
{
@@ -2362,6 +2428,17 @@ static void drm_destroy_dumb_buffer(DrmVideoData* vdata,
free (surface_buffer);
}
/* Destroy flip buffer used for page flipping */
static void drm_destroy_flip_buffer(DrmVideoData* vdata,
DrmSurfaceBuffer *flip_buffer)
{
if (flip_buffer == NULL) {
return;
}
drm_destroy_dumb_buffer(vdata, flip_buffer);
}
static DrmModeInfo* find_mode(DrmVideoData* vdata, int width, int height)
{
DrmModeInfo *iter;
@@ -2393,18 +2470,71 @@ static double get_elapsed_seconds(const struct timespec *ts_from,
}
#endif
#if defined(__arm__) && defined(__linux__)
// ARM64 NEON accelerated memcpy implementation
static void *neon_memcpy(void *dst, const void *src, size_t n)
{
// Backup original pointer for return
void *ret = dst;
// Handle unaligned portion
uintptr_t dst_addr = (uintptr_t)dst;
size_t pre_align = (16 - (dst_addr & 15)) & 15;
if (pre_align > 0) {
if (pre_align > n) {
pre_align = n;
}
memcpy(dst, src, pre_align);
dst = (char *)dst + pre_align;
src = (char *)src + pre_align;
n -= pre_align;
}
// NEON vector copy main loop, copy 128 bytes each time
if (n >= 128) {
size_t count = n >> 7;
asm volatile("1:\n"
// Load 128 bytes into v0-v7 registers
"ld1 {v0.2d, v1.2d, v2.2d, v3.2d}, [%1], #64\n"
"ld1 {v4.2d, v5.2d, v6.2d, v7.2d}, [%1], #64\n"
// Store 128 bytes
"st1 {v0.2d, v1.2d, v2.2d, v3.2d}, [%0], #64\n"
"st1 {v4.2d, v5.2d, v6.2d, v7.2d}, [%0], #64\n"
"subs %2, %2, #1\n"
"b.ne 1b\n"
: "+r"(dst), "+r"(src), "+r"(count)
:
: "memory", "v0", "v1", "v2", "v3", "v4", "v5", "v6",
"v7");
n &= 127;
}
// Handle remaining bytes
if (n > 0) {
memcpy(dst, src, n);
}
return ret;
}
#endif /* defined(__arm__) && defined(__linux__) */
static void update_real_screen_memcpy(_THIS, const GAL_Rect *dirty_rect)
{
DrmSurfaceBuffer *real_buff, *shadow_buff;
real_buff = (DrmSurfaceBuffer *)this->hidden->real_screen->hwdata;
shadow_buff = (DrmSurfaceBuffer *)this->hidden->shadow_screen->hwdata;
DrmSurfaceBuffer *target_buff, *shadow_buff;
DrmVideoData *vdata = this->hidden;
shadow_buff = (DrmSurfaceBuffer *)vdata->shadow_screen->hwdata;
if (!vdata->flip_buff || (vdata->curr_buff == vdata->flip_buff)) {
target_buff = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;
}
else {
target_buff = (DrmSurfaceBuffer *)vdata->flip_buff;
}
uint32_t i;
uint8_t *src, *dst;
int cpp = real_buff->cpp;
int shadow_pitch = this->hidden->shadow_screen->pitch;
int real_pitch = real_buff->pitch;
size_t count = cpp * dirty_rect->w;
int shadow_pitch = vdata->shadow_screen->pitch;
int target_pitch = target_buff->pitch;
if (shadow_buff) {
src = shadow_buff->vaddr;
@@ -2415,16 +2545,18 @@ static void update_real_screen_memcpy(_THIS, const GAL_Rect *dirty_rect)
src += this->hidden->shadow_screen->pixels_off;
}
src += shadow_pitch * dirty_rect->y + cpp * dirty_rect->x;
dst = target_buff->vaddr;
dst += target_buff->offset;
dst = real_buff->vaddr;
dst += real_pitch * dirty_rect->y + cpp * dirty_rect->x;
dst += real_buff->offset;
for (i = 0; i < dirty_rect->h; i++) {
memcpy(dst, src, count);
for (uint32_t i = 0; i < target_buff->height; i++) {
#if defined(__arm__) && defined(__linux__)
neon_memcpy(dst, src, target_pitch);
#else
memcpy(dst, src, target_pitch);
#endif /* defined(__arm__) && defined(__linux__) */
src += shadow_pitch;
dst += real_pitch;
dst += target_pitch;
}
}
@@ -2518,18 +2650,99 @@ static inline void refresh_cursor(_THIS, const GAL_Rect *dirty_rect) {
}
#endif /* _MGSCHEMA_COMPOSITING */
static int is_fd_readable(int fd)
{
fd_set rfds;
struct timeval tv;
int retval;
/* Initialize the file descriptor set */
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
/* Set timeout to 0 to return immediately */
tv.tv_sec = 0;
tv.tv_usec = 0;
/* Call select to check if fd is readable */
retval = select(fd + 1, &rfds, NULL, NULL, &tv);
if (retval == -1) {
/* Error occurred */
return -1;
} else if (retval) {
/* File descriptor is readable */
return 1;
} else {
/* Timeout occurred, file descriptor is not readable */
return 0;
}
}
/* Perform page flip between flip_buffer and real_screen->hwdata using curr_buff */
static int drm_page_flip(DrmVideoData* vdata)
{
int ret;
/* Perform the page flip */
if (!vdata->flip_buff || !vdata->flip_buff->fb_id) {
_ERR_PRINTF("NEWGAL>DRM: No valid flip buffer for page flipping\n");
return -1;
}
/* Get the next buffer to display */
DrmSurfaceBuffer *next_buffer;
if (vdata->curr_buff == vdata->flip_buff) {
next_buffer = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;
} else {
next_buffer = vdata->flip_buff;
}
uint32_t next_fb_id = next_buffer->fb_id;
/* drmModePageFlip will wait for vertical sync signal internally */
ret = drmModePageFlip(vdata->dev_fd, vdata->saved_crtc->crtc_id,
next_fb_id, DRM_MODE_PAGE_FLIP_EVENT, NULL);
if (ret) {
_ERR_PRINTF("NEWGAL>DRM: Failed to perform page flip: %m\n");
return -1;
}
/* Update scanout buffer ID */
vdata->scanout_buff_id = next_fb_id;
/* Update current buffer pointer */
vdata->curr_buff = next_buffer;
return 0;
}
static void update_real_screen_helper(_THIS, const GAL_Rect *dirty_rect)
{
DrmVideoData* vdata = this->hidden;
DrmSurfaceBuffer *real_buff, *shadow_buff;
DrmSurfaceBuffer *target_buff, *shadow_buff;
/* Initialize curr_buff if not set */
if (!vdata->curr_buff) {
vdata->curr_buff = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;
}
/* Use the buffer that is not currently displayed as the target buffer */
if (vdata->flip_buff) {
target_buff = (vdata->curr_buff == vdata->flip_buff)
? (DrmSurfaceBuffer *)vdata->real_screen->hwdata
: vdata->flip_buff;
}
else {
target_buff = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;
}
real_buff = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;
shadow_buff = (DrmSurfaceBuffer *)vdata->shadow_screen->hwdata;
#if 0 // def _DEBUG
_DBG_PRINTF("Copy pixels to real screen (pitch: %u, count: %u, %d x %d)\n",
(unsigned)real_buff->pitch, (unsigned)count,
RECTWP(update_rect), RECTHP(update_rect));
_DBG_PRINTF("Copy pixels to target buffer (pitch: %u, %d x %d)\n",
(unsigned)target_buff->pitch,
dirty_rect->w, dirty_rect->h);
struct timespec ts_start;
clock_gettime(CLOCK_REALTIME, &ts_start);
@@ -2539,7 +2752,7 @@ static void update_real_screen_helper(_THIS, const GAL_Rect *dirty_rect)
if (shadow_buff && vdata->driver && vdata->driver_ops->copy_buff) {
if ((dirty_rect->w * dirty_rect->h) >= vdata->min_pixels_using_hwaccl) {
if (vdata->driver_ops->copy_buff(vdata->driver, shadow_buff,
dirty_rect, real_buff, dirty_rect,
dirty_rect, target_buff, dirty_rect,
BLIT_COPY_TRANSLATE) == 0) {
hw_ok = TRUE;
}
@@ -2569,6 +2782,8 @@ static void* task_do_update(void *data)
{
_THIS = data;
DrmVideoData* vdata = this->hidden;
drmEventContext ev = {};
ev.version = DRM_EVENT_CONTEXT_VERSION;
if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) {
goto error;
@@ -2627,20 +2842,18 @@ static void* task_do_update(void *data)
RECTH(vdata->update_rect) };
update_real_screen_helper(this, &dirty_rect);
/* Flush driver buffer if needed */
if (vdata->driver && vdata->driver_ops->flush) {
DrmSurfaceBuffer *real_buff;
real_buff = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;
vdata->driver_ops->flush(vdata->driver,
real_buff, &dirty_rect);
vdata->curr_buff, &dirty_rect);
}
else if (vdata->dirty_fb_ok) {
drmModeClip clip = {
vdata->update_rect.left,
vdata->update_rect.top,
vdata->update_rect.right,
vdata->update_rect.bottom };
drmModeDirtyFB(vdata->dev_fd,
vdata->scanout_buff_id, &clip, 1);
/* Perform page flip */
else if (vdata->flip_buff) {
drm_page_flip(vdata);
if (1 == is_fd_readable(vdata->dev_fd)) {
drmHandleEvent(vdata->dev_fd, &ev);
}
}
SetRectEmpty(&vdata->update_rect);
@@ -2788,6 +3001,20 @@ static GAL_Surface *DRM_SetVideoMode(_THIS, GAL_Surface *current,
_ERR_PRINTF("NEWGAL>DRM: cannot setup scanout buffer\n");
goto error;
}
real_buffer->fb_id = vdata->scanout_buff_id;
/* Create flip buffer for page flipping */
if (!vdata->driver) {
vdata->flip_buff =
drm_create_flip_buffer(vdata, drm_format, info->width, info->height);
if (vdata->flip_buff == NULL) {
_ERR_PRINTF("NEWGAL>DRM: failed to create flip buffer\n");
goto error;
}
}
/* Initialize curr_buff to point to real_screen buffer */
vdata->curr_buff = real_buffer;
if (vdata->crtc_idx >= 0)
this->WaitVBlank = DRM_WaitVBlank;
@@ -2924,6 +3151,12 @@ error:
}
}
/* Clean up flip buffer if created */
if (vdata->flip_buff) {
drm_destroy_flip_buffer(vdata, vdata->flip_buff);
vdata->flip_buff = NULL;
}
if (vdata->real_screen) {
GAL_FreeSurface (vdata->real_screen);
vdata->real_screen = NULL;
@@ -3834,16 +4067,16 @@ static BOOL DRM_SyncUpdate(_THIS)
refresh_cursor(this, &dirty_rect);
if (vdata->driver && vdata->driver_ops->flush) {
DrmSurfaceBuffer *real_buff;
real_buff = (DrmSurfaceBuffer *)vdata->real_screen->hwdata;
vdata->driver_ops->flush(vdata->driver,
real_buff, &dirty_rect);
vdata->driver_ops->flush(vdata->driver, vdata->curr_buff, &dirty_rect);
}
else if (vdata->dirty_fb_ok) {
drmModeClip clip = { clipped.left, clipped.top,
clipped.right, clipped.bottom };
drmModeDirtyFB(vdata->dev_fd,
vdata->scanout_buff_id, &clip, 1);
else if (vdata->dirty_fb_ok && vdata->flip_buff) {
/* Perform page flip */
drm_page_flip(vdata);
if (1 == is_fd_readable(vdata->dev_fd)) {
drmEventContext ev = {};
ev.version = DRM_EVENT_CONTEXT_VERSION;
drmHandleEvent(vdata->dev_fd, &ev);
}
}
ret:
+6
View File
@@ -89,6 +89,12 @@ typedef struct GAL_PrivateVideoData {
uint32_t real_name, shadow_name;
#endif /* not defined _MGSCHEMA_COMPOSITING */
/* flip buffer used for page flipping */
DrmSurfaceBuffer *flip_buff;
/* current buffer pointer for managing buffer switching */
DrmSurfaceBuffer *curr_buff;
sem_t *update_lock;
#if !IS_SHAREDFB_SCHEMA_PROCS