yagl_resource_release(&ctx->res);
}
}
+
+void yagl_context_finish(struct yagl_context *ctx)
+{
+ yagl_display_finalize_images(ctx->dpy);
+}
*/
void yagl_context_release(struct yagl_context *ctx);
+void yagl_context_finish(struct yagl_context *ctx);
+
#endif
#include "yagl_fence.h"
#include "yagl_native_display.h"
#include "yagl_native_platform.h"
+#include "yagl_client_image.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
return 0;
}
+void yagl_display_finalize_images(struct yagl_display *dpy)
+{
+ struct yagl_resource *res;
+
+ pthread_mutex_lock(&dpy->mutex);
+
+ yagl_list_for_each(struct yagl_resource, res, &dpy->images, list) {
+ struct yagl_image *image = (struct yagl_image *)res;
+ int need_finalize;
+
+ yagl_image_acquire(image);
+
+ yagl_client_image_acquire(image->client_image);
+ need_finalize = image->client_image->need_finalize;
+ image->client_image->need_finalize = 0;
+ yagl_client_image_release(image->client_image);
+
+ if (need_finalize && image->finalize) {
+ image->finalize(image);
+ }
+
+ yagl_image_release(image);
+ }
+
+ pthread_mutex_unlock(&dpy->mutex);
+}
+
void yagl_display_fence_add(struct yagl_display *dpy,
struct yagl_fence *fence)
{
int yagl_display_image_remove(struct yagl_display *dpy,
EGLImageKHR handle);
+void yagl_display_finalize_images(struct yagl_display *dpy);
/*
* @}
*/
struct yagl_client_image *client_image;
void (*update)(struct yagl_image */*image*/);
+
+ void (*finalize)(struct yagl_image */*image*/);
};
void yagl_image_init(struct yagl_image *image,
return (0xff000000 | (r << 16) | (g << 8) | b);
}
+static inline uint32_t argb2xbgr(uint32_t argb)
+{
+ uint32_t r = (argb & 0xff0000) >> 16;
+ uint32_t g = (argb & 0xff00) >> 8;
+ uint32_t b = (argb & 0xff);
+
+ return (0xff000000) | (b << 16) | (g << 8) | (r);
+}
+
static bool yagl_onscreen_image_tizen_sfc_convert(struct yagl_onscreen_image_tizen_sfc *image)
{
uint32_t *dst;
return true;
}
+static bool yagl_onscreen_image_tizen_sfc_convert_back(struct yagl_onscreen_image_tizen_sfc *image)
+{
+ uint32_t *dst;
+ int i, j;
+ tbm_surface_info_s info;
+ int ret;
+
+ YAGL_LOG_FUNC_SET(yagl_onscreen_image_tizen_sfc_convert_back);
+
+ ret = tbm_surface_map(image->sfc, TBM_SURF_OPTION_WRITE, &info);
+
+ if (ret != TBM_SURFACE_ERROR_NONE) {
+ YAGL_LOG_ERROR("tbm_surface_map failed: %d", ret);
+ return false;
+ }
+
+ ret = vigs_drm_surface_start_access(image->drm_sfc, VIGS_DRM_SAF_READ);
+
+ if (ret) {
+ YAGL_LOG_ERROR("vigs_drm_surface_start_access failed: %s", strerror(-ret));
+ tbm_surface_unmap(image->sfc);
+ return false;
+ }
+
+ dst = image->drm_sfc->gem.vaddr;
+ dst += info.width * info.height - info.width;
+
+ switch (info.format) {
+ case TBM_FORMAT_XBGR8888:
+ for (i = 0; i < info.height; i++) {
+ for (j = 0; j < info.width; j++) {
+ uint32_t argb = *(dst - i * info.width + j);
+ ((uint32_t *)info.planes[0].ptr)[i * info.width + j] = argb2xbgr(argb);
+ }
+ }
+
+ YAGL_LOG_ERROR("cpu converting: %p[0] = 0x%x", info.planes[0].ptr,
+ ((uint32_t *)info.planes[0].ptr)[0]);
+
+ break;
+ }
+
+ ret = vigs_drm_surface_end_access(image->drm_sfc, 1);
+
+ if (ret) {
+ YAGL_LOG_ERROR("vigs_drm_surface_end_access failed: %s", strerror(-ret));
+ return false;
+ }
+
+ tbm_surface_unmap(image->sfc);
+
+ return true;
+}
+
static void yagl_onscreen_image_tizen_sfc_update(struct yagl_image *image)
{
struct yagl_onscreen_image_tizen_sfc *tizen_sfc_image =
yagl_onscreen_image_tizen_sfc_convert(tizen_sfc_image);
}
+static void yagl_onscreen_image_tizen_sfc_finalize(struct yagl_image *image)
+{
+ struct yagl_onscreen_image_tizen_sfc *tizen_sfc_image =
+ (struct yagl_onscreen_image_tizen_sfc *)image;
+
+ tbm_bo bo;
+ struct vigs_drm_surface *dst;
+ int ret;
+
+ YAGL_LOG_FUNC_SET(yagl_onscreen_image_tizen_sfc_finalize);
+
+ vigs_drm_surface_set_gpu_dirty(tizen_sfc_image->drm_sfc);
+
+ if (!tizen_sfc_image->need_convert_back) {
+ return;
+ }
+
+ switch (tizen_sfc_image->format) {
+ case TBM_FORMAT_XBGR8888:
+ bo = tbm_surface_internal_get_bo(tizen_sfc_image->sfc, 0);
+ dst = bo ? (struct vigs_drm_surface *)tbm_bo_get_handle(bo, TBM_DEVICE_3D).ptr : NULL;
+
+ ret = vigs_drm_surface_convert(tizen_sfc_image->drm_sfc,
+ DRM_FORMAT_ARGB8888,
+ dst,
+ DRM_FORMAT_XBGR8888,
+ true);
+
+ if (ret == 0) {
+ return;
+ }
+
+ YAGL_LOG_ERROR("vigs_drm_surface_convert failed %s\n", strerror(-ret));
+
+ break;
+ }
+
+ yagl_onscreen_image_tizen_sfc_convert_back(tizen_sfc_image);
+}
+
static void yagl_onscreen_image_tizen_sfc_destroy(struct yagl_ref *ref)
{
struct yagl_onscreen_image_tizen_sfc *image = (struct yagl_onscreen_image_tizen_sfc *)ref;
tbm_bo bo;
tbm_surface_info_s info;
bool need_convert;
+ bool need_convert_back;
int ret;
YAGL_LOG_FUNC_SET(yagl_onscreen_image_tizen_sfc_create);
case TBM_FORMAT_RGB888:
case TBM_FORMAT_XRGB8888:
need_convert = false;
+ need_convert_back = false;
break;
case TBM_FORMAT_ARGB8888:
case TBM_FORMAT_RGBA8888:
case TBM_FORMAT_NV21:
case TBM_FORMAT_YUV420:
need_convert = true;
+ need_convert_back = false;
+ break;
+ case TBM_FORMAT_XBGR8888:
+ need_convert = true;
+ need_convert_back = true;
break;
default:
YAGL_LOG_ERROR("bad format: 0x%X", info.format);
yagl_client_image_release(client_image);
image->base.update = &yagl_onscreen_image_tizen_sfc_update;
+ image->base.finalize = &yagl_onscreen_image_tizen_sfc_finalize;
image->sfc = sfc;
image->need_convert = need_convert;
+ image->need_convert_back = need_convert_back;
image->drm_sfc = drm_sfc;
image->format = info.format;
bool need_convert;
+ bool need_convert_back;
+
struct vigs_drm_surface *drm_sfc;
uint32_t format;
void yagl_render_finish()
{
struct yagl_surface *draw_sfc = yagl_get_draw_surface();
+ struct yagl_context *ctx = yagl_get_context();
if (draw_sfc) {
draw_sfc->wait_gl(draw_sfc);
*/
yagl_transport_flush(yagl_get_transport(), NULL);
}
+
+ yagl_context_finish(ctx);
}
yagl_host_glBindFramebuffer(target, fb->global_name);
fb->was_bound = 1;
+
+ fb->target = target;
}
int yagl_gles_framebuffer_was_bound(struct yagl_gles_framebuffer *fb)
GLenum read_buffer;
int was_bound;
+
+ GLenum target;
};
int yagl_gles_framebuffer_attachment_internalformat(struct yagl_gles_framebuffer_attachment_state *attachment_state,
#include "yagl_gles_texture_unit.h"
#include "yagl_gles_vertex_array.h"
#include "yagl_gles_utils.h"
+#include "yagl_gles_framebuffer.h"
+#include "yagl_gles_image.h"
#include "yagl_log.h"
#include "yagl_malloc.h"
#include "yagl_state.h"
return 1;
}
+static void yagl_gles2_context_prepare_framebuffer(struct yagl_gles2_context *ctx,
+ struct yagl_gles_framebuffer *fb)
+{
+ int i = 0;
+ struct yagl_gles_framebuffer_attachment_state state;
+
+ if (fb == NULL) {
+ return;
+ }
+
+ yagl_gles_framebuffer_acquire(fb);
+
+ /*
+ * Currently we don't support depth and stencil attachments for
+ * texture images
+ */
+
+ for (i = 0; i < YAGL_MAX_GLES_FRAMEBUFFER_COLOR_ATTACHMENTS; i++) {
+ state = fb->attachment_states[yagl_gles_framebuffer_attachment_color0 + i];
+
+ if (state.type == GL_TEXTURE && state.texture) {
+ yagl_gles_texture_acquire(state.texture);
+
+ if (state.texture->image) {
+ yagl_gles_image_acquire(state.texture->image);
+ state.texture->image->base.need_finalize = 1;
+ yagl_gles_image_release(state.texture->image);
+
+ yagl_gles_framebuffer_texture2d(fb,
+ fb->target,
+ GL_COLOR_ATTACHMENT0 + i,
+ yagl_gles_framebuffer_attachment_color0,
+ state.textarget,
+ 0,
+ state.texture);
+ }
+
+ yagl_gles_texture_release(state.texture);
+ }
+ }
+
+ yagl_gles_framebuffer_release(fb);
+}
+
void yagl_gles2_context_init(struct yagl_gles2_context *ctx,
yagl_client_api client_api,
struct yagl_sharegroup *sg)
{
YAGL_LOG_FUNC_SET(yagl_gles2_context_pre_draw);
+ yagl_gles2_context_prepare_framebuffer(ctx, ctx->base.fbo_draw);
+
/*
* 'count' can be <= 0 in case of integer overflows, this is
* typically user problem, just don't simulate vertex attribute array 0
{
struct yagl_object base;
+ int need_finalize;
+
void (*update)(struct yagl_client_image */*image*/,
uint32_t /*width*/,
uint32_t /*height*/,