2 * Copyright (C) 2013 libhybris
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "hwcomposer_window.h"
26 #include <android/android-version.h>
29 #include <android/sync/sync.h>
32 static pthread_cond_t _cond
= PTHREAD_COND_INITIALIZER
;
33 static pthread_mutex_t _mutex
= PTHREAD_MUTEX_INITIALIZER
;
36 HWComposerNativeWindowBuffer::HWComposerNativeWindowBuffer(alloc_device_t
* alloc_device
,
42 ANativeWindowBuffer::width
= width
;
43 ANativeWindowBuffer::height
= height
;
44 ANativeWindowBuffer::format
= format
;
45 ANativeWindowBuffer::usage
= usage
;
49 m_alloc
= alloc_device
;
52 status
= m_alloc
->alloc(m_alloc
,
53 width
, height
, format
, usage
,
57 TRACE("width=%d height=%d stride=%d format=x%x usage=x%x status=%s this=%p",
58 width
, height
, stride
, format
, usage
, strerror(-status
), this);
63 HWComposerNativeWindowBuffer::~HWComposerNativeWindowBuffer()
66 if (m_alloc
&& handle
)
67 m_alloc
->free(m_alloc
, handle
);
72 ////////////////////////////////////////////////////////////////////////////////
73 HWComposerNativeWindow::HWComposerNativeWindow(unsigned int width
, unsigned int height
, unsigned int format
)
79 m_usage
= GRALLOC_USAGE_HW_COMPOSER
;
83 void HWComposerNativeWindow::setup(gralloc_module_t
* gralloc
, alloc_device_t
* alloc
)
89 HWComposerNativeWindow::~HWComposerNativeWindow()
96 void HWComposerNativeWindow::destroyBuffers()
100 std::list
<HWComposerNativeWindowBuffer
*>::iterator it
= m_bufList
.begin();
101 for (; it
!=m_bufList
.end(); ++it
)
103 HWComposerNativeWindowBuffer
* fbnb
= *it
;
104 fbnb
->common
.decRef(&fbnb
->common
);
115 * Set the swap interval for this surface.
117 * Returns 0 on success or -errno on error.
119 int HWComposerNativeWindow::setSwapInterval(int interval
)
121 TRACE("interval=%i WARN STUB", interval
);
127 * Hook called by EGL to acquire a buffer. This call may block if no
128 * buffers are available.
130 * The window holds a reference to the buffer between dequeueBuffer and
131 * either queueBuffer or cancelBuffer, so clients only need their own
132 * reference if they might use the buffer after queueing or canceling it.
133 * Holding a reference to a buffer after queueing or canceling it is only
134 * allowed if a specific buffer count has been set.
136 * The libsync fence file descriptor returned in the int pointed to by the
137 * fenceFd argument will refer to the fence that must signal before the
138 * dequeued buffer may be written to. A value of -1 indicates that the
139 * caller may access the buffer immediately without waiting on a fence. If
140 * a valid file descriptor is returned (i.e. any value except -1) then the
141 * caller is responsible for closing the file descriptor.
143 * Returns 0 on success or -errno on error.
145 int HWComposerNativeWindow::dequeueBuffer(BaseNativeWindowBuffer
** buffer
, int *fenceFd
)
147 HYBRIS_TRACE_BEGIN("hwcomposer-platform", "dequeueBuffer", "");
149 HWComposerNativeWindowBuffer
* fbnb
=NULL
;
151 pthread_mutex_lock(&_mutex
);
153 HYBRIS_TRACE_BEGIN("hwcomposer-platform", "dequeueBuffer-wait", "");
157 TRACE("Status: Has front buf %p", m_frontBuf
);
159 std::list
<HWComposerNativeWindowBuffer
*>::iterator cit
= m_bufList
.begin();
160 for (; cit
!= m_bufList
.end(); ++cit
)
162 TRACE("Status: Buffer %p with busy %i\n", (*cit
), (*cit
)->busy
);
167 while (m_freeBufs
==0)
169 pthread_cond_wait(&_cond
, &_mutex
);
174 std::list
<HWComposerNativeWindowBuffer
*>::iterator it
= m_bufList
.begin();
175 for (; it
!= m_bufList
.end(); ++it
)
181 TRACE("Found a free non-front buffer");
185 if (it
== m_bufList
.end())
187 // have to wait once again
188 pthread_cond_wait(&_cond
, &_mutex
);
195 HYBRIS_TRACE_END("hwcomposer-platform", "dequeueBuffer-wait", "");
204 TRACE("%lu DONE --> %p", pthread_self(), fbnb
);
205 pthread_mutex_unlock(&_mutex
);
206 HYBRIS_TRACE_END("hwcomposer-platform", "dequeueBuffer", "");
212 * Hook called by EGL when modifications to the render buffer are done.
213 * This unlocks and post the buffer.
215 * The window holds a reference to the buffer between dequeueBuffer and
216 * either queueBuffer or cancelBuffer, so clients only need their own
217 * reference if they might use the buffer after queueing or canceling it.
218 * Holding a reference to a buffer after queueing or canceling it is only
219 * allowed if a specific buffer count has been set.
221 * The fenceFd argument specifies a libsync fence file descriptor for a
222 * fence that must signal before the buffer can be accessed. If the buffer
223 * can be accessed immediately then a value of -1 should be used. The
224 * caller must not use the file descriptor after it is passed to
225 * queueBuffer, and the ANativeWindow implementation is responsible for
228 * Returns 0 on success or -errno on error.
230 int HWComposerNativeWindow::queueBuffer(BaseNativeWindowBuffer
* buffer
, int fenceFd
)
232 TRACE("%lu %d", pthread_self(), fenceFd
);
233 HWComposerNativeWindowBuffer
* fbnb
= (HWComposerNativeWindowBuffer
*) buffer
;
235 HYBRIS_TRACE_BEGIN("hwcomposer-platform", "queueBuffer", "-%p", fbnb
);
236 fbnb
->fenceFd
= fenceFd
;
238 pthread_mutex_lock(&_mutex
);
240 /* Front buffer hasn't yet been picked up for posting */
241 while (m_frontBuf
&& m_frontBuf
->busy
>= 2)
243 pthread_cond_wait(&_cond
, &_mutex
);
246 assert(fbnb
->busy
==1);
251 sync_wait(fenceFd
, -1);
254 pthread_cond_signal(&_cond
);
256 TRACE("%lu %p %p",pthread_self(), m_frontBuf
, fbnb
);
257 pthread_mutex_unlock(&_mutex
);
258 HYBRIS_TRACE_END("hwcomposer-platform", "queueBuffer", "-%p", fbnb
);
263 void HWComposerNativeWindow::lockFrontBuffer(HWComposerNativeWindowBuffer
**buffer
)
266 HWComposerNativeWindowBuffer
*buf
;
267 pthread_mutex_lock(&_mutex
);
271 pthread_cond_wait(&_cond
, &_mutex
);
274 assert(m_frontBuf
->busy
== 2);
276 m_frontBuf
->busy
= 3;
278 pthread_mutex_unlock(&_mutex
);
285 void HWComposerNativeWindow::unlockFrontBuffer(HWComposerNativeWindowBuffer
*buffer
)
288 pthread_mutex_lock(&_mutex
);
290 assert(buffer
== m_frontBuf
);
291 m_frontBuf
->busy
= 0;
293 pthread_cond_signal(&_cond
);
294 pthread_mutex_unlock(&_mutex
);
300 * Hook used to cancel a buffer that has been dequeued.
301 * No synchronization is performed between dequeue() and cancel(), so
302 * either external synchronization is needed, or these functions must be
303 * called from the same thread.
305 * The window holds a reference to the buffer between dequeueBuffer and
306 * either queueBuffer or cancelBuffer, so clients only need their own
307 * reference if they might use the buffer after queueing or canceling it.
308 * Holding a reference to a buffer after queueing or canceling it is only
309 * allowed if a specific buffer count has been set.
311 * The fenceFd argument specifies a libsync fence file decsriptor for a
312 * fence that must signal before the buffer can be accessed. If the buffer
313 * can be accessed immediately then a value of -1 should be used.
315 * Note that if the client has not waited on the fence that was returned
316 * from dequeueBuffer, that same fence should be passed to cancelBuffer to
317 * ensure that future uses of the buffer are preceded by a wait on that
318 * fence. The caller must not use the file descriptor after it is passed
319 * to cancelBuffer, and the ANativeWindow implementation is responsible for
322 * Returns 0 on success or -errno on error.
324 int HWComposerNativeWindow::cancelBuffer(BaseNativeWindowBuffer
* buffer
, int fenceFd
)
327 HWComposerNativeWindowBuffer
* fbnb
= (HWComposerNativeWindowBuffer
*)buffer
;
329 pthread_mutex_lock(&_mutex
);
335 pthread_cond_signal(&_cond
);
336 pthread_mutex_unlock(&_mutex
);
343 int HWComposerNativeWindow::lockBuffer(BaseNativeWindowBuffer
* buffer
)
345 TRACE("%lu STUB", pthread_self());
351 * see NATIVE_WINDOW_FORMAT
353 unsigned int HWComposerNativeWindow::width() const
355 unsigned int rv
= m_width
;
356 TRACE("width=%i", rv
);
362 * see NATIVE_WINDOW_HEIGHT
364 unsigned int HWComposerNativeWindow::height() const
366 unsigned int rv
= m_height
;
367 TRACE("height=%i", rv
);
373 * see NATIVE_WINDOW_FORMAT
375 unsigned int HWComposerNativeWindow::format() const
377 unsigned int rv
= m_bufFormat
;
378 TRACE("format=x%x", rv
);
384 * Default width and height of ANativeWindow buffers, these are the
385 * dimensions of the window buffers irrespective of the
386 * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS call and match the native window
387 * size unless overridden by NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS.
390 * see NATIVE_WINDOW_DEFAULT_HEIGHT
392 unsigned int HWComposerNativeWindow::defaultHeight() const
394 unsigned int rv
= m_height
;
395 TRACE("height=%i", rv
);
401 * see BaseNativeWindow::_query(NATIVE_WINDOW_DEFAULT_WIDTH)
403 unsigned int HWComposerNativeWindow::defaultWidth() const
405 unsigned int rv
= m_width
;
406 TRACE("width=%i", rv
);
412 * see NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER
414 unsigned int HWComposerNativeWindow::queueLength() const
422 * see NATIVE_WINDOW_CONCRETE_TYPE
424 unsigned int HWComposerNativeWindow::type() const
427 return NATIVE_WINDOW_FRAMEBUFFER
;
432 * see NATIVE_WINDOW_TRANSFORM_HINT
434 unsigned int HWComposerNativeWindow::transformHint() const
443 * native_window_set_usage(..., usage)
444 * Sets the intended usage flags for the next buffers
445 * acquired with (*lockBuffer)() and on.
446 * By default (if this function is never called), a usage of
447 * GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
449 * Calling this function will usually cause following buffers to be
452 int HWComposerNativeWindow::setUsage(int usage
)
454 int need_realloc
= (m_usage
!= usage
);
455 TRACE("usage=x%x realloc=%d", usage
, need_realloc
);
458 this->setBufferCount(m_bufList
.size());
465 * native_window_set_buffers_format(..., int format)
466 * All buffers dequeued after this call will have the format specified.
468 * If the specified format is 0, the default buffer format will be used.
470 int HWComposerNativeWindow::setBuffersFormat(int format
)
472 int need_realloc
= (format
!= m_bufFormat
);
473 TRACE("format=x%x realloc=%d", format
, need_realloc
);
474 m_bufFormat
= format
;
476 this->setBufferCount(m_bufList
.size());
482 * native_window_set_buffer_count(..., count)
483 * Sets the number of buffers associated with this native window.
485 int HWComposerNativeWindow::setBufferCount(int cnt
)
487 TRACE("cnt=%d", cnt
);
489 pthread_mutex_lock(&_mutex
);
493 for(unsigned int i
= 0; i
< cnt
; i
++)
495 HWComposerNativeWindowBuffer
*fbnb
= new HWComposerNativeWindowBuffer(m_alloc
,
496 m_width
, m_height
, m_bufFormat
,
497 m_usage
|GRALLOC_USAGE_HW_COMPOSER
);
499 fbnb
->common
.incRef(&fbnb
->common
);
501 TRACE("buffer %i is at %p (native %p),err=%s, handle=%p stride=%i",
502 i
, fbnb
, (ANativeWindowBuffer
*)fbnb
,
503 strerror(-fbnb
->status
), fbnb
->handle
, fbnb
->stride
);
507 fbnb
->common
.decRef(&fbnb
->common
);
508 fprintf(stderr
,"WARNING: %s: allocated only %d buffers out of %d\n", __PRETTY_FUNCTION__
, m_freeBufs
, cnt
);
513 m_bufList
.push_back(fbnb
);
515 pthread_mutex_unlock(&_mutex
);
521 * native_window_set_buffers_dimensions(..., int w, int h)
522 * All buffers dequeued after this call will have the dimensions specified.
523 * In particular, all buffers will have a fixed-size, independent from the
524 * native-window size. They will be scaled according to the scaling mode
525 * (see native_window_set_scaling_mode) upon window composition.
527 * If w and h are 0, the normal behavior is restored. That is, dequeued buffers
528 * following this call will be sized to match the window's size.
530 * Calling this function will reset the window crop to a NULL value, which
531 * disables cropping of the buffers.
533 int HWComposerNativeWindow::setBuffersDimensions(int width
, int height
)
535 TRACE("WARN: stub. size=%ix%i", width
, height
);
538 // vim: noai:ts=4:sw=4:ss=4:expandtab