1*e01b6f76SAndroid Build Coastguard Worker /*
2*e01b6f76SAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project
3*e01b6f76SAndroid Build Coastguard Worker *
4*e01b6f76SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e01b6f76SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e01b6f76SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e01b6f76SAndroid Build Coastguard Worker *
8*e01b6f76SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e01b6f76SAndroid Build Coastguard Worker *
10*e01b6f76SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e01b6f76SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e01b6f76SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e01b6f76SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e01b6f76SAndroid Build Coastguard Worker * limitations under the License.
15*e01b6f76SAndroid Build Coastguard Worker */
16*e01b6f76SAndroid Build Coastguard Worker
17*e01b6f76SAndroid Build Coastguard Worker #include <stdio.h>
18*e01b6f76SAndroid Build Coastguard Worker #include <stdlib.h>
19*e01b6f76SAndroid Build Coastguard Worker #include <stdarg.h>
20*e01b6f76SAndroid Build Coastguard Worker #include <string.h>
21*e01b6f76SAndroid Build Coastguard Worker #include <errno.h>
22*e01b6f76SAndroid Build Coastguard Worker
23*e01b6f76SAndroid Build Coastguard Worker #include <pthread.h>
24*e01b6f76SAndroid Build Coastguard Worker
25*e01b6f76SAndroid Build Coastguard Worker #include <hardware/hardware.h>
26*e01b6f76SAndroid Build Coastguard Worker #include <hardware/gralloc.h>
27*e01b6f76SAndroid Build Coastguard Worker #include <hardware/hwcomposer.h>
28*e01b6f76SAndroid Build Coastguard Worker
29*e01b6f76SAndroid Build Coastguard Worker #include <system/window.h>
30*e01b6f76SAndroid Build Coastguard Worker #include <cutils/native_handle.h>
31*e01b6f76SAndroid Build Coastguard Worker
32*e01b6f76SAndroid Build Coastguard Worker // normalize and shorten type names
33*e01b6f76SAndroid Build Coastguard Worker typedef struct android_native_base_t aBase;
34*e01b6f76SAndroid Build Coastguard Worker typedef struct ANativeWindowBuffer aBuffer;
35*e01b6f76SAndroid Build Coastguard Worker typedef struct ANativeWindow aWindow;
36*e01b6f76SAndroid Build Coastguard Worker
37*e01b6f76SAndroid Build Coastguard Worker static int trace_level = 1;
38*e01b6f76SAndroid Build Coastguard Worker
39*e01b6f76SAndroid Build Coastguard Worker #define _TRACE(n,fmt...) \
40*e01b6f76SAndroid Build Coastguard Worker do { if (trace_level >= (n)) fprintf(stderr, "CNW: " fmt); } while (0)
41*e01b6f76SAndroid Build Coastguard Worker
42*e01b6f76SAndroid Build Coastguard Worker #define ERROR(fmt...) _TRACE(0, fmt)
43*e01b6f76SAndroid Build Coastguard Worker #define INFO(fmt...) _TRACE(1, fmt)
44*e01b6f76SAndroid Build Coastguard Worker #define LOG(fmt...) _TRACE(2, fmt)
45*e01b6f76SAndroid Build Coastguard Worker #define TRACE(fmt...) _TRACE(3, fmt)
46*e01b6f76SAndroid Build Coastguard Worker
47*e01b6f76SAndroid Build Coastguard Worker #define QCT_WORKAROUND 1
48*e01b6f76SAndroid Build Coastguard Worker
49*e01b6f76SAndroid Build Coastguard Worker typedef struct CNativeBuffer {
50*e01b6f76SAndroid Build Coastguard Worker aBuffer base;
51*e01b6f76SAndroid Build Coastguard Worker struct CNativeBuffer *next;
52*e01b6f76SAndroid Build Coastguard Worker struct CNativeBuffer *prev;
53*e01b6f76SAndroid Build Coastguard Worker int ffd;
54*e01b6f76SAndroid Build Coastguard Worker } CNativeBuffer;
55*e01b6f76SAndroid Build Coastguard Worker
56*e01b6f76SAndroid Build Coastguard Worker typedef struct CNativeWindow {
57*e01b6f76SAndroid Build Coastguard Worker aWindow base;
58*e01b6f76SAndroid Build Coastguard Worker
59*e01b6f76SAndroid Build Coastguard Worker hwc_composer_device_1_t *hwc;
60*e01b6f76SAndroid Build Coastguard Worker framebuffer_device_t *fb;
61*e01b6f76SAndroid Build Coastguard Worker alloc_device_t *gr;
62*e01b6f76SAndroid Build Coastguard Worker
63*e01b6f76SAndroid Build Coastguard Worker pthread_mutex_t lock;
64*e01b6f76SAndroid Build Coastguard Worker pthread_cond_t cvar;
65*e01b6f76SAndroid Build Coastguard Worker
66*e01b6f76SAndroid Build Coastguard Worker aBuffer *front;
67*e01b6f76SAndroid Build Coastguard Worker aBuffer *spare;
68*e01b6f76SAndroid Build Coastguard Worker
69*e01b6f76SAndroid Build Coastguard Worker CNativeBuffer free_buffer_queue;
70*e01b6f76SAndroid Build Coastguard Worker
71*e01b6f76SAndroid Build Coastguard Worker unsigned width;
72*e01b6f76SAndroid Build Coastguard Worker unsigned height;
73*e01b6f76SAndroid Build Coastguard Worker unsigned xdpi;
74*e01b6f76SAndroid Build Coastguard Worker unsigned ydpi;
75*e01b6f76SAndroid Build Coastguard Worker unsigned format;
76*e01b6f76SAndroid Build Coastguard Worker
77*e01b6f76SAndroid Build Coastguard Worker hwc_display_contents_1_t *dclist[HWC_NUM_PHYSICAL_DISPLAY_TYPES];
78*e01b6f76SAndroid Build Coastguard Worker
79*e01b6f76SAndroid Build Coastguard Worker hwc_display_contents_1_t dc;
80*e01b6f76SAndroid Build Coastguard Worker hwc_layer_1_t layer[4];
81*e01b6f76SAndroid Build Coastguard Worker } CNativeWindow;
82*e01b6f76SAndroid Build Coastguard Worker
from_abuffer(aBuffer * buf)83*e01b6f76SAndroid Build Coastguard Worker static inline CNativeBuffer *from_abuffer(aBuffer *buf) {
84*e01b6f76SAndroid Build Coastguard Worker return (CNativeBuffer*) buf;
85*e01b6f76SAndroid Build Coastguard Worker }
86*e01b6f76SAndroid Build Coastguard Worker
get_front(struct CNativeBuffer * queue)87*e01b6f76SAndroid Build Coastguard Worker static CNativeBuffer *get_front(struct CNativeBuffer *queue) {
88*e01b6f76SAndroid Build Coastguard Worker CNativeBuffer *buf = queue->next;
89*e01b6f76SAndroid Build Coastguard Worker if (buf == queue)
90*e01b6f76SAndroid Build Coastguard Worker return 0;
91*e01b6f76SAndroid Build Coastguard Worker buf->next->prev = queue;
92*e01b6f76SAndroid Build Coastguard Worker queue->next = buf->next;
93*e01b6f76SAndroid Build Coastguard Worker buf->next = buf->prev = 0;
94*e01b6f76SAndroid Build Coastguard Worker return buf;
95*e01b6f76SAndroid Build Coastguard Worker }
96*e01b6f76SAndroid Build Coastguard Worker
put_front(struct CNativeBuffer * queue,aBuffer * _buf)97*e01b6f76SAndroid Build Coastguard Worker static void put_front(struct CNativeBuffer *queue, aBuffer *_buf) {
98*e01b6f76SAndroid Build Coastguard Worker struct CNativeBuffer *buf = (struct CNativeBuffer *) _buf;
99*e01b6f76SAndroid Build Coastguard Worker buf->prev = queue;
100*e01b6f76SAndroid Build Coastguard Worker buf->next = queue->next;
101*e01b6f76SAndroid Build Coastguard Worker queue->next->prev = buf;
102*e01b6f76SAndroid Build Coastguard Worker queue->next = buf;
103*e01b6f76SAndroid Build Coastguard Worker }
104*e01b6f76SAndroid Build Coastguard Worker
put_back(struct CNativeBuffer * queue,aBuffer * _buf)105*e01b6f76SAndroid Build Coastguard Worker static void put_back(struct CNativeBuffer *queue, aBuffer *_buf) {
106*e01b6f76SAndroid Build Coastguard Worker struct CNativeBuffer *buf = (struct CNativeBuffer *) _buf;
107*e01b6f76SAndroid Build Coastguard Worker buf->next = queue;
108*e01b6f76SAndroid Build Coastguard Worker buf->prev = queue->prev;
109*e01b6f76SAndroid Build Coastguard Worker queue->prev->next = buf;
110*e01b6f76SAndroid Build Coastguard Worker queue->prev = buf;
111*e01b6f76SAndroid Build Coastguard Worker }
112*e01b6f76SAndroid Build Coastguard Worker
cnw_inc_ref(aBase * base)113*e01b6f76SAndroid Build Coastguard Worker static void cnw_inc_ref(aBase *base) { TRACE("buf %p ref++\n",base); }
cnw_dec_ref(aBase * base)114*e01b6f76SAndroid Build Coastguard Worker static void cnw_dec_ref(aBase *base) { TRACE("buf %p ref--\n",base); }
115*e01b6f76SAndroid Build Coastguard Worker
from_base(aWindow * base)116*e01b6f76SAndroid Build Coastguard Worker static inline CNativeWindow *from_base(aWindow *base) {
117*e01b6f76SAndroid Build Coastguard Worker return (CNativeWindow *) base;
118*e01b6f76SAndroid Build Coastguard Worker }
119*e01b6f76SAndroid Build Coastguard Worker
from_base_const(const aWindow * base)120*e01b6f76SAndroid Build Coastguard Worker static inline CNativeWindow *from_base_const(const aWindow *base) {
121*e01b6f76SAndroid Build Coastguard Worker return (CNativeWindow *) base;
122*e01b6f76SAndroid Build Coastguard Worker }
123*e01b6f76SAndroid Build Coastguard Worker
cnw_set_swap_interval(aWindow * base,int interval)124*e01b6f76SAndroid Build Coastguard Worker static int cnw_set_swap_interval(aWindow *base, int interval) {
125*e01b6f76SAndroid Build Coastguard Worker CNativeWindow *win = from_base(base);
126*e01b6f76SAndroid Build Coastguard Worker if (win->fb && win->fb->setSwapInterval)
127*e01b6f76SAndroid Build Coastguard Worker return win->fb->setSwapInterval(win->fb, interval);
128*e01b6f76SAndroid Build Coastguard Worker return 0;
129*e01b6f76SAndroid Build Coastguard Worker }
130*e01b6f76SAndroid Build Coastguard Worker
cnw_dequeue_buffer1(aWindow * base,aBuffer ** buf,int * ffd)131*e01b6f76SAndroid Build Coastguard Worker static int cnw_dequeue_buffer1(aWindow *base, aBuffer **buf, int *ffd) {
132*e01b6f76SAndroid Build Coastguard Worker CNativeWindow *win = from_base(base);
133*e01b6f76SAndroid Build Coastguard Worker CNativeBuffer *cnb;
134*e01b6f76SAndroid Build Coastguard Worker
135*e01b6f76SAndroid Build Coastguard Worker pthread_mutex_lock(&win->lock);
136*e01b6f76SAndroid Build Coastguard Worker
137*e01b6f76SAndroid Build Coastguard Worker while ((cnb = get_front(&win->free_buffer_queue)) == 0) {
138*e01b6f76SAndroid Build Coastguard Worker pthread_cond_wait(&win->cvar, &win->lock);
139*e01b6f76SAndroid Build Coastguard Worker }
140*e01b6f76SAndroid Build Coastguard Worker
141*e01b6f76SAndroid Build Coastguard Worker *ffd = cnb->ffd;
142*e01b6f76SAndroid Build Coastguard Worker *buf = &cnb->base;
143*e01b6f76SAndroid Build Coastguard Worker cnb->ffd = -1;
144*e01b6f76SAndroid Build Coastguard Worker LOG("<< dequeue buffer %p %d\n", *buf, *ffd);
145*e01b6f76SAndroid Build Coastguard Worker
146*e01b6f76SAndroid Build Coastguard Worker pthread_mutex_unlock(&win->lock);
147*e01b6f76SAndroid Build Coastguard Worker return 0;
148*e01b6f76SAndroid Build Coastguard Worker }
149*e01b6f76SAndroid Build Coastguard Worker
cnw_lock_buffer0(aWindow * base,aBuffer * buffer)150*e01b6f76SAndroid Build Coastguard Worker static int cnw_lock_buffer0(aWindow *base, aBuffer *buffer) {
151*e01b6f76SAndroid Build Coastguard Worker return 0;
152*e01b6f76SAndroid Build Coastguard Worker }
153*e01b6f76SAndroid Build Coastguard Worker
set_layer(hwc_layer_1_t * dl,aBuffer * buf,int ffd)154*e01b6f76SAndroid Build Coastguard Worker static void set_layer(hwc_layer_1_t *dl, aBuffer *buf, int ffd) {
155*e01b6f76SAndroid Build Coastguard Worker int right = buf->width;
156*e01b6f76SAndroid Build Coastguard Worker int bottom = buf->height;
157*e01b6f76SAndroid Build Coastguard Worker
158*e01b6f76SAndroid Build Coastguard Worker dl->compositionType = HWC_FRAMEBUFFER;
159*e01b6f76SAndroid Build Coastguard Worker dl->hints = 0;
160*e01b6f76SAndroid Build Coastguard Worker dl->flags = 0;
161*e01b6f76SAndroid Build Coastguard Worker
162*e01b6f76SAndroid Build Coastguard Worker dl->handle = buf->handle;
163*e01b6f76SAndroid Build Coastguard Worker dl->transform = 0;
164*e01b6f76SAndroid Build Coastguard Worker dl->blending = HWC_BLENDING_NONE;
165*e01b6f76SAndroid Build Coastguard Worker dl->sourceCrop.left = 0;
166*e01b6f76SAndroid Build Coastguard Worker dl->sourceCrop.top = 0;
167*e01b6f76SAndroid Build Coastguard Worker dl->sourceCrop.right = right;
168*e01b6f76SAndroid Build Coastguard Worker dl->sourceCrop.bottom = bottom;
169*e01b6f76SAndroid Build Coastguard Worker dl->displayFrame.left = 0;
170*e01b6f76SAndroid Build Coastguard Worker dl->displayFrame.top = 0;
171*e01b6f76SAndroid Build Coastguard Worker dl->displayFrame.right = right;
172*e01b6f76SAndroid Build Coastguard Worker dl->displayFrame.bottom = bottom;
173*e01b6f76SAndroid Build Coastguard Worker dl->visibleRegionScreen.numRects = 1;
174*e01b6f76SAndroid Build Coastguard Worker dl->visibleRegionScreen.rects = &dl->displayFrame;
175*e01b6f76SAndroid Build Coastguard Worker
176*e01b6f76SAndroid Build Coastguard Worker dl->acquireFenceFd = ffd;
177*e01b6f76SAndroid Build Coastguard Worker dl->releaseFenceFd = -1;
178*e01b6f76SAndroid Build Coastguard Worker }
179*e01b6f76SAndroid Build Coastguard Worker
hwc_post(CNativeWindow * win,aBuffer * buf,int ffd)180*e01b6f76SAndroid Build Coastguard Worker static void hwc_post(CNativeWindow *win, aBuffer *buf, int ffd) {
181*e01b6f76SAndroid Build Coastguard Worker hwc_composer_device_1_t *hwc = win->hwc;
182*e01b6f76SAndroid Build Coastguard Worker hwc_display_contents_1_t *dc = &(win->dc);
183*e01b6f76SAndroid Build Coastguard Worker hwc_layer_1_t *dl = win->dc.hwLayers;
184*e01b6f76SAndroid Build Coastguard Worker int r;
185*e01b6f76SAndroid Build Coastguard Worker
186*e01b6f76SAndroid Build Coastguard Worker dc->retireFenceFd = -1;
187*e01b6f76SAndroid Build Coastguard Worker dc->outbufAcquireFenceFd = -1;
188*e01b6f76SAndroid Build Coastguard Worker dc->flags = HWC_GEOMETRY_CHANGED;
189*e01b6f76SAndroid Build Coastguard Worker dc->numHwLayers = 1;
190*e01b6f76SAndroid Build Coastguard Worker
191*e01b6f76SAndroid Build Coastguard Worker // some hwcomposers fail if these are NULL
192*e01b6f76SAndroid Build Coastguard Worker dc->dpy = (void*) 0xdeadbeef;
193*e01b6f76SAndroid Build Coastguard Worker dc->sur = (void*) 0xdeadbeef;
194*e01b6f76SAndroid Build Coastguard Worker
195*e01b6f76SAndroid Build Coastguard Worker set_layer(&dl[0], buf, ffd);
196*e01b6f76SAndroid Build Coastguard Worker
197*e01b6f76SAndroid Build Coastguard Worker if (QCT_WORKAROUND) {
198*e01b6f76SAndroid Build Coastguard Worker set_layer(&dl[1], win->spare, -1);
199*e01b6f76SAndroid Build Coastguard Worker dl[1].compositionType = HWC_FRAMEBUFFER_TARGET;
200*e01b6f76SAndroid Build Coastguard Worker dc->numHwLayers++;
201*e01b6f76SAndroid Build Coastguard Worker }
202*e01b6f76SAndroid Build Coastguard Worker
203*e01b6f76SAndroid Build Coastguard Worker r = hwc->prepare(hwc, HWC_NUM_PHYSICAL_DISPLAY_TYPES, win->dclist);
204*e01b6f76SAndroid Build Coastguard Worker if (r) {
205*e01b6f76SAndroid Build Coastguard Worker ERROR("hwc->prepare failed r=%d\n",r);
206*e01b6f76SAndroid Build Coastguard Worker return;
207*e01b6f76SAndroid Build Coastguard Worker }
208*e01b6f76SAndroid Build Coastguard Worker
209*e01b6f76SAndroid Build Coastguard Worker // for (i = 0; i < dc->numHwLayers; i++)
210*e01b6f76SAndroid Build Coastguard Worker // LOG("dl[%d] ctype=0x%08x hints=0x%08x flags=0x%08x\n", i,
211*e01b6f76SAndroid Build Coastguard Worker // dl[i].compositionType, dl[0].hints, dl[0].flags);
212*e01b6f76SAndroid Build Coastguard Worker
213*e01b6f76SAndroid Build Coastguard Worker r = hwc->set(hwc, HWC_NUM_PHYSICAL_DISPLAY_TYPES, win->dclist);
214*e01b6f76SAndroid Build Coastguard Worker if (r) {
215*e01b6f76SAndroid Build Coastguard Worker ERROR("hwc->set failed, r=%d\n", r);
216*e01b6f76SAndroid Build Coastguard Worker return;
217*e01b6f76SAndroid Build Coastguard Worker }
218*e01b6f76SAndroid Build Coastguard Worker
219*e01b6f76SAndroid Build Coastguard Worker if (dc->retireFenceFd != -1)
220*e01b6f76SAndroid Build Coastguard Worker close(dc->retireFenceFd);
221*e01b6f76SAndroid Build Coastguard Worker if (dl->releaseFenceFd != -1) {
222*e01b6f76SAndroid Build Coastguard Worker CNativeBuffer *cnb = from_abuffer(buf);
223*e01b6f76SAndroid Build Coastguard Worker cnb->ffd = dl->releaseFenceFd;
224*e01b6f76SAndroid Build Coastguard Worker }
225*e01b6f76SAndroid Build Coastguard Worker if (QCT_WORKAROUND)
226*e01b6f76SAndroid Build Coastguard Worker if (dl[1].releaseFenceFd != -1)
227*e01b6f76SAndroid Build Coastguard Worker close(dl[1].releaseFenceFd);
228*e01b6f76SAndroid Build Coastguard Worker }
229*e01b6f76SAndroid Build Coastguard Worker
cnw_queue_buffer1(aWindow * base,aBuffer * buffer,int ffd)230*e01b6f76SAndroid Build Coastguard Worker static int cnw_queue_buffer1(aWindow *base, aBuffer *buffer, int ffd) {
231*e01b6f76SAndroid Build Coastguard Worker CNativeWindow *win = from_base(base);
232*e01b6f76SAndroid Build Coastguard Worker int res;
233*e01b6f76SAndroid Build Coastguard Worker LOG(">> queue buffer %p %d\n", buffer, ffd);
234*e01b6f76SAndroid Build Coastguard Worker if (win->fb) {
235*e01b6f76SAndroid Build Coastguard Worker res = win->fb->post(win->fb, buffer->handle);
236*e01b6f76SAndroid Build Coastguard Worker if (ffd != -1)
237*e01b6f76SAndroid Build Coastguard Worker close(ffd);
238*e01b6f76SAndroid Build Coastguard Worker } else {
239*e01b6f76SAndroid Build Coastguard Worker hwc_post(win, buffer, ffd);
240*e01b6f76SAndroid Build Coastguard Worker res = 0;
241*e01b6f76SAndroid Build Coastguard Worker }
242*e01b6f76SAndroid Build Coastguard Worker pthread_mutex_lock(&win->lock);
243*e01b6f76SAndroid Build Coastguard Worker if (win->front)
244*e01b6f76SAndroid Build Coastguard Worker put_back(&win->free_buffer_queue, win->front);
245*e01b6f76SAndroid Build Coastguard Worker win->front = buffer;
246*e01b6f76SAndroid Build Coastguard Worker pthread_cond_signal(&win->cvar);
247*e01b6f76SAndroid Build Coastguard Worker pthread_mutex_unlock(&win->lock);
248*e01b6f76SAndroid Build Coastguard Worker
249*e01b6f76SAndroid Build Coastguard Worker return res;
250*e01b6f76SAndroid Build Coastguard Worker }
251*e01b6f76SAndroid Build Coastguard Worker
cnw_cancel_buffer1(aWindow * base,aBuffer * buf,int ffd)252*e01b6f76SAndroid Build Coastguard Worker static int cnw_cancel_buffer1(aWindow *base, aBuffer *buf, int ffd) {
253*e01b6f76SAndroid Build Coastguard Worker CNativeWindow *win = from_base(base);
254*e01b6f76SAndroid Build Coastguard Worker CNativeBuffer *cnb = from_abuffer(buf);
255*e01b6f76SAndroid Build Coastguard Worker LOG("<< cancel buffer %p %d\n", buf, ffd);
256*e01b6f76SAndroid Build Coastguard Worker cnb->ffd = ffd;
257*e01b6f76SAndroid Build Coastguard Worker pthread_mutex_lock(&win->lock);
258*e01b6f76SAndroid Build Coastguard Worker put_front(&win->free_buffer_queue, buf);
259*e01b6f76SAndroid Build Coastguard Worker pthread_mutex_unlock(&win->lock);
260*e01b6f76SAndroid Build Coastguard Worker return 0;
261*e01b6f76SAndroid Build Coastguard Worker }
262*e01b6f76SAndroid Build Coastguard Worker
cnw_dequeue_buffer0(aWindow * base,aBuffer ** buf)263*e01b6f76SAndroid Build Coastguard Worker static int cnw_dequeue_buffer0(aWindow *base, aBuffer **buf) {
264*e01b6f76SAndroid Build Coastguard Worker int ffd = -1;
265*e01b6f76SAndroid Build Coastguard Worker int r;
266*e01b6f76SAndroid Build Coastguard Worker r = cnw_dequeue_buffer1(base, buf, &ffd);
267*e01b6f76SAndroid Build Coastguard Worker if (ffd != -1)
268*e01b6f76SAndroid Build Coastguard Worker close(ffd);
269*e01b6f76SAndroid Build Coastguard Worker return r;
270*e01b6f76SAndroid Build Coastguard Worker }
271*e01b6f76SAndroid Build Coastguard Worker
cnw_queue_buffer0(aWindow * base,aBuffer * buf)272*e01b6f76SAndroid Build Coastguard Worker static int cnw_queue_buffer0(aWindow *base, aBuffer *buf) {
273*e01b6f76SAndroid Build Coastguard Worker return cnw_queue_buffer1(base, buf, -1);
274*e01b6f76SAndroid Build Coastguard Worker }
275*e01b6f76SAndroid Build Coastguard Worker
cnw_cancel_buffer0(aWindow * base,aBuffer * buf)276*e01b6f76SAndroid Build Coastguard Worker static int cnw_cancel_buffer0(aWindow *base, aBuffer *buf) {
277*e01b6f76SAndroid Build Coastguard Worker return cnw_cancel_buffer1(base, buf, -1);
278*e01b6f76SAndroid Build Coastguard Worker }
279*e01b6f76SAndroid Build Coastguard Worker
cnw_query(const aWindow * base,int what,int * value)280*e01b6f76SAndroid Build Coastguard Worker static int cnw_query(const aWindow *base, int what, int *value) {
281*e01b6f76SAndroid Build Coastguard Worker CNativeWindow *win = from_base_const(base);
282*e01b6f76SAndroid Build Coastguard Worker
283*e01b6f76SAndroid Build Coastguard Worker switch (what) {
284*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_WIDTH:
285*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_DEFAULT_WIDTH:
286*e01b6f76SAndroid Build Coastguard Worker *value = win->width;
287*e01b6f76SAndroid Build Coastguard Worker TRACE("query window width: %d\n", *value);
288*e01b6f76SAndroid Build Coastguard Worker return 0;
289*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_HEIGHT:
290*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_DEFAULT_HEIGHT:
291*e01b6f76SAndroid Build Coastguard Worker *value = win->height;
292*e01b6f76SAndroid Build Coastguard Worker TRACE("query window height: %d\n", *value);
293*e01b6f76SAndroid Build Coastguard Worker return 0;
294*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_FORMAT:
295*e01b6f76SAndroid Build Coastguard Worker *value = win->format;
296*e01b6f76SAndroid Build Coastguard Worker TRACE("query window format: %d\n", *value);
297*e01b6f76SAndroid Build Coastguard Worker return 0;
298*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_TRANSFORM_HINT:
299*e01b6f76SAndroid Build Coastguard Worker TRACE("query transform hint: 0\n");
300*e01b6f76SAndroid Build Coastguard Worker *value = 0;
301*e01b6f76SAndroid Build Coastguard Worker return 0;
302*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
303*e01b6f76SAndroid Build Coastguard Worker TRACE("query min undequeued buffers: 1\n");
304*e01b6f76SAndroid Build Coastguard Worker *value = 1;
305*e01b6f76SAndroid Build Coastguard Worker return 0;
306*e01b6f76SAndroid Build Coastguard Worker default:
307*e01b6f76SAndroid Build Coastguard Worker *value = 0;
308*e01b6f76SAndroid Build Coastguard Worker ERROR("query %d unknown!\n", what);
309*e01b6f76SAndroid Build Coastguard Worker return -EINVAL;
310*e01b6f76SAndroid Build Coastguard Worker }
311*e01b6f76SAndroid Build Coastguard Worker }
312*e01b6f76SAndroid Build Coastguard Worker
cnw_perform(aWindow * base,int op,...)313*e01b6f76SAndroid Build Coastguard Worker static int cnw_perform(aWindow *base, int op, ...) {
314*e01b6f76SAndroid Build Coastguard Worker CNativeWindow *win = from_base(base);
315*e01b6f76SAndroid Build Coastguard Worker va_list ap;
316*e01b6f76SAndroid Build Coastguard Worker va_start(ap, op);
317*e01b6f76SAndroid Build Coastguard Worker
318*e01b6f76SAndroid Build Coastguard Worker switch (op) {
319*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_USAGE:
320*e01b6f76SAndroid Build Coastguard Worker TRACE("set usage %d\n", va_arg(ap,int));
321*e01b6f76SAndroid Build Coastguard Worker return 0;
322*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_CONNECT:
323*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_DISCONNECT:
324*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_API_CONNECT:
325*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_API_DISCONNECT:
326*e01b6f76SAndroid Build Coastguard Worker return 0;
327*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
328*e01b6f76SAndroid Build Coastguard Worker TRACE("set buffers format %d\n", va_arg(ap,int));
329*e01b6f76SAndroid Build Coastguard Worker return 0;
330*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
331*e01b6f76SAndroid Build Coastguard Worker TRACE("set buffers transform %d\n", va_arg(ap,int));
332*e01b6f76SAndroid Build Coastguard Worker return 0;
333*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
334*e01b6f76SAndroid Build Coastguard Worker TRACE("set buffers timestamp %lld\n", va_arg(ap,long long));
335*e01b6f76SAndroid Build Coastguard Worker return 0;
336*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_SCALING_MODE:
337*e01b6f76SAndroid Build Coastguard Worker TRACE("set scaling mode %d\n", va_arg(ap,int));
338*e01b6f76SAndroid Build Coastguard Worker return 0;
339*e01b6f76SAndroid Build Coastguard Worker case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: {
340*e01b6f76SAndroid Build Coastguard Worker unsigned int w = va_arg(ap,unsigned int);
341*e01b6f76SAndroid Build Coastguard Worker unsigned int h = va_arg(ap,unsigned int);
342*e01b6f76SAndroid Build Coastguard Worker if ((w == win->width) && (h == win->height)) {
343*e01b6f76SAndroid Build Coastguard Worker TRACE("set buffers dimensions %d x %d\n", w, h);
344*e01b6f76SAndroid Build Coastguard Worker return 0;
345*e01b6f76SAndroid Build Coastguard Worker }
346*e01b6f76SAndroid Build Coastguard Worker ERROR("cannot resize buffers to %d x %d\n", w, h);
347*e01b6f76SAndroid Build Coastguard Worker return -1;
348*e01b6f76SAndroid Build Coastguard Worker }
349*e01b6f76SAndroid Build Coastguard Worker default:
350*e01b6f76SAndroid Build Coastguard Worker ERROR("perform %d unknown!\n", op);
351*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
352*e01b6f76SAndroid Build Coastguard Worker }
353*e01b6f76SAndroid Build Coastguard Worker }
354*e01b6f76SAndroid Build Coastguard Worker
hwc_invalidate(const struct hwc_procs * procs)355*e01b6f76SAndroid Build Coastguard Worker static void hwc_invalidate(const struct hwc_procs *procs) {}
hwc_vsync(const struct hwc_procs * procs,int disp,int64_t ts)356*e01b6f76SAndroid Build Coastguard Worker static void hwc_vsync(const struct hwc_procs *procs, int disp, int64_t ts) {}
hwc_hotplug(const struct hwc_procs * procs,int disp,int conn)357*e01b6f76SAndroid Build Coastguard Worker static void hwc_hotplug(const struct hwc_procs *procs, int disp, int conn) {}
358*e01b6f76SAndroid Build Coastguard Worker
359*e01b6f76SAndroid Build Coastguard Worker struct hwc_procs hprocs = {
360*e01b6f76SAndroid Build Coastguard Worker .invalidate = hwc_invalidate,
361*e01b6f76SAndroid Build Coastguard Worker .vsync = hwc_vsync,
362*e01b6f76SAndroid Build Coastguard Worker .hotplug = hwc_hotplug,
363*e01b6f76SAndroid Build Coastguard Worker };
364*e01b6f76SAndroid Build Coastguard Worker
365*e01b6f76SAndroid Build Coastguard Worker uint32_t attrs[] = {
366*e01b6f76SAndroid Build Coastguard Worker HWC_DISPLAY_WIDTH,
367*e01b6f76SAndroid Build Coastguard Worker HWC_DISPLAY_HEIGHT,
368*e01b6f76SAndroid Build Coastguard Worker HWC_DISPLAY_VSYNC_PERIOD,
369*e01b6f76SAndroid Build Coastguard Worker HWC_DISPLAY_DPI_X,
370*e01b6f76SAndroid Build Coastguard Worker HWC_DISPLAY_DPI_Y,
371*e01b6f76SAndroid Build Coastguard Worker HWC_DISPLAY_NO_ATTRIBUTE,
372*e01b6f76SAndroid Build Coastguard Worker };
373*e01b6f76SAndroid Build Coastguard Worker
hwc_init(CNativeWindow * win)374*e01b6f76SAndroid Build Coastguard Worker static int hwc_init(CNativeWindow *win) {
375*e01b6f76SAndroid Build Coastguard Worker hw_module_t const* module;
376*e01b6f76SAndroid Build Coastguard Worker hwc_composer_device_1_t *hwc;
377*e01b6f76SAndroid Build Coastguard Worker unsigned i;
378*e01b6f76SAndroid Build Coastguard Worker int r;
379*e01b6f76SAndroid Build Coastguard Worker uint32_t configs[32];
380*e01b6f76SAndroid Build Coastguard Worker size_t numconfigs = 32;
381*e01b6f76SAndroid Build Coastguard Worker int32_t values[8];
382*e01b6f76SAndroid Build Coastguard Worker
383*e01b6f76SAndroid Build Coastguard Worker if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
384*e01b6f76SAndroid Build Coastguard Worker ERROR("cannot open hw composer module\n");
385*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
386*e01b6f76SAndroid Build Coastguard Worker }
387*e01b6f76SAndroid Build Coastguard Worker
388*e01b6f76SAndroid Build Coastguard Worker if (hwc_open_1(module, &hwc)) {
389*e01b6f76SAndroid Build Coastguard Worker ERROR("cannot open hwc device\n");
390*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
391*e01b6f76SAndroid Build Coastguard Worker }
392*e01b6f76SAndroid Build Coastguard Worker win->hwc = hwc;
393*e01b6f76SAndroid Build Coastguard Worker
394*e01b6f76SAndroid Build Coastguard Worker LOG("hwc version 0x%08x\n", hwc->common.version);
395*e01b6f76SAndroid Build Coastguard Worker
396*e01b6f76SAndroid Build Coastguard Worker if ((hwc->common.version & 0xFFFF0000) < 0x01010000) {
397*e01b6f76SAndroid Build Coastguard Worker ERROR("hwc version less than 1.1\n");
398*e01b6f76SAndroid Build Coastguard Worker hwc_close_1(hwc);
399*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
400*e01b6f76SAndroid Build Coastguard Worker }
401*e01b6f76SAndroid Build Coastguard Worker
402*e01b6f76SAndroid Build Coastguard Worker hwc->registerProcs(hwc, &hprocs);
403*e01b6f76SAndroid Build Coastguard Worker
404*e01b6f76SAndroid Build Coastguard Worker if (hwc->getDisplayConfigs(hwc, 0, configs, &numconfigs)) {
405*e01b6f76SAndroid Build Coastguard Worker ERROR("cannot get configs\n");
406*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
407*e01b6f76SAndroid Build Coastguard Worker }
408*e01b6f76SAndroid Build Coastguard Worker for (i = 0; i < numconfigs; i++)
409*e01b6f76SAndroid Build Coastguard Worker LOG("cfg[%d] = 0x%08x\n", i, configs[i]);
410*e01b6f76SAndroid Build Coastguard Worker
411*e01b6f76SAndroid Build Coastguard Worker if ((r = hwc->getDisplayAttributes(hwc, 0, configs[0], attrs, values))) {
412*e01b6f76SAndroid Build Coastguard Worker ERROR("cannot get attributes %d\n", r);
413*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
414*e01b6f76SAndroid Build Coastguard Worker }
415*e01b6f76SAndroid Build Coastguard Worker
416*e01b6f76SAndroid Build Coastguard Worker win->width = values[0];
417*e01b6f76SAndroid Build Coastguard Worker win->height = values[1];
418*e01b6f76SAndroid Build Coastguard Worker win->xdpi = values[3];
419*e01b6f76SAndroid Build Coastguard Worker win->ydpi = values[4];
420*e01b6f76SAndroid Build Coastguard Worker win->format = HAL_PIXEL_FORMAT_RGBA_8888;
421*e01b6f76SAndroid Build Coastguard Worker
422*e01b6f76SAndroid Build Coastguard Worker hwc->blank(hwc, 0, 0);
423*e01b6f76SAndroid Build Coastguard Worker
424*e01b6f76SAndroid Build Coastguard Worker win->dclist[0] = &(win->dc);
425*e01b6f76SAndroid Build Coastguard Worker return 0;
426*e01b6f76SAndroid Build Coastguard Worker }
427*e01b6f76SAndroid Build Coastguard Worker
cnw_alloc(CNativeWindow * win,unsigned format,unsigned usage)428*e01b6f76SAndroid Build Coastguard Worker static aBuffer *cnw_alloc(CNativeWindow *win, unsigned format, unsigned usage) {
429*e01b6f76SAndroid Build Coastguard Worker CNativeBuffer *cnb;
430*e01b6f76SAndroid Build Coastguard Worker aBuffer *buf;
431*e01b6f76SAndroid Build Coastguard Worker int err;
432*e01b6f76SAndroid Build Coastguard Worker
433*e01b6f76SAndroid Build Coastguard Worker if (!(cnb = malloc(sizeof(CNativeBuffer))))
434*e01b6f76SAndroid Build Coastguard Worker return 0;
435*e01b6f76SAndroid Build Coastguard Worker
436*e01b6f76SAndroid Build Coastguard Worker buf = &cnb->base;
437*e01b6f76SAndroid Build Coastguard Worker cnb->ffd = -1;
438*e01b6f76SAndroid Build Coastguard Worker
439*e01b6f76SAndroid Build Coastguard Worker buf->common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
440*e01b6f76SAndroid Build Coastguard Worker buf->common.version = sizeof(aBuffer);
441*e01b6f76SAndroid Build Coastguard Worker buf->common.incRef = cnw_inc_ref;
442*e01b6f76SAndroid Build Coastguard Worker buf->common.decRef = cnw_dec_ref;
443*e01b6f76SAndroid Build Coastguard Worker
444*e01b6f76SAndroid Build Coastguard Worker buf->width = win->width;
445*e01b6f76SAndroid Build Coastguard Worker buf->height = win->height;
446*e01b6f76SAndroid Build Coastguard Worker buf->format = format;
447*e01b6f76SAndroid Build Coastguard Worker buf->usage = usage;
448*e01b6f76SAndroid Build Coastguard Worker
449*e01b6f76SAndroid Build Coastguard Worker err = win->gr->alloc(win->gr, win->width, win->height,
450*e01b6f76SAndroid Build Coastguard Worker format, usage, &buf->handle, &buf->stride);
451*e01b6f76SAndroid Build Coastguard Worker if (err) {
452*e01b6f76SAndroid Build Coastguard Worker ERROR("gralloc of %d x %d failed: err=%d\n",
453*e01b6f76SAndroid Build Coastguard Worker win->width, win->height, err);
454*e01b6f76SAndroid Build Coastguard Worker free(buf);
455*e01b6f76SAndroid Build Coastguard Worker return 0;
456*e01b6f76SAndroid Build Coastguard Worker }
457*e01b6f76SAndroid Build Coastguard Worker INFO("alloc buffer %p %d x %d\n", buf, win->width, win->height);
458*e01b6f76SAndroid Build Coastguard Worker return buf;
459*e01b6f76SAndroid Build Coastguard Worker }
460*e01b6f76SAndroid Build Coastguard Worker
cnw_init(CNativeWindow * win)461*e01b6f76SAndroid Build Coastguard Worker static int cnw_init(CNativeWindow *win) {
462*e01b6f76SAndroid Build Coastguard Worker hw_module_t const* module;
463*e01b6f76SAndroid Build Coastguard Worker framebuffer_device_t *fb = NULL;
464*e01b6f76SAndroid Build Coastguard Worker alloc_device_t *gr;
465*e01b6f76SAndroid Build Coastguard Worker int err, i;
466*e01b6f76SAndroid Build Coastguard Worker unsigned usage;
467*e01b6f76SAndroid Build Coastguard Worker
468*e01b6f76SAndroid Build Coastguard Worker memset(win, 0, sizeof(CNativeWindow));
469*e01b6f76SAndroid Build Coastguard Worker
470*e01b6f76SAndroid Build Coastguard Worker win->free_buffer_queue.next = &(win->free_buffer_queue);
471*e01b6f76SAndroid Build Coastguard Worker win->free_buffer_queue.prev = &(win->free_buffer_queue);
472*e01b6f76SAndroid Build Coastguard Worker
473*e01b6f76SAndroid Build Coastguard Worker if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) != 0) {
474*e01b6f76SAndroid Build Coastguard Worker ERROR("cannot open gralloc module\n");
475*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
476*e01b6f76SAndroid Build Coastguard Worker }
477*e01b6f76SAndroid Build Coastguard Worker
478*e01b6f76SAndroid Build Coastguard Worker if (hwc_init(win)) {
479*e01b6f76SAndroid Build Coastguard Worker ERROR("cannot open hwcomposer, trying legacy fb HAL\n");
480*e01b6f76SAndroid Build Coastguard Worker err = framebuffer_open(module, &fb);
481*e01b6f76SAndroid Build Coastguard Worker if (err) {
482*e01b6f76SAndroid Build Coastguard Worker ERROR("cannot open fb HAL (%s)", strerror(-err));
483*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
484*e01b6f76SAndroid Build Coastguard Worker }
485*e01b6f76SAndroid Build Coastguard Worker win->width = fb->width;
486*e01b6f76SAndroid Build Coastguard Worker win->height = fb->height;
487*e01b6f76SAndroid Build Coastguard Worker win->format = fb->format;
488*e01b6f76SAndroid Build Coastguard Worker win->xdpi = fb->xdpi;
489*e01b6f76SAndroid Build Coastguard Worker win->ydpi = fb->ydpi;
490*e01b6f76SAndroid Build Coastguard Worker win->fb = fb;
491*e01b6f76SAndroid Build Coastguard Worker }
492*e01b6f76SAndroid Build Coastguard Worker
493*e01b6f76SAndroid Build Coastguard Worker INFO("display %d x %d fmt=%d\n",
494*e01b6f76SAndroid Build Coastguard Worker win->width, win->height, win->format);
495*e01b6f76SAndroid Build Coastguard Worker
496*e01b6f76SAndroid Build Coastguard Worker err = gralloc_open(module, &gr);
497*e01b6f76SAndroid Build Coastguard Worker if (err) {
498*e01b6f76SAndroid Build Coastguard Worker ERROR("couldn't open gralloc HAL (%s)", strerror(-err));
499*e01b6f76SAndroid Build Coastguard Worker return -ENODEV;
500*e01b6f76SAndroid Build Coastguard Worker }
501*e01b6f76SAndroid Build Coastguard Worker win->gr = gr;
502*e01b6f76SAndroid Build Coastguard Worker
503*e01b6f76SAndroid Build Coastguard Worker usage = GRALLOC_USAGE_HW_FB |
504*e01b6f76SAndroid Build Coastguard Worker GRALLOC_USAGE_HW_COMPOSER |
505*e01b6f76SAndroid Build Coastguard Worker GRALLOC_USAGE_HW_RENDER;
506*e01b6f76SAndroid Build Coastguard Worker
507*e01b6f76SAndroid Build Coastguard Worker for (i = 0; i < 2; i++) {
508*e01b6f76SAndroid Build Coastguard Worker aBuffer *buf = cnw_alloc(win, win->format, usage);
509*e01b6f76SAndroid Build Coastguard Worker if (!buf)
510*e01b6f76SAndroid Build Coastguard Worker return -ENOMEM;
511*e01b6f76SAndroid Build Coastguard Worker put_back(&win->free_buffer_queue, buf);
512*e01b6f76SAndroid Build Coastguard Worker }
513*e01b6f76SAndroid Build Coastguard Worker
514*e01b6f76SAndroid Build Coastguard Worker if (!win->fb && QCT_WORKAROUND) {
515*e01b6f76SAndroid Build Coastguard Worker win->spare = cnw_alloc(win, win->format, usage);
516*e01b6f76SAndroid Build Coastguard Worker if (!win->spare)
517*e01b6f76SAndroid Build Coastguard Worker return -ENOMEM;
518*e01b6f76SAndroid Build Coastguard Worker }
519*e01b6f76SAndroid Build Coastguard Worker
520*e01b6f76SAndroid Build Coastguard Worker // Disgusting, but we need to init these "const" fields
521*e01b6f76SAndroid Build Coastguard Worker // and unlike C++ we can't use const_cast<>
522*e01b6f76SAndroid Build Coastguard Worker *((float*) &win->base.xdpi) = win->xdpi;
523*e01b6f76SAndroid Build Coastguard Worker *((float*) &win->base.ydpi) = win->ydpi;
524*e01b6f76SAndroid Build Coastguard Worker *((int*) &win->base.minSwapInterval) = 1;
525*e01b6f76SAndroid Build Coastguard Worker *((int*) &win->base.maxSwapInterval) = 1;
526*e01b6f76SAndroid Build Coastguard Worker
527*e01b6f76SAndroid Build Coastguard Worker win->base.common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
528*e01b6f76SAndroid Build Coastguard Worker win->base.common.version = sizeof(aWindow);
529*e01b6f76SAndroid Build Coastguard Worker win->base.common.incRef = cnw_inc_ref;
530*e01b6f76SAndroid Build Coastguard Worker win->base.common.decRef = cnw_dec_ref;
531*e01b6f76SAndroid Build Coastguard Worker
532*e01b6f76SAndroid Build Coastguard Worker win->base.setSwapInterval = cnw_set_swap_interval;
533*e01b6f76SAndroid Build Coastguard Worker win->base.dequeueBuffer_DEPRECATED = cnw_dequeue_buffer0;
534*e01b6f76SAndroid Build Coastguard Worker win->base.lockBuffer_DEPRECATED = cnw_lock_buffer0;
535*e01b6f76SAndroid Build Coastguard Worker win->base.queueBuffer_DEPRECATED = cnw_queue_buffer0;
536*e01b6f76SAndroid Build Coastguard Worker win->base.query = cnw_query;
537*e01b6f76SAndroid Build Coastguard Worker win->base.perform = cnw_perform;
538*e01b6f76SAndroid Build Coastguard Worker win->base.cancelBuffer_DEPRECATED = cnw_cancel_buffer0;
539*e01b6f76SAndroid Build Coastguard Worker win->base.dequeueBuffer = cnw_dequeue_buffer1;
540*e01b6f76SAndroid Build Coastguard Worker win->base.queueBuffer = cnw_queue_buffer1;
541*e01b6f76SAndroid Build Coastguard Worker win->base.cancelBuffer = cnw_cancel_buffer1;
542*e01b6f76SAndroid Build Coastguard Worker
543*e01b6f76SAndroid Build Coastguard Worker pthread_mutex_init(&win->lock, NULL);
544*e01b6f76SAndroid Build Coastguard Worker pthread_cond_init(&win->cvar, NULL);
545*e01b6f76SAndroid Build Coastguard Worker
546*e01b6f76SAndroid Build Coastguard Worker return 0;
547*e01b6f76SAndroid Build Coastguard Worker }
548*e01b6f76SAndroid Build Coastguard Worker
cnw_destroy(CNativeWindow * win)549*e01b6f76SAndroid Build Coastguard Worker void cnw_destroy(CNativeWindow *win) {
550*e01b6f76SAndroid Build Coastguard Worker if (win->fb)
551*e01b6f76SAndroid Build Coastguard Worker framebuffer_close(win->fb);
552*e01b6f76SAndroid Build Coastguard Worker if (win->hwc)
553*e01b6f76SAndroid Build Coastguard Worker hwc_close_1(win->hwc);
554*e01b6f76SAndroid Build Coastguard Worker if (win->gr)
555*e01b6f76SAndroid Build Coastguard Worker gralloc_close(win->gr);
556*e01b6f76SAndroid Build Coastguard Worker free(win);
557*e01b6f76SAndroid Build Coastguard Worker }
558*e01b6f76SAndroid Build Coastguard Worker
cnw_create(void)559*e01b6f76SAndroid Build Coastguard Worker CNativeWindow *cnw_create(void) {
560*e01b6f76SAndroid Build Coastguard Worker CNativeWindow *win;
561*e01b6f76SAndroid Build Coastguard Worker char *x;
562*e01b6f76SAndroid Build Coastguard Worker if ((x = getenv("CNWDEBUG")))
563*e01b6f76SAndroid Build Coastguard Worker trace_level = atoi(x);
564*e01b6f76SAndroid Build Coastguard Worker if (!(win = malloc(sizeof(CNativeWindow))))
565*e01b6f76SAndroid Build Coastguard Worker return NULL;
566*e01b6f76SAndroid Build Coastguard Worker if (cnw_init(win)) {
567*e01b6f76SAndroid Build Coastguard Worker cnw_destroy(win);
568*e01b6f76SAndroid Build Coastguard Worker return NULL;
569*e01b6f76SAndroid Build Coastguard Worker }
570*e01b6f76SAndroid Build Coastguard Worker return win;
571*e01b6f76SAndroid Build Coastguard Worker }
572*e01b6f76SAndroid Build Coastguard Worker
cnw_info(CNativeWindow * win,unsigned * w,unsigned * h,unsigned * fmt)573*e01b6f76SAndroid Build Coastguard Worker void cnw_info(CNativeWindow *win, unsigned *w, unsigned *h, unsigned *fmt) {
574*e01b6f76SAndroid Build Coastguard Worker *w = win->width;
575*e01b6f76SAndroid Build Coastguard Worker *h = win->height;
576*e01b6f76SAndroid Build Coastguard Worker *fmt = win->format;
577*e01b6f76SAndroid Build Coastguard Worker }
578*e01b6f76SAndroid Build Coastguard Worker
579