summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2011-07-31 10:49:52 +0900
committerChia-I Wu <[email protected]>2011-08-21 02:01:50 +0800
commit4c222ff4fea46ee5b740575df4b256fa2064984f (patch)
tree40a9895a8534751cf47329b0008f809256260cd6 /src
parent62c7c2fca423020dc634cad838f53751b9835654 (diff)
st/egl: improve buffer cache for Android
There may be more than two back buffers. Clean up and prepare the buffer cache for that.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/state_trackers/egl/android/native_android.cpp104
1 files changed, 73 insertions, 31 deletions
diff --git a/src/gallium/state_trackers/egl/android/native_android.cpp b/src/gallium/state_trackers/egl/android/native_android.cpp
index ccb71efa030..b9f12dadc41 100644
--- a/src/gallium/state_trackers/egl/android/native_android.cpp
+++ b/src/gallium/state_trackers/egl/android/native_android.cpp
@@ -63,7 +63,12 @@ struct android_surface {
android_native_buffer_t *buf;
struct pipe_resource *res;
- /* cache the current front and back resources */
+ /* cache the current back buffers */
+ struct {
+ int width;
+ int height;
+ int format;
+ } cache_key;
void *cache_handles[2];
struct pipe_resource *cache_resources[2];
};
@@ -194,32 +199,42 @@ import_buffer(struct android_display *adpy, const struct pipe_resource *templ,
return res;
}
-/**
- * Dequeue the next back buffer for rendering.
- */
-static boolean
-android_surface_dequeue_buffer(struct native_surface *nsurf)
+static void
+android_surface_clear_cache(struct native_surface *nsurf)
{
struct android_surface *asurf = android_surface(nsurf);
- void *handle;
- int idx;
+ int i;
- if (asurf->win->dequeueBuffer(asurf->win, &asurf->buf) != NO_ERROR) {
- LOGE("failed to dequeue window %p", asurf->win);
- return FALSE;
+ for (i = 0; i < Elements(asurf->cache_handles); i++) {
+ asurf->cache_handles[i] = NULL;
+ pipe_resource_reference(&asurf->cache_resources[i], NULL);
}
- asurf->buf->common.incRef(&asurf->buf->common);
- asurf->win->lockBuffer(asurf->win, asurf->buf);
+ memset(&asurf->cache_key, 0, sizeof(asurf->cache_key));
+}
+
+static struct pipe_resource *
+android_surface_add_cache(struct native_surface *nsurf,
+ struct android_native_buffer_t *abuf)
+{
+ struct android_surface *asurf = android_surface(nsurf);
+ void *handle;
+ int idx;
+
+ /* how about abuf->usage? */
+ if (asurf->cache_key.width != abuf->width ||
+ asurf->cache_key.height != abuf->height ||
+ asurf->cache_key.format != abuf->format)
+ android_surface_clear_cache(&asurf->base);
if (asurf->adpy->use_drm)
- handle = (void *) get_handle_name(asurf->buf->handle);
+ handle = (void *) get_handle_name(abuf->handle);
else
- handle = (void *) asurf->buf->handle;
+ handle = (void *) abuf->handle;
/* NULL is invalid */
if (!handle) {
- LOGE("window %p returned an invalid buffer", asurf->win);
- return TRUE;
+ LOGE("invalid buffer native buffer %p", abuf);
+ return NULL;
}
/* find the slot to use */
@@ -228,15 +243,18 @@ android_surface_dequeue_buffer(struct native_surface *nsurf)
break;
}
if (idx == Elements(asurf->cache_handles)) {
- /* buffer reallocated; clear the cache */
- for (idx = 0; idx < Elements(asurf->cache_handles); idx++) {
- asurf->cache_handles[idx] = 0;
- pipe_resource_reference(&asurf->cache_resources[idx], NULL);
- }
+ LOGW("cache full: buf %p, width %d, height %d, format %d, usage 0x%x",
+ abuf, abuf->width, abuf->height, abuf->format, abuf->usage);
+ android_surface_clear_cache(&asurf->base);
idx = 0;
}
- /* update the cache */
+ if (idx == 0) {
+ asurf->cache_key.width = abuf->width;
+ asurf->cache_key.height = abuf->height;
+ asurf->cache_key.format = abuf->format;
+ }
+
if (!asurf->cache_handles[idx]) {
struct pipe_resource templ;
@@ -244,17 +262,18 @@ android_surface_dequeue_buffer(struct native_surface *nsurf)
memset(&templ, 0, sizeof(templ));
templ.target = PIPE_TEXTURE_2D;
- templ.last_level = 0;
- templ.width0 = asurf->buf->width;
- templ.height0 = asurf->buf->height;
- templ.depth0 = 1;
+ templ.format = get_pipe_format(asurf->buf->format);
templ.bind = PIPE_BIND_RENDER_TARGET;
if (!asurf->adpy->use_drm) {
templ.bind |= PIPE_BIND_TRANSFER_WRITE |
PIPE_BIND_TRANSFER_READ;
}
- templ.format = get_pipe_format(asurf->buf->format);
+ templ.width0 = asurf->buf->width;
+ templ.height0 = asurf->buf->height;
+ templ.depth0 = 1;
+ templ.array_size = 1;
+
if (templ.format != PIPE_FORMAT_NONE) {
asurf->cache_resources[idx] =
import_buffer(asurf->adpy, &templ, asurf->buf);
@@ -266,7 +285,31 @@ android_surface_dequeue_buffer(struct native_surface *nsurf)
asurf->cache_handles[idx] = handle;
}
- pipe_resource_reference(&asurf->res, asurf->cache_resources[idx]);
+ return asurf->cache_resources[idx];
+}
+
+/**
+ * Dequeue the next back buffer for rendering.
+ */
+static boolean
+android_surface_dequeue_buffer(struct native_surface *nsurf)
+{
+ struct android_surface *asurf = android_surface(nsurf);
+ struct pipe_resource *res;
+
+ if (asurf->win->dequeueBuffer(asurf->win, &asurf->buf) != NO_ERROR) {
+ LOGE("failed to dequeue window %p", asurf->win);
+ return FALSE;
+ }
+
+ asurf->buf->common.incRef(&asurf->buf->common);
+ asurf->win->lockBuffer(asurf->win, asurf->buf);
+
+ res = android_surface_add_cache(&asurf->base, asurf->buf);
+ if (!res)
+ return FALSE;
+
+ pipe_resource_reference(&asurf->res, res);
return TRUE;
}
@@ -368,8 +411,7 @@ android_surface_destroy(struct native_surface *nsurf)
if (asurf->buf)
android_surface_enqueue_buffer(&asurf->base);
- for (i = 0; i < Elements(asurf->cache_handles); i++)
- pipe_resource_reference(&asurf->cache_resources[i], NULL);
+ android_surface_clear_cache(&asurf->base);
asurf->win->common.decRef(&asurf->win->common);