Beispiel #1
0
static GLboolean
dri_make_current(__DRIcontext * cPriv,
		 __DRIdrawable * driDrawPriv,
		 __DRIdrawable * driReadPriv)
{
    struct gl_context *mesaCtx;
    struct gl_framebuffer *mesaDraw;
    struct gl_framebuffer *mesaRead;
    TRACE;

    if (cPriv) {
	struct dri_context *ctx = dri_context(cPriv);
	struct dri_drawable *draw;
	struct dri_drawable *read;

	if (!driDrawPriv || !driReadPriv)
	    return GL_FALSE;

	draw = dri_drawable(driDrawPriv);
	read = dri_drawable(driReadPriv);
	mesaCtx = &ctx->Base;
	mesaDraw = &draw->Base;
	mesaRead = &read->Base;

	/* check for same context and buffer */
	if (mesaCtx == _mesa_get_current_context()
	    && mesaCtx->DrawBuffer == mesaDraw
	    && mesaCtx->ReadBuffer == mesaRead) {
	    return GL_TRUE;
	}

	_glapi_check_multithread();

	swrast_check_and_update_window_size(mesaCtx, mesaDraw);
	if (mesaRead != mesaDraw)
	    swrast_check_and_update_window_size(mesaCtx, mesaRead);

	_mesa_make_current( mesaCtx,
			    mesaDraw,
			    mesaRead );
    }
    else {
	/* unbind */
	_mesa_make_current( NULL, NULL, NULL );
    }

    return GL_TRUE;
}
Beispiel #2
0
static void
dri_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
                    int w, int h)
{
    __DRIscreen *sPriv = dPriv->driScreenPriv;
    void *data;
    int iy;
    struct dri_drawable *drawable = dri_drawable(dPriv);
    struct gl_framebuffer *fb;
    struct dri_swrast_renderbuffer *frontrb, *backrb;

    TRACE;

    fb = &drawable->Base;

    frontrb =
	dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
    backrb =
	dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);

    /* check for signle-buffered */
    if (backrb == NULL)
       return;

    iy = frontrb->Base.Base.Height - y - h;
    data = (char *)backrb->Base.Buffer + (iy * backrb->pitch) + (x * ((backrb->bpp + 7) / 8));
    sPriv->swrast_loader->putImage2(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
                                    x, iy, w, h,
                                    frontrb->pitch,
                                    data,
                                    dPriv->loaderPrivate);
}
static inline void
drisw_invalidate_drawable(__DRIdrawable *dPriv)
{
   struct dri_drawable *drawable = dri_drawable(dPriv);

   drawable->texture_stamp = dPriv->lastStamp - 1;

   p_atomic_inc(&drawable->base.stamp);
}
Beispiel #4
0
static void
dri2_invalidate_drawable(__DRIdrawable *dPriv)
{
   struct dri_drawable *drawable = dri_drawable(dPriv);

   dri2InvalidateDrawable(dPriv);
   drawable->dPriv->lastStamp = drawable->dPriv->dri2.stamp;

   p_atomic_inc(&drawable->base.stamp);
}
GLboolean
dri_make_current(__DRIcontext * cPriv,
		 __DRIdrawable * driDrawPriv,
		 __DRIdrawable * driReadPriv)
{
   /* dri_util.c ensures cPriv is not null */
   struct dri_context *ctx = dri_context(cPriv);
   struct dri_drawable *draw = dri_drawable(driDrawPriv);
   struct dri_drawable *read = dri_drawable(driReadPriv);
   struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi);

   /* Flush the old context here so we don't have to flush on unbind() */
   if (old_st && old_st != ctx->st)
      old_st->flush(old_st, ST_FLUSH_FRONT, NULL);

   ++ctx->bind_count;

   if (!driDrawPriv && !driReadPriv)
      return ctx->stapi->make_current(ctx->stapi, ctx->st, NULL, NULL);
   else if (!driDrawPriv || !driReadPriv)
      return GL_FALSE;

   if (ctx->dPriv != driDrawPriv) {
      ctx->dPriv = driDrawPriv;
      draw->texture_stamp = driDrawPriv->lastStamp - 1;
   }
   if (ctx->rPriv != driReadPriv) {
      ctx->rPriv = driReadPriv;
      read->texture_stamp = driReadPriv->lastStamp - 1;
   }

   ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base);

   // This is ok to call here. If they are already init, it's a no-op.
   if (draw->textures[ST_ATTACHMENT_BACK_LEFT] && draw->textures[ST_ATTACHMENT_DEPTH_STENCIL]
      && ctx->pp)
         pp_init_fbos(ctx->pp, draw->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
            draw->textures[ST_ATTACHMENT_BACK_LEFT]->height0);

   return GL_TRUE;
}
Beispiel #6
0
static void
dri2_invalidate_drawable(__DRIdrawable *dPriv)
{
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct dri_context *ctx = drawable->context;

   dri2InvalidateDrawable(dPriv);
   drawable->dPriv->lastStamp = *drawable->dPriv->pStamp;

   if (ctx)
      ctx->st->notify_invalid_framebuffer(ctx->st, &drawable->base);
}
static inline void
drisw_present_texture(__DRIdrawable *dPriv,
                      struct pipe_resource *ptex, struct pipe_box *sub_box)
{
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct dri_screen *screen = dri_screen(drawable->sPriv);

   if (swrast_no_present)
      return;

   screen->base.screen->flush_frontbuffer(screen->base.screen, ptex, 0, 0, drawable, sub_box);
}
Beispiel #8
0
/**
 * DRI2 flush extension.
 */
static void
dri2_flush_drawable(__DRIdrawable *dPriv)
{
   struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
   struct dri_drawable *drawable = dri_drawable(dPriv);

   struct pipe_resource *ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];

   if (ctx) {
      if (ptex && ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
         pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);

      ctx->st->flush(ctx->st, 0, NULL);
   }
}
Beispiel #9
0
static void
dri_destroy_buffer(__DRIdrawable * dPriv)
{
    TRACE;

    if (dPriv) {
	struct dri_drawable *drawable = dri_drawable(dPriv);
	struct gl_framebuffer *fb;

	free(drawable->row);

	fb = &drawable->Base;

	fb->DeletePending = GL_TRUE;
	_mesa_reference_framebuffer(&fb, NULL);
    }
}
Beispiel #10
0
void
dri_destroy_buffer(__DRIdrawable * dPriv)
{
   struct dri_drawable *drawable = dri_drawable(dPriv);
   int i;

   pipe_surface_reference(&drawable->drisw_surface, NULL);

   for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
      pipe_resource_reference(&drawable->textures[i], NULL);
   for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
      pipe_resource_reference(&drawable->msaa_textures[i], NULL);

   swap_fences_unref(drawable);

   FREE(drawable);
}
Beispiel #11
0
/**
 * These are used for GLX_EXT_texture_from_pixmap
 */
static void
dri_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
                    GLint format, __DRIdrawable *dPriv)
{
   struct dri_context *ctx = dri_context(pDRICtx);
   struct st_context_iface *st = ctx->st;
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct pipe_resource *pt;

   if (st->thread_finish)
      st->thread_finish(st);

   dri_drawable_validate_att(ctx, drawable, ST_ATTACHMENT_FRONT_LEFT);

   /* Use the pipe resource associated with the X drawable */
   pt = drawable->textures[ST_ATTACHMENT_FRONT_LEFT];

   if (pt) {
      enum pipe_format internal_format = pt->format;

      if (format == __DRI_TEXTURE_FORMAT_RGB)  {
         /* only need to cover the formats recognized by dri_fill_st_visual */
         switch (internal_format) {
         case PIPE_FORMAT_BGRA8888_UNORM:
            internal_format = PIPE_FORMAT_BGRX8888_UNORM;
            break;
         case PIPE_FORMAT_ARGB8888_UNORM:
            internal_format = PIPE_FORMAT_XRGB8888_UNORM;
            break;
         default:
            break;
         }
      }

      drawable->update_tex_buffer(drawable, ctx, pt);

      ctx->st->teximage(ctx->st,
            (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT,
            0, internal_format, pt, FALSE);
   }
}
static void
drisw_swap_buffers(__DRIdrawable *dPriv)
{
   struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct pipe_resource *ptex;

   if (!ctx)
      return;

   ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];

   if (ptex) {
      if (ctx->pp)
         pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);

      ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);

      drisw_copy_to_front(dPriv, ptex);
   }
}
Beispiel #13
0
void
dri_destroy_buffer(__DRIdrawable * dPriv)
{
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct dri_screen *screen = drawable->screen;
   struct st_api *stapi = screen->st_api;
   int i;

   pipe_surface_reference(&drawable->drisw_surface, NULL);

   for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
      pipe_resource_reference(&drawable->textures[i], NULL);
   for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
      pipe_resource_reference(&drawable->msaa_textures[i], NULL);

   swap_fences_unref(drawable);

   /* Notify the st manager that this drawable is no longer valid */
   stapi->destroy_drawable(stapi, &drawable->base);

   FREE(drawable);
}
static void
drisw_copy_sub_buffer(__DRIdrawable *dPriv, int x, int y,
                      int w, int h)
{
   struct dri_context *ctx = dri_get_current(dPriv->driScreenPriv);
   struct dri_drawable *drawable = dri_drawable(dPriv);
   struct pipe_resource *ptex;
   struct pipe_box box;
   if (!ctx)
      return;

   ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT];

   if (ptex) {
      if (ctx->pp && drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL])
         pp_run(ctx->pp, ptex, ptex, drawable->textures[ST_ATTACHMENT_DEPTH_STENCIL]);

      ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL);

      u_box_2d(x, dPriv->h - y - h, w, h, &box);
      drisw_present_texture(dPriv, ptex, &box);
   }
}
Beispiel #15
0
static void
dri_swap_buffers(__DRIdrawable * dPriv)
{
    __DRIscreen *sPriv = dPriv->driScreenPriv;

    GET_CURRENT_CONTEXT(ctx);

    struct dri_drawable *drawable = dri_drawable(dPriv);
    struct gl_framebuffer *fb;
    struct swrast_renderbuffer *frontrb, *backrb;

    TRACE;

    fb = &drawable->Base;

    frontrb =
	swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
    backrb =
	swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);

    /* check for signle-buffered */
    if (backrb == NULL)
	return;

    /* check if swapping currently bound buffer */
    if (ctx && ctx->DrawBuffer == fb) {
	/* flush pending rendering */
	_mesa_notifySwapBuffers(ctx);
    }

    sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
				   0, 0,
				   frontrb->Base.Width,
				   frontrb->Base.Height,
				   backrb->Base.Data,
				   dPriv->loaderPrivate);
}
Beispiel #16
0
/**
 * DRI2 flush extension, the flush_with_flags function.
 *
 * \param context           the context
 * \param drawable          the drawable to flush
 * \param flags             a combination of _DRI2_FLUSH_xxx flags
 * \param throttle_reason   the reason for throttling, 0 = no throttling
 */
void
dri_flush(__DRIcontext *cPriv,
          __DRIdrawable *dPriv,
          unsigned flags,
          enum __DRI2throttleReason reason)
{
   struct dri_context *ctx = dri_context(cPriv);
   struct dri_drawable *drawable = dri_drawable(dPriv);
   unsigned flush_flags;
   boolean swap_msaa_buffers = FALSE;

   if (!ctx) {
      assert(0);
      return;
   }

   if (drawable) {
      /* prevent recursion */
      if (drawable->flushing)
         return;

      drawable->flushing = TRUE;
   }
   else {
      flags &= ~__DRI2_FLUSH_DRAWABLE;
   }

   /* Flush the drawable. */
   if ((flags & __DRI2_FLUSH_DRAWABLE) &&
       drawable->textures[ST_ATTACHMENT_BACK_LEFT]) {
      struct pipe_context *pipe = ctx->st->pipe;

      if (drawable->stvis.samples > 1 &&
          reason == __DRI2_THROTTLE_SWAPBUFFER) {
         /* Resolve the MSAA back buffer. */
         dri_pipe_blit(ctx->st->pipe,
                       drawable->textures[ST_ATTACHMENT_BACK_LEFT],
                       drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]);

         if (drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT] &&
             drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT]) {
            swap_msaa_buffers = TRUE;
         }

         /* FRONT_LEFT is resolved in drawable->flush_frontbuffer. */
      }

      dri_postprocessing(ctx, drawable, ST_ATTACHMENT_BACK_LEFT);

      if (ctx->hud) {
         hud_draw(ctx->hud, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
      }

      pipe->flush_resource(pipe, drawable->textures[ST_ATTACHMENT_BACK_LEFT]);
   }

   flush_flags = 0;
   if (flags & __DRI2_FLUSH_CONTEXT)
      flush_flags |= ST_FLUSH_FRONT;
   if (reason == __DRI2_THROTTLE_SWAPBUFFER)
      flush_flags |= ST_FLUSH_END_OF_FRAME;

   /* Flush the context and throttle if needed. */
   if (dri_screen(ctx->sPriv)->throttling_enabled &&
       drawable &&
       (reason == __DRI2_THROTTLE_SWAPBUFFER ||
        reason == __DRI2_THROTTLE_FLUSHFRONT)) {
      /* Throttle.
       *
       * This pulls a fence off the throttling queue and waits for it if the
       * number of fences on the throttling queue has reached the desired
       * number.
       *
       * Then flushes to insert a fence at the current rendering position, and
       * pushes that fence on the queue. This requires that the st_context_iface
       * flush method returns a fence even if there are no commands to flush.
       */
      struct pipe_screen *screen = drawable->screen->base.screen;
      struct pipe_fence_handle *fence;

      fence = swap_fences_pop_front(drawable);
      if (fence) {
         (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE);
         screen->fence_reference(screen, &fence, NULL);
      }

      ctx->st->flush(ctx->st, flush_flags, &fence);

      if (fence) {
         swap_fences_push_back(drawable, fence);
         screen->fence_reference(screen, &fence, NULL);
      }
   }
   else if (flags & (__DRI2_FLUSH_DRAWABLE | __DRI2_FLUSH_CONTEXT)) {
      ctx->st->flush(ctx->st, flush_flags, NULL);
   }

   if (drawable) {
      drawable->flushing = FALSE;
   }

   /* Swap the MSAA front and back buffers, so that reading
    * from the front buffer after SwapBuffers returns what was
    * in the back buffer.
    */
   if (swap_msaa_buffers) {
      struct pipe_resource *tmp =
         drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT];

      drawable->msaa_textures[ST_ATTACHMENT_FRONT_LEFT] =
         drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT];
      drawable->msaa_textures[ST_ATTACHMENT_BACK_LEFT] = tmp;

      /* Now that we have swapped the buffers, this tells the state
       * tracker to revalidate the framebuffer.
       */
      p_atomic_inc(&drawable->base.stamp);
   }
}