summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2011-07-31 11:16:53 +0900
committerChia-I Wu <olvaffe@gmail.com>2011-07-31 12:34:04 +0900
commitd63af92bb8557e37f59706043c617ca60458ec2c (patch)
tree36c180142cd19fb7efe1ff121ed29f04611b2e52
parent11ab44baf8187dc7bfb84bfc15f0c92f1d4fe988 (diff)
st/egl: add buffer preserving support to Android
-rw-r--r--src/gallium/state_trackers/egl/android/native_android.cpp70
1 files changed, 66 insertions, 4 deletions
diff --git a/src/gallium/state_trackers/egl/android/native_android.cpp b/src/gallium/state_trackers/egl/android/native_android.cpp
index 1be23e06e7..c4398f16c0 100644
--- a/src/gallium/state_trackers/egl/android/native_android.cpp
+++ b/src/gallium/state_trackers/egl/android/native_android.cpp
@@ -37,6 +37,7 @@ extern "C" {
#include "util/u_memory.h"
#include "util/u_inlines.h"
#include "util/u_format.h"
+#include "util/u_box.h"
#include "common/native.h"
#include "common/native_helper.h"
#include "android/android_sw_winsys.h"
@@ -59,9 +60,11 @@ struct android_surface {
struct android_display *adpy;
android_native_window_t *win;
+ struct pipe_resource *color_res;
+
uint stamp;
android_native_buffer_t *buf;
- struct pipe_resource *res;
+ struct pipe_resource *buf_res;
/* cache the current back buffers */
struct {
@@ -301,7 +304,7 @@ android_surface_dequeue_buffer(struct native_surface *nsurf)
if (!res)
return FALSE;
- pipe_resource_reference(&asurf->res, res);
+ pipe_resource_reference(&asurf->buf_res, res);
return TRUE;
}
@@ -311,7 +314,7 @@ android_surface_enqueue_buffer(struct native_surface *nsurf)
{
struct android_surface *asurf = android_surface(nsurf);
- pipe_resource_reference(&asurf->res, NULL);
+ pipe_resource_reference(&asurf->buf_res, NULL);
asurf->win->queueBuffer(asurf->win, asurf->buf);
@@ -339,17 +342,63 @@ android_surface_swap_buffers(struct native_surface *nsurf)
return TRUE;
}
+static void
+copy_resources(struct native_display *ndpy,
+ struct pipe_resource *src,
+ struct pipe_resource *dst)
+{
+ struct pipe_context *pipe;
+ struct pipe_box box;
+
+ pipe = ndpy_get_copy_context(ndpy);
+ if (!pipe)
+ return;
+
+ u_box_origin_2d(src->width0, src->height0, &box);
+ pipe->resource_copy_region(pipe, dst, 0, 0, 0, 0, src, 0, &box);
+ pipe->flush(pipe, NULL);
+}
+
static boolean
android_surface_present(struct native_surface *nsurf,
enum native_attachment natt,
boolean preserve,
uint swap_interval)
{
+ struct android_surface *asurf = android_surface(nsurf);
+ struct android_display *adpy = asurf->adpy;
boolean ret;
if (swap_interval || natt != NATIVE_ATTACHMENT_BACK_LEFT)
return FALSE;
+ /* we always render to color_res first when it exists */
+ if (asurf->color_res) {
+ copy_resources(&adpy->base, asurf->color_res, asurf->buf_res);
+ if (!preserve)
+ pipe_resource_reference(&asurf->color_res, NULL);
+ }
+ else if (preserve) {
+ struct pipe_resource templ;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = asurf->buf_res->target;
+ templ.format = asurf->buf_res->format;
+ templ.bind = PIPE_BIND_RENDER_TARGET;
+ templ.width0 = asurf->buf_res->width0;
+ templ.height0 = asurf->buf_res->height0;
+ templ.depth0 = asurf->buf_res->depth0;
+ templ.array_size = asurf->buf_res->array_size;
+
+ asurf->color_res =
+ adpy->base.screen->resource_create(adpy->base.screen, &templ);
+ if (!asurf->color_res)
+ return FALSE;
+
+ /* preserve the contents */
+ copy_resources(&adpy->base, asurf->buf_res, asurf->color_res);
+ }
+
return android_surface_swap_buffers(nsurf);
}
@@ -364,6 +413,13 @@ android_surface_validate(struct native_surface *nsurf, uint attachment_mask,
if (!asurf->buf) {
if (!android_surface_dequeue_buffer(&asurf->base))
return FALSE;
+
+ /* color_res must be compatible with buf_res */
+ if (asurf->color_res &&
+ (asurf->color_res->format != asurf->buf_res->format ||
+ asurf->color_res->width0 != asurf->buf_res->width0 ||
+ asurf->color_res->height0 != asurf->buf_res->height0))
+ pipe_resource_reference(&asurf->color_res, NULL);
}
if (textures) {
@@ -371,7 +427,8 @@ android_surface_validate(struct native_surface *nsurf, uint attachment_mask,
if (native_attachment_mask_test(attachment_mask, att)) {
textures[att] = NULL;
- pipe_resource_reference(&textures[att], asurf->res);
+ pipe_resource_reference(&textures[att],
+ (asurf->color_res) ? asurf->color_res : asurf->buf_res);
}
}
@@ -396,6 +453,8 @@ android_surface_destroy(struct native_surface *nsurf)
struct android_surface *asurf = android_surface(nsurf);
int i;
+ pipe_resource_reference(&asurf->color_res, NULL);
+
if (asurf->buf)
android_surface_enqueue_buffer(&asurf->base);
@@ -610,6 +669,9 @@ android_display_get_param(struct native_display *ndpy,
int val;
switch (param) {
+ case NATIVE_PARAM_PRESERVE_BUFFER:
+ val = 1;
+ break;
default:
val = 0;
break;