12c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland/* 22c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * Copyright (C) 2013 The Android Open Source Project 32c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * 42c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * Licensed under the Apache License, Version 2.0 (the "License"); 52c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * you may not use this file except in compliance with the License. 62c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * You may obtain a copy of the License at 72c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * 82c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * http://www.apache.org/licenses/LICENSE-2.0 92c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * 102c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * Unless required by applicable law or agreed to in writing, software 112c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * distributed under the License is distributed on an "AS IS" BASIS, 122c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * See the License for the specific language governing permissions and 142c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland * limitations under the License. 152c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland */ 162c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 172c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <stdio.h> 182c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <stdlib.h> 192c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <stdarg.h> 202c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <string.h> 212c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <errno.h> 222c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 232c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <pthread.h> 242c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 252c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <hardware/hardware.h> 262c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <hardware/gralloc.h> 272c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <hardware/hwcomposer.h> 282c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 292c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <system/window.h> 302c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#include <cutils/native_handle.h> 312c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 322c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland// normalize and shorten type names 332c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandtypedef struct android_native_base_t aBase; 342c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandtypedef struct ANativeWindowBuffer aBuffer; 352c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandtypedef struct ANativeWindow aWindow; 362c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 372c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int trace_level = 1; 382c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 392c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#define _TRACE(n,fmt...) \ 402c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland do { if (trace_level >= n) fprintf(stderr, "CNW: " fmt); } while (0) 412c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 422c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#define ERROR(fmt...) _TRACE(0, fmt) 432c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#define INFO(fmt...) _TRACE(1, fmt) 442c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#define LOG(fmt...) _TRACE(2, fmt) 452c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#define TRACE(fmt...) _TRACE(3, fmt) 462c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 472c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland#define QCT_WORKAROUND 1 482c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 492c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandtypedef struct CNativeBuffer { 502c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland aBuffer base; 512c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland struct CNativeBuffer *next; 522c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland struct CNativeBuffer *prev; 532c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int ffd; 542c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} CNativeBuffer; 552c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 562c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandtypedef struct CNativeWindow { 572c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland aWindow base; 582c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 592c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_composer_device_1_t *hwc; 602c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland framebuffer_device_t *fb; 612c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland alloc_device_t *gr; 622c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 632c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_mutex_t lock; 642c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_cond_t cvar; 652c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 662c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland aBuffer *front; 672c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland aBuffer *spare; 682c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 692c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeBuffer free_buffer_queue; 702c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 712c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland unsigned width; 722c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland unsigned height; 732c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland unsigned xdpi; 742c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland unsigned ydpi; 752c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland unsigned format; 762c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 77fc0ff2a8700eb11aef7a961b279d846c8a1c04c5Jesse Hall hwc_display_contents_1_t *dclist[HWC_NUM_PHYSICAL_DISPLAY_TYPES]; 782c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 792c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_display_contents_1_t dc; 802c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_layer_1_t layer[4]; 812c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} CNativeWindow; 822c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 832c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic inline CNativeBuffer *from_abuffer(aBuffer *buf) { 842c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return (CNativeBuffer*) buf; 852c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 862c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 872c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic CNativeBuffer *get_front(struct CNativeBuffer *queue) { 882c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeBuffer *buf = queue->next; 892c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (buf == queue) 902c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 912c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->next->prev = queue; 922c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland queue->next = buf->next; 932c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->next = buf->prev = 0; 942c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return buf; 952c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 962c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 972c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void put_front(struct CNativeBuffer *queue, aBuffer *_buf) { 982c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland struct CNativeBuffer *buf = (struct CNativeBuffer *) _buf; 992c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->prev = queue; 1002c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->next = queue->next; 1012c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland queue->next->prev = buf; 1022c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland queue->next = buf; 1032c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 1042c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1052c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void put_back(struct CNativeBuffer *queue, aBuffer *_buf) { 1062c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland struct CNativeBuffer *buf = (struct CNativeBuffer *) _buf; 1072c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->next = queue; 1082c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->prev = queue->prev; 1092c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland queue->prev->next = buf; 1102c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland queue->prev = buf; 1112c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 1122c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1132c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void cnw_inc_ref(aBase *base) { TRACE("buf %p ref++\n",base); } 1142c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void cnw_dec_ref(aBase *base) { TRACE("buf %p ref--\n",base); } 1152c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1162c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic inline CNativeWindow *from_base(aWindow *base) { 1172c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return (CNativeWindow *) base; 1182c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 1192c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1202c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic inline CNativeWindow *from_base_const(const aWindow *base) { 1212c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return (CNativeWindow *) base; 1222c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 1232c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1242c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_set_swap_interval(aWindow *base, int interval) { 1252c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeWindow *win = from_base(base); 1262c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (win->fb && win->fb->setSwapInterval) 1272c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return win->fb->setSwapInterval(win->fb, interval); 1282c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 1292c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 1302c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1312c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_dequeue_buffer1(aWindow *base, aBuffer **buf, int *ffd) { 1322c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeWindow *win = from_base(base); 1332c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeBuffer *cnb; 1342c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1352c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_mutex_lock(&win->lock); 1362c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1372c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland while ((cnb = get_front(&win->free_buffer_queue)) == 0) { 1382c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_cond_wait(&win->cvar, &win->lock); 1392c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 1402c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1412c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *ffd = cnb->ffd; 1422c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *buf = &cnb->base; 1432c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland cnb->ffd = -1; 1442c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland LOG("<< dequeue buffer %p %d\n", *buf, *ffd); 1452c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1462c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_mutex_unlock(&win->lock); 1472c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 1482c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 1492c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1502c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_lock_buffer0(aWindow *base, aBuffer *buffer) { 1512c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 1522c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 1532c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1542c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void set_layer(hwc_layer_1_t *dl, aBuffer *buf, int ffd) { 1552c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int right = buf->width; 1562c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int bottom = buf->height; 1572c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1582c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->compositionType = HWC_FRAMEBUFFER; 1592c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->hints = 0; 1602c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->flags = 0; 1612c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1622c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->handle = buf->handle; 1632c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->transform = 0; 1642c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->blending = HWC_BLENDING_NONE; 1652c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->sourceCrop.left = 0; 1662c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->sourceCrop.top = 0; 1672c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->sourceCrop.right = right; 1682c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->sourceCrop.bottom = bottom; 1692c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->displayFrame.left = 0; 1702c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->displayFrame.top = 0; 1712c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->displayFrame.right = right; 1722c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->displayFrame.bottom = bottom; 1732c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->visibleRegionScreen.numRects = 1; 1742c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->visibleRegionScreen.rects = &dl->displayFrame; 1752c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1762c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->acquireFenceFd = ffd; 1772c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl->releaseFenceFd = -1; 1782c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 1792c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1802c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void hwc_post(CNativeWindow *win, aBuffer *buf, int ffd) { 1812c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_composer_device_1_t *hwc = win->hwc; 1822c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_display_contents_1_t *dc = &(win->dc); 1832c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_layer_1_t *dl = win->dc.hwLayers; 1842c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int r, i; 1852c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1862c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dc->retireFenceFd = -1; 1872c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dc->outbufAcquireFenceFd = -1; 1882c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dc->flags = HWC_GEOMETRY_CHANGED; 1892c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dc->numHwLayers = 1; 1902c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1912c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland // some hwcomposers fail if these are NULL 1922c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dc->dpy = (void*) 0xdeadbeef; 1932c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dc->sur = (void*) 0xdeadbeef; 1942c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1952c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland set_layer(&dl[0], buf, ffd); 1962c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 1972c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (QCT_WORKAROUND) { 1982c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland set_layer(&dl[1], win->spare, -1); 1992c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dl[1].compositionType = HWC_FRAMEBUFFER_TARGET; 2002c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland dc->numHwLayers++; 2012c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 2022c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 203fc0ff2a8700eb11aef7a961b279d846c8a1c04c5Jesse Hall r = hwc->prepare(hwc, HWC_NUM_PHYSICAL_DISPLAY_TYPES, win->dclist); 2042c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (r) { 2052c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("hwc->prepare failed r=%d\n",r); 2062c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return; 2072c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 2082c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2092c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland// for (i = 0; i < dc->numHwLayers; i++) 2102c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland// LOG("dl[%d] ctype=0x%08x hints=0x%08x flags=0x%08x\n", i, 2112c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland// dl[i].compositionType, dl[0].hints, dl[0].flags); 2122c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 213fc0ff2a8700eb11aef7a961b279d846c8a1c04c5Jesse Hall r = hwc->set(hwc, HWC_NUM_PHYSICAL_DISPLAY_TYPES, win->dclist); 2142c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (r) { 2152c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("hwc->set failed, r=%d\n", r); 2162c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return; 2172c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 2182c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2192c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (dc->retireFenceFd != -1) 2202c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland close(dc->retireFenceFd); 2212c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (dl->releaseFenceFd != -1) { 2222c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeBuffer *cnb = from_abuffer(buf); 2232c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland cnb->ffd = dl->releaseFenceFd; 2242c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 2252c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (QCT_WORKAROUND) 2262c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (dl[1].releaseFenceFd != -1) 2272c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland close(dl[1].releaseFenceFd); 2282c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 2292c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2302c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_queue_buffer1(aWindow *base, aBuffer *buffer, int ffd) { 2312c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeWindow *win = from_base(base); 2322c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int res; 2332c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland LOG(">> queue buffer %p %d\n", buffer, ffd); 2342c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (win->fb) { 2352c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland res = win->fb->post(win->fb, buffer->handle); 2362c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (ffd != -1) 2372c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland close(ffd); 2382c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } else { 2392c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_post(win, buffer, ffd); 2402c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland res = 0; 2412c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 2422c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_mutex_lock(&win->lock); 2432c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (win->front) 2442c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland put_back(&win->free_buffer_queue, win->front); 2452c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->front = buffer; 2462c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_cond_signal(&win->cvar); 2472c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_mutex_unlock(&win->lock); 2482c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2492c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return res; 2502c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 2512c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2522c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_cancel_buffer1(aWindow *base, aBuffer *buf, int ffd) { 2532c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeWindow *win = from_base(base); 2542c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeBuffer *cnb = from_abuffer(buf); 2552c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland LOG("<< cancel buffer %p %d\n", buf, ffd); 2562c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland cnb->ffd = ffd; 2572c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_mutex_lock(&win->lock); 2582c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland put_front(&win->free_buffer_queue, buf); 2592c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_mutex_unlock(&win->lock); 2602c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 2612c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 2622c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2632c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_dequeue_buffer0(aWindow *base, aBuffer **buf) { 2642c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int ffd = -1; 2652c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int r; 2662c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland r = cnw_dequeue_buffer1(base, buf, &ffd); 2672c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (ffd != -1) 2682c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland close(ffd); 2692c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return r; 2702c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 2712c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2722c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_queue_buffer0(aWindow *base, aBuffer *buf) { 2732c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return cnw_queue_buffer1(base, buf, -1); 2742c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 2752c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2762c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_cancel_buffer0(aWindow *base, aBuffer *buf) { 2772c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return cnw_cancel_buffer1(base, buf, -1); 2782c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 2792c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2802c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_query(const aWindow *base, int what, int *value) { 2812c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeWindow *win = from_base_const(base); 2822c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 2832c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland switch (what) { 2842c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_WIDTH: 2852c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_DEFAULT_WIDTH: 2862c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *value = win->width; 2872c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("query window width: %d\n", *value); 2882c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 2892c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_HEIGHT: 2902c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_DEFAULT_HEIGHT: 2912c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *value = win->height; 2922c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("query window height: %d\n", *value); 2932c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 2942c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_FORMAT: 2952c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *value = win->format; 2962c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("query window format: %d\n", *value); 2972c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 2982c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_TRANSFORM_HINT: 2992c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("query transform hint: 0\n"); 3002c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *value = 0; 3012c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3022c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 3032c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("query min undequeued buffers: 1\n"); 3042c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *value = 1; 3052c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3062c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland default: 3072c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *value = 0; 3082c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("query %d unknown!\n", what); 3092c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -EINVAL; 3102c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 3112c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 3122c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3132c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_perform(aWindow *base, int op, ...) { 3142c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeWindow *win = from_base(base); 3152c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland va_list ap; 3162c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland va_start(ap, op); 3172c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3182c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland switch (op) { 3192c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_SET_USAGE: 3202c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("set usage %d\n", va_arg(ap,int)); 3212c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3222c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_CONNECT: 3232c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_DISCONNECT: 3242c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_API_CONNECT: 3252c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_API_DISCONNECT: 3262c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3272c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_SET_BUFFERS_FORMAT: 3282c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("set buffers format %d\n", va_arg(ap,int)); 3292c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3302c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: 3312c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("set buffers transform %d\n", va_arg(ap,int)); 3322c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3332c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: 3342c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("set buffers timestamp %lld\n", va_arg(ap,long long)); 3352c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3362c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_SET_SCALING_MODE: 3372c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("set scaling mode %d\n", va_arg(ap,int)); 3382c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3392c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: { 3402c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int w = va_arg(ap,int); 3412c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int h = va_arg(ap,int); 3422c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if ((w == win->width) && (h == win->height)) { 3432c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland TRACE("set buffers dimensions %d x %d\n", w, h); 3442c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 3452c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 3462c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("cannot resize buffers to %d x %d\n", w, h); 3472c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -1; 3482c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 3492c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland default: 3502c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("perform %d unknown!\n", op); 3512c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 3522c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 3532c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 3542c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3552c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void hwc_invalidate(const struct hwc_procs *procs) {} 3562c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void hwc_vsync(const struct hwc_procs *procs, int disp, int64_t ts) {} 3572c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic void hwc_hotplug(const struct hwc_procs *procs, int disp, int conn) {} 3582c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3592c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstruct hwc_procs hprocs = { 3602c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland .invalidate = hwc_invalidate, 3612c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland .vsync = hwc_vsync, 3622c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland .hotplug = hwc_hotplug, 3632c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland}; 3642c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3652c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlanduint32_t attrs[] = { 3662c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland HWC_DISPLAY_WIDTH, 3672c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland HWC_DISPLAY_HEIGHT, 3682c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland HWC_DISPLAY_VSYNC_PERIOD, 3692c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland HWC_DISPLAY_DPI_X, 3702c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland HWC_DISPLAY_DPI_Y, 3712c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland HWC_DISPLAY_NO_ATTRIBUTE, 3722c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland}; 3732c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3742c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int hwc_init(CNativeWindow *win) { 3752c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hw_module_t const* module; 3762c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_composer_device_1_t *hwc; 3772c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland unsigned i; 3782c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int r; 3792c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland uint32_t configs[32]; 3802c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland uint32_t numconfigs = 32; 3812c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int32_t values[8]; 3822c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3832c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) { 3842c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("cannot open hw composer module\n"); 3852c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 3862c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 3872c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3882c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (hwc_open_1(module, &hwc)) { 3892c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("cannot open hwc device\n"); 3902c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 3912c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 3922c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->hwc = hwc; 3932c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3942c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland LOG("hwc version 0x%08x\n", hwc->common.version); 3952c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 3962c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if ((hwc->common.version & 0xFFFF0000) < 0x01010000) { 3972c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("hwc version less than 1.1\n"); 3982c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_close_1(hwc); 3992c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 4002c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 4012c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4022c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc->registerProcs(hwc, &hprocs); 4032c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4042c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (hwc->getDisplayConfigs(hwc, 0, configs, &numconfigs)) { 4052c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("cannot get configs\n"); 4062c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 4072c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 4082c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland for (i = 0; i < numconfigs; i++) 4092c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland LOG("cfg[%d] = 0x%08x\n", i, configs[i]); 4102c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4112c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if ((r = hwc->getDisplayAttributes(hwc, 0, configs[0], attrs, values))) { 4122c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("cannot get attributes %d\n", r); 4132c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 4142c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 4152c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4162c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->width = values[0]; 4172c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->height = values[1]; 4182c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->xdpi = values[3]; 4192c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->ydpi = values[4]; 4202c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->format = HAL_PIXEL_FORMAT_RGBA_8888; 4212c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4222c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc->blank(hwc, 0, 0); 4232c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4242c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->dclist[0] = &(win->dc); 4252c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 4262c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 4272c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4282c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic aBuffer *cnw_alloc(CNativeWindow *win, unsigned format, unsigned usage) { 4292c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeBuffer *cnb; 4302c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland aBuffer *buf; 4312c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int err; 4322c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4332c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (!(cnb = malloc(sizeof(CNativeBuffer)))) 4342c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 4352c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4362c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf = &cnb->base; 4372c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland cnb->ffd = -1; 4382c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4392c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->common.magic = ANDROID_NATIVE_BUFFER_MAGIC; 4402c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->common.version = sizeof(aBuffer); 4412c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->common.incRef = cnw_inc_ref; 4422c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->common.decRef = cnw_dec_ref; 4432c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4442c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->width = win->width; 4452c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->height = win->height; 4462c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->format = format; 4472c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland buf->usage = usage; 4482c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4492c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland err = win->gr->alloc(win->gr, win->width, win->height, 4502c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland format, usage, &buf->handle, &buf->stride); 4512c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (err) { 4522c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("gralloc of %d x %d failed: err=%d\n", 4532c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->width, win->height, err); 4542c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland free(buf); 4552c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 4562c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 4572c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland INFO("alloc buffer %p %d x %d\n", buf, win->width, win->height); 4582c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return buf; 4592c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 4602c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4612c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandstatic int cnw_init(CNativeWindow *win) { 4622c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hw_module_t const* module; 4632c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland framebuffer_device_t *fb = NULL; 4642c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland alloc_device_t *gr; 4652c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland int err, i, n; 4662c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland unsigned usage, format; 4672c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4682c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland memset(win, 0, sizeof(CNativeWindow)); 4692c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4702c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->free_buffer_queue.next = &(win->free_buffer_queue); 4712c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->free_buffer_queue.prev = &(win->free_buffer_queue); 4722c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4732c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) != 0) { 4742c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("cannot open gralloc module\n"); 4752c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 4762c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 4772c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4782c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (hwc_init(win)) { 4792c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("cannot open hwcomposer, trying legacy fb HAL\n"); 4802c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland err = framebuffer_open(module, &fb); 4812c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (err) { 4822c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("cannot open fb HAL (%s)", strerror(-err)); 4832c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 4842c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 4852c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->width = fb->width; 4862c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->height = fb->height; 4872c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->format = fb->format; 4882c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->xdpi = fb->xdpi; 4892c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->ydpi = fb->ydpi; 4902c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->fb = fb; 4912c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 4922c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4932c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland INFO("display %d x %d fmt=%d\n", 4942c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->width, win->height, win->format); 4952c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 4962c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland err = gralloc_open(module, &gr); 4972c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (err) { 4982c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland ERROR("couldn't open gralloc HAL (%s)", strerror(-err)); 4992c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENODEV; 5002c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 5012c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->gr = gr; 5022c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5032c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland usage = GRALLOC_USAGE_HW_FB | 5042c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland GRALLOC_USAGE_HW_COMPOSER | 5052c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland GRALLOC_USAGE_HW_RENDER; 5062c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5072c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland for (i = 0; i < 2; i++) { 5082c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland aBuffer *buf = cnw_alloc(win, win->format, usage); 5092c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (!buf) 5102c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENOMEM; 5112c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland put_back(&win->free_buffer_queue, buf); 5122c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 5132c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5142c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (!win->fb && QCT_WORKAROUND) { 5152c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->spare = cnw_alloc(win, win->format, usage); 5162c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (!win->spare) 5172c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return -ENOMEM; 5182c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 5192c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5202c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland // Disgusting, but we need to init these "const" fields 5212c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland // and unlike C++ we can't use const_cast<> 5222c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *((float*) &win->base.xdpi) = win->xdpi; 5232c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *((float*) &win->base.ydpi) = win->ydpi; 5242c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *((int*) &win->base.minSwapInterval) = 1; 5252c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *((int*) &win->base.maxSwapInterval) = 1; 5262c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5272c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.common.magic = ANDROID_NATIVE_WINDOW_MAGIC; 5282c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.common.version = sizeof(aWindow); 5292c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.common.incRef = cnw_inc_ref; 5302c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.common.decRef = cnw_dec_ref; 5312c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5322c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.setSwapInterval = cnw_set_swap_interval; 5332c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.dequeueBuffer_DEPRECATED = cnw_dequeue_buffer0; 5342c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.lockBuffer_DEPRECATED = cnw_lock_buffer0; 5352c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.queueBuffer_DEPRECATED = cnw_queue_buffer0; 5362c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.query = cnw_query; 5372c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.perform = cnw_perform; 5382c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.cancelBuffer_DEPRECATED = cnw_cancel_buffer0; 5392c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.dequeueBuffer = cnw_dequeue_buffer1; 5402c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.queueBuffer = cnw_queue_buffer1; 5412c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland win->base.cancelBuffer = cnw_cancel_buffer1; 5422c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5432c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_mutex_init(&win->lock, NULL); 5442c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland pthread_cond_init(&win->cvar, NULL); 5452c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5462c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return 0; 5472c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 5482c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5492c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandvoid cnw_destroy(CNativeWindow *win) { 5502c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (win->fb) 5512c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland framebuffer_close(win->fb); 5522c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (win->hwc) 5532c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland hwc_close_1(win->hwc); 5542c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (win->gr) 5552c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland gralloc_close(win->gr); 5562c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland free(win); 5572c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 5582c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5592c7b08ad8aeedef1807560ea16d54d073bede2b2Brian SwetlandCNativeWindow *cnw_create(void) { 5602c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland CNativeWindow *win; 5612c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland char *x; 5622c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if ((x = getenv("CNWDEBUG"))) 5632c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland trace_level = atoi(x); 5642c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (!(win = malloc(sizeof(CNativeWindow)))) 5652c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return NULL; 5662c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland if (cnw_init(win)) { 5672c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland cnw_destroy(win); 5682c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return NULL; 5692c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland } 5702c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland return win; 5712c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 5722c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 5732c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetlandvoid cnw_info(CNativeWindow *win, unsigned *w, unsigned *h, unsigned *fmt) { 5742c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *w = win->width; 5752c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *h = win->height; 5762c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland *fmt = win->format; 5772c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland} 5782c7b08ad8aeedef1807560ea16d54d073bede2b2Brian Swetland 579