ilo: replace a boolean by bool
[mesa.git] / src / gallium / state_trackers / vega / vg_manager.c
index 9254d7d1cfbf97b71a180a0303ca855688818fe2..c079d90359c0d39f9683a1de65ca02dcde99d02b 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.9
  *
  * Copyright 2009 VMware, Inc.  All Rights Reserved.
  * Copyright (C) 2010 LunarG Inc.
 #include "pipe/p_screen.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_sampler.h"
+#include "util/u_box.h"
+#include "util/u_surface.h"
 
 #include "vg_api.h"
 #include "vg_manager.h"
 #include "vg_context.h"
-#include "image.h"
-#include "mask.h"
 #include "api.h"
-
-static struct pipe_resource *
-create_texture(struct pipe_context *pipe, enum pipe_format format,
-                    VGint width, VGint height)
-{
-   struct pipe_resource templ;
-
-   memset(&templ, 0, sizeof(templ));
-
-   if (format != PIPE_FORMAT_NONE) {
-      templ.format = format;
-   }
-   else {
-      templ.format = PIPE_FORMAT_B8G8R8A8_UNORM;
-   }
-
-   templ.target = PIPE_TEXTURE_2D;
-   templ.width0 = width;
-   templ.height0 = height;
-   templ.depth0 = 1;
-   templ.last_level = 0;
-
-   if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1)) {
-      templ.bind = PIPE_BIND_DEPTH_STENCIL;
-   } else {
-      templ.bind = (PIPE_BIND_DISPLAY_TARGET |
-                    PIPE_BIND_RENDER_TARGET |
-                    PIPE_BIND_SAMPLER_VIEW);
-   }
-
-   return pipe->screen->resource_create(pipe->screen, &templ);
-}
-
-static struct pipe_sampler_view *
-create_tex_and_view(struct pipe_context *pipe, enum pipe_format format,
-                    VGint width, VGint height)
-{
-   struct pipe_resource *texture;
-   struct pipe_sampler_view view_templ;
-   struct pipe_sampler_view *view;
-
-   texture = create_texture(pipe, format, width, height);
-
-   if (!texture)
-      return NULL;
-
-   u_sampler_view_default_template(&view_templ, texture, texture->format);
-   view = pipe->create_sampler_view(pipe, texture, &view_templ);
-   /* want the texture to go away if the view is freed */
-   pipe_resource_reference(&texture, NULL);
-
-   return view;
-}
-
-static void
-vg_context_update_alpha_mask_view(struct vg_context *ctx,
-                                  uint width, uint height)
-{
-   struct st_framebuffer *stfb = ctx->draw_buffer;
-   struct pipe_sampler_view *old_sampler_view = stfb->alpha_mask_view;
-   struct pipe_context *pipe = ctx->pipe;
-
-   if (old_sampler_view &&
-       old_sampler_view->texture->width0 == width &&
-       old_sampler_view->texture->height0 == height)
-      return;
-
-   /*
-     we use PIPE_FORMAT_B8G8R8A8_UNORM because we want to render to
-     this texture and use it as a sampler, so while this wastes some
-     space it makes both of those a lot simpler
-   */
-   stfb->alpha_mask_view = create_tex_and_view(pipe,
-         PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
-
-   if (!stfb->alpha_mask_view) {
-      if (old_sampler_view)
-         pipe_sampler_view_reference(&old_sampler_view, NULL);
-      return;
-   }
-
-   /* XXX could this call be avoided? */
-   vg_validate_state(ctx);
-
-   /* alpha mask starts with 1.f alpha */
-   mask_fill(0, 0, width, height, 1.f);
-
-   /* if we had an old surface copy it over */
-   if (old_sampler_view) {
-      struct pipe_subresource subsurf, subold_surf;
-      subsurf.face = 0;
-      subsurf.level = 0;
-      subold_surf.face = 0;
-      subold_surf.level = 0;
-      pipe->resource_copy_region(pipe,
-                                 stfb->alpha_mask_view->texture,
-                                 subsurf,
-                                 0, 0, 0,
-                                 old_sampler_view->texture,
-                                 subold_surf,
-                                 0, 0, 0,
-                                 MIN2(old_sampler_view->texture->width0,
-                                      stfb->alpha_mask_view->texture->width0),
-                                 MIN2(old_sampler_view->texture->height0,
-                                      stfb->alpha_mask_view->texture->height0));
-   }
-
-   /* Free the old texture
-    */
-   if (old_sampler_view)
-      pipe_sampler_view_reference(&old_sampler_view, NULL);
-}
-
-static void
-vg_context_update_blend_texture_view(struct vg_context *ctx,
-                                     uint width, uint height)
-{
-   struct pipe_context *pipe = ctx->pipe;
-   struct st_framebuffer *stfb = ctx->draw_buffer;
-   struct pipe_sampler_view *old = stfb->blend_texture_view;
-
-   if (old &&
-       old->texture->width0 == width &&
-       old->texture->height0 == height)
-      return;
-
-   stfb->blend_texture_view = create_tex_and_view(pipe,
-         PIPE_FORMAT_B8G8R8A8_UNORM, width, height);
-
-   pipe_sampler_view_reference(&old, NULL);
-}
-
-static boolean
-vg_context_update_depth_stencil_rb(struct vg_context * ctx,
-                                   uint width, uint height)
-{
-   struct st_renderbuffer *dsrb = ctx->draw_buffer->dsrb;
-   struct pipe_context *pipe = ctx->pipe;
-   unsigned surface_usage;
-
-   if ((dsrb->width == width && dsrb->height == height) && dsrb->texture)
-      return FALSE;
-
-   /* unreference existing ones */
-   pipe_surface_reference(&dsrb->surface, NULL);
-   pipe_resource_reference(&dsrb->texture, NULL);
-   dsrb->width = dsrb->height = 0;
-
-   /* Probably need dedicated flags for surface usage too:
-    */
-   surface_usage = PIPE_BIND_DEPTH_STENCIL; /* XXX: was: RENDER_TARGET */
-
-   dsrb->texture = create_texture(pipe, dsrb->format, width, height);
-   if (!dsrb->texture)
-      return TRUE;
-
-   dsrb->surface = pipe->screen->get_tex_surface(pipe->screen,
-                                                 dsrb->texture,
-                                                 0, 0, 0,
-                                                 surface_usage);
-   if (!dsrb->surface) {
-      pipe_resource_reference(&dsrb->texture, NULL);
-      return TRUE;
-   }
-
-   dsrb->width = width;
-   dsrb->height = height;
-
-   assert(dsrb->surface->width == width);
-   assert(dsrb->surface->height == height);
-
-   return TRUE;
-}
+#include "handle.h"
 
 static boolean
 vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
 {
    struct st_renderbuffer *strb = ctx->draw_buffer->strb;
-   struct pipe_screen *screen = ctx->pipe->screen;
+   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_surface surf_tmpl;
 
    if (strb->texture == pt) {
       pipe_resource_reference(&pt, NULL);
@@ -233,8 +59,10 @@ vg_context_update_color_rb(struct vg_context *ctx, struct pipe_resource *pt)
    strb->width = strb->height = 0;
 
    strb->texture = pt;
-   strb->surface = screen->get_tex_surface(screen, strb->texture, 0, 0, 0,
-                                           PIPE_BIND_RENDER_TARGET);
+
+   u_surface_default_template(&surf_tmpl, strb->texture);
+   strb->surface = pipe->create_surface(pipe, strb->texture, &surf_tmpl);
+
    if (!strb->surface) {
       pipe_resource_reference(&strb->texture, NULL);
       return TRUE;
@@ -260,7 +88,7 @@ vg_manager_flush_frontbuffer(struct vg_context *ctx)
    switch (stfb->strb_att) {
    case ST_ATTACHMENT_FRONT_LEFT:
    case ST_ATTACHMENT_FRONT_RIGHT:
-      stfb->iface->flush_front(stfb->iface, stfb->strb_att);
+      stfb->iface->flush_front(&ctx->iface, stfb->iface, stfb->strb_att);
       break;
    default:
       break;
@@ -275,42 +103,38 @@ vg_manager_validate_framebuffer(struct vg_context *ctx)
 {
    struct st_framebuffer *stfb = ctx->draw_buffer;
    struct pipe_resource *pt;
+   int32_t new_stamp;
 
    /* no binding surface */
    if (!stfb)
       return;
 
-   if (!p_atomic_read(&ctx->draw_buffer_invalid))
-      return;
+   new_stamp = p_atomic_read(&stfb->iface->stamp);
+   if (stfb->iface_stamp != new_stamp) {
+      do {
+        /* validate the fb */
+        if (!stfb->iface->validate(stfb->iface, &stfb->strb_att,
+                                   1, &pt) || !pt)
+           return;
 
-   /* validate the fb */
-   if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt)
-      return;
-
-   p_atomic_set(&ctx->draw_buffer_invalid, FALSE);
-
-   if (vg_context_update_color_rb(ctx, pt) ||
-       stfb->width != pt->width0 ||
-       stfb->height != pt->height0)
-      ctx->state.dirty |= FRAMEBUFFER_DIRTY;
+        stfb->iface_stamp = new_stamp;
+        new_stamp = p_atomic_read(&stfb->iface->stamp);
 
-   if (vg_context_update_depth_stencil_rb(ctx, pt->width0, pt->height0))
-      ctx->state.dirty |= DEPTH_STENCIL_DIRTY;
+      } while (stfb->iface_stamp != new_stamp);
 
-   stfb->width = pt->width0;
-   stfb->height = pt->height0;
+      if (vg_context_update_color_rb(ctx, pt) ||
+          stfb->width != pt->width0 ||
+          stfb->height != pt->height0)
+         ++stfb->stamp;
 
-   /* TODO create as needed */
-   vg_context_update_alpha_mask_view(ctx, stfb->width, stfb->height);
-   vg_context_update_blend_texture_view(ctx, stfb->width, stfb->height);
-}
+      stfb->width = pt->width0;
+      stfb->height = pt->height0;
+   }
 
-static void
-vg_context_notify_invalid_framebuffer(struct st_context_iface *stctxi,
-                                      struct st_framebuffer_iface *stfbi)
-{
-   struct vg_context *ctx = (struct vg_context *) stctxi;
-   p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
+   if (ctx->draw_stamp != stfb->stamp) {
+      ctx->state.dirty |= FRAMEBUFFER_DIRTY;
+      ctx->draw_stamp = stfb->stamp;
+   }
 }
 
 static void
@@ -318,8 +142,14 @@ vg_context_flush(struct st_context_iface *stctxi, unsigned flags,
                  struct pipe_fence_handle **fence)
 {
    struct vg_context *ctx = (struct vg_context *) stctxi;
-   ctx->pipe->flush(ctx->pipe, flags, fence);
-   if (flags & PIPE_FLUSH_RENDER_CACHE)
+   unsigned pipe_flags = 0;
+
+   if (flags & ST_FLUSH_END_OF_FRAME) {
+      pipe_flags |= PIPE_FLUSH_END_OF_FRAME;
+   }
+
+   ctx->pipe->flush(ctx->pipe, fence, pipe_flags);
+   if (flags & ST_FLUSH_FRONT)
       vg_manager_flush_frontbuffer(ctx);
 }
 
@@ -327,38 +157,50 @@ static void
 vg_context_destroy(struct st_context_iface *stctxi)
 {
    struct vg_context *ctx = (struct vg_context *) stctxi;
+   struct pipe_context *pipe = ctx->pipe;
+
    vg_destroy_context(ctx);
+   pipe->destroy(pipe);
 }
 
 static struct st_context_iface *
 vg_api_create_context(struct st_api *stapi, struct st_manager *smapi,
                       const struct st_context_attribs *attribs,
+                      enum st_context_error *error,
                       struct st_context_iface *shared_stctxi)
 {
    struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi;
    struct vg_context *ctx;
    struct pipe_context *pipe;
 
-   if (!(stapi->profile_mask & (1 << attribs->profile)))
+   if (!(stapi->profile_mask & (1 << attribs->profile))) {
+      *error = ST_CONTEXT_ERROR_BAD_API;
       return NULL;
+   }
 
    /* only 1.0 is supported */
-   if (attribs->major > 1 || (attribs->major == 1 && attribs->minor > 0))
+   if (attribs->major > 1 || (attribs->major == 1 && attribs->minor > 0)) {
+      *error = ST_CONTEXT_ERROR_BAD_VERSION;
       return NULL;
+   }
+
+   /* for VGHandle / pointer lookups */
+   init_handles();
 
    pipe = smapi->screen->context_create(smapi->screen, NULL);
-   if (!pipe)
+   if (!pipe) {
+      *error = ST_CONTEXT_ERROR_NO_MEMORY;
       return NULL;
+   }
    ctx = vg_create_context(pipe, NULL, shared_ctx);
    if (!ctx) {
       pipe->destroy(pipe);
+      *error = ST_CONTEXT_ERROR_NO_MEMORY;
       return NULL;
    }
 
    ctx->iface.destroy = vg_context_destroy;
 
-   ctx->iface.notify_invalid_framebuffer =
-      vg_context_notify_invalid_framebuffer;
    ctx->iface.flush = vg_context_flush;
 
    ctx->iface.teximage = NULL;
@@ -436,8 +278,6 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
    if (stdrawi != streadi)
       return FALSE;
 
-   p_atomic_set(&ctx->draw_buffer_invalid, TRUE);
-
    strb_att = (stdrawi) ? choose_attachment(stdrawi) : ST_ATTACHMENT_INVALID;
 
    if (ctx->draw_buffer) {
@@ -483,11 +323,14 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
       stfb->width = 0;
       stfb->height = 0;
       stfb->strb_att = strb_att;
+      stfb->stamp = 1;
+      stfb->iface_stamp = p_atomic_read(&stdrawi->stamp) - 1;
 
       ctx->draw_buffer = stfb;
    }
 
    ctx->draw_buffer->iface = stdrawi;
+   ctx->draw_stamp = ctx->draw_buffer->stamp - 1;
 
    return TRUE;
 }
@@ -526,9 +369,10 @@ vg_api_destroy(struct st_api *stapi)
 }
 
 static const struct st_api vg_api = {
-   "Vega " VEGA_VERSION_STRING,
+   "Vega " PACKAGE_VERSION,
    ST_API_OPENVG,
    ST_PROFILE_DEFAULT_MASK,
+   0,
    vg_api_destroy,
    vg_api_get_proc_address,
    vg_api_create_context,