Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / state_tracker / st_cb_bitmap.c
index 3a102df67f1f1541bd22d91ff11f6e151c7839db..694104f9cfb10734406b030c8d8a1a1cd07ae02c 100644 (file)
@@ -50,7 +50,7 @@
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
 #include "pipe/p_inlines.h"
-#include "util/p_tile.h"
+#include "util/u_tile.h"
 #include "util/u_draw_quad.h"
 #include "util/u_simple_shaders.h"
 #include "shader/prog_instruction.h"
@@ -90,6 +90,8 @@ struct bitmap_cache
    /** Bounds of region used in window coords */
    GLint xmin, ymin, xmax, ymax;
 
+   GLfloat color[4];
+
    struct pipe_texture *texture;
    struct pipe_surface *surf;
 
@@ -339,9 +341,9 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
    dest = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_WRITE);
 
    /* Put image into texture surface */
-   memset(dest, 0xff, height * surface->pitch);
+   memset(dest, 0xff, height * surface->stride);
    unpack_bitmap(ctx->st, 0, 0, width, height, unpack, bitmap,
-                 dest, surface->pitch);
+                 dest, surface->stride);
 
    _mesa_unmap_bitmap_pbo(ctx, unpack);
 
@@ -360,23 +362,23 @@ setup_bitmap_vertex_data(struct st_context *st,
 {
    struct pipe_context *pipe = st->pipe;
    const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
-   const GLfloat fb_width = fb->Width;
-   const GLfloat fb_height = fb->Height;
-   const GLfloat x0 = x;
-   const GLfloat x1 = x + width;
-   const GLfloat y0 = y;
-   const GLfloat y1 = y + height;
-   const GLfloat sLeft = 0.0F, sRight = 1.0F;
-   const GLfloat tTop = 0.0, tBot = 1.0 - tTop;
-   const GLfloat clip_x0 = x0 / fb_width * 2.0 - 1.0;
-   const GLfloat clip_y0 = y0 / fb_height * 2.0 - 1.0;
-   const GLfloat clip_x1 = x1 / fb_width * 2.0 - 1.0;
-   const GLfloat clip_y1 = y1 / fb_height * 2.0 - 1.0;
+   const GLfloat fb_width = (GLfloat)fb->Width;
+   const GLfloat fb_height = (GLfloat)fb->Height;
+   const GLfloat x0 = (GLfloat)x;
+   const GLfloat x1 = (GLfloat)(x + width);
+   const GLfloat y0 = (GLfloat)y;
+   const GLfloat y1 = (GLfloat)(y + height);
+   const GLfloat sLeft = (GLfloat)0.0, sRight = (GLfloat)1.0;
+   const GLfloat tTop = (GLfloat)0.0, tBot = (GLfloat)1.0 - tTop;
+   const GLfloat clip_x0 = (GLfloat)(x0 / fb_width * 2.0 - 1.0);
+   const GLfloat clip_y0 = (GLfloat)(y0 / fb_height * 2.0 - 1.0);
+   const GLfloat clip_x1 = (GLfloat)(x1 / fb_width * 2.0 - 1.0);
+   const GLfloat clip_y1 = (GLfloat)(y1 / fb_height * 2.0 - 1.0);
    GLuint i;
    void *buf;
 
    if (!st->bitmap.vbuf) {
-      st->bitmap.vbuf = pipe_buffer_create(pipe, 32, PIPE_BUFFER_USAGE_VERTEX,
+      st->bitmap.vbuf = pipe_buffer_create(pipe->screen, 32, PIPE_BUFFER_USAGE_VERTEX,
                                            sizeof(st->bitmap.vertices));
    }
 
@@ -416,9 +418,9 @@ setup_bitmap_vertex_data(struct st_context *st,
    }
 
    /* put vertex data into vbuf */
-   buf = pipe_buffer_map(pipe, st->bitmap.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
+   buf = pipe_buffer_map(pipe->screen, st->bitmap.vbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
    memcpy(buf, st->bitmap.vertices, sizeof(st->bitmap.vertices));
-   pipe_buffer_unmap(pipe, st->bitmap.vbuf);
+   pipe_buffer_unmap(pipe->screen, st->bitmap.vbuf);
 }
 
 
@@ -429,7 +431,8 @@ setup_bitmap_vertex_data(struct st_context *st,
 static void
 draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
                  GLsizei width, GLsizei height,
-                 struct pipe_texture *pt)
+                 struct pipe_texture *pt,
+                 const GLfloat *color)
 {
    struct st_context *st = ctx->st;
    struct pipe_context *pipe = ctx->st->pipe;
@@ -444,8 +447,8 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
     * it up into chunks.
     */
    maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
-   assert(width <= maxSize);
-   assert(height <= maxSize);
+   assert(width <= (GLsizei)maxSize);
+   assert(height <= (GLsizei)maxSize);
 
    cso_save_rasterizer(cso);
    cso_save_samplers(cso);
@@ -488,24 +491,24 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
    {
       const struct gl_framebuffer *fb = st->ctx->DrawBuffer;
       const GLboolean invert = (st_fb_orientation(fb) == Y_0_TOP);
-      const float width = fb->Width;
-      const float height = fb->Height;
+      const GLfloat width = (GLfloat)fb->Width;
+      const GLfloat height = (GLfloat)fb->Height;
       struct pipe_viewport_state vp;
-      vp.scale[0] =  0.5 * width;
-      vp.scale[1] = height * (invert ? -0.5 : 0.5);
-      vp.scale[2] = 1.0;
-      vp.scale[3] = 1.0;
-      vp.translate[0] = 0.5 * width;
-      vp.translate[1] = 0.5 * height;
-      vp.translate[2] = 0.0;
-      vp.translate[3] = 0.0;
+      vp.scale[0] =  0.5f * width;
+      vp.scale[1] = height * (invert ? -0.5f : 0.5f);
+      vp.scale[2] = 1.0f;
+      vp.scale[3] = 1.0f;
+      vp.translate[0] = 0.5f * width;
+      vp.translate[1] = 0.5f * height;
+      vp.translate[2] = 0.0f;
+      vp.translate[3] = 0.0f;
       cso_set_viewport(cso, &vp);
    }
 
    /* draw textured quad */
    setup_bitmap_vertex_data(st, x, y, width, height,
                             ctx->Current.RasterPos[2],
-                            ctx->Current.RasterColor);
+                            color);
 
    util_draw_vertex_buffer(pipe, st->bitmap.vbuf,
                            PIPE_PRIM_TRIANGLE_FAN,
@@ -538,6 +541,9 @@ reset_cache(struct st_context *st)
    cache->ymin = 1000000;
    cache->ymax = -1000000;
 
+   if (cache->surf)
+      screen->tex_surface_release(screen, &cache->surf);
+
    assert(!cache->texture);
 
    /* allocate a new texture */
@@ -567,8 +573,9 @@ void
 st_flush_bitmap_cache(struct st_context *st)
 {
    if (!st->bitmap.cache->empty) {
+      struct bitmap_cache *cache = st->bitmap.cache;
+
       if (st->ctx->DrawBuffer) {
-         struct bitmap_cache *cache = st->bitmap.cache;
          struct pipe_context *pipe = st->pipe;
          struct pipe_screen *screen = pipe->screen;
 
@@ -584,6 +591,8 @@ st_flush_bitmap_cache(struct st_context *st)
           * So unmap and release the texture surface before drawing.
           */
          screen->surface_unmap(screen, cache->surf);
+         cache->buffer = NULL;
+
          screen->tex_surface_release(screen, &cache->surf);
 
          draw_bitmap_quad(st->ctx,
@@ -591,11 +600,13 @@ st_flush_bitmap_cache(struct st_context *st)
                           cache->ypos,
                           st->ctx->Current.RasterPos[2],
                           BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
-                          cache->texture);
-
-         /* release/free the texture */
-         pipe_texture_reference(&cache->texture, NULL);
+                          cache->texture,
+                          cache->color);
       }
+
+      /* release/free the texture */
+      pipe_texture_reference(&cache->texture, NULL);
+
       reset_cache(st);
    }
 }
@@ -622,8 +633,10 @@ accum_bitmap(struct st_context *st,
       px = x - cache->xpos;  /* pos in buffer */
       py = y - cache->ypos;
       if (px < 0 || px + width > BITMAP_CACHE_WIDTH ||
-          py < 0 || py + height > BITMAP_CACHE_HEIGHT) {
-         /* This bitmap would extend beyond cache bounds,
+          py < 0 || py + height > BITMAP_CACHE_HEIGHT ||
+          !TEST_EQ_4V(st->ctx->Current.RasterColor, cache->color)) {
+         /* This bitmap would extend beyond cache bounds, or the bitmap
+          * color is changing
           * so flush and continue.
           */
          st_flush_bitmap_cache(st);
@@ -637,6 +650,7 @@ accum_bitmap(struct st_context *st,
       cache->xpos = x;
       cache->ypos = y - py;
       cache->empty = GL_FALSE;
+      COPY_4FV(cache->color, st->ctx->Current.RasterColor);
    }
 
    assert(px != -999);
@@ -692,7 +706,8 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
    if (pt) {
       assert(pt->target == PIPE_TEXTURE_2D);
       draw_bitmap_quad(ctx, x, y, ctx->Current.RasterPos[2],
-                       width, height, pt);
+                       width, height, pt,
+                       st->ctx->Current.RasterColor);
       /* release/free the texture */
       pipe_texture_reference(&pt, NULL);
    }
@@ -731,7 +746,8 @@ st_init_bitmap(struct st_context *st)
    st->bitmap.rasterizer.bypass_vs = 1;
 
    /* find a usable texture format */
-   if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, PIPE_TEXTURE)) {
+   if (screen->is_format_supported(screen, PIPE_FORMAT_I8_UNORM, PIPE_TEXTURE_2D, 
+                                   PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
       st->bitmap.tex_format = PIPE_FORMAT_I8_UNORM;
    }
    else {
@@ -763,7 +779,7 @@ st_destroy_bitmap(struct st_context *st)
    }
 
    if (st->bitmap.vbuf) {
-      pipe_buffer_destroy(pipe, st->bitmap.vbuf);
+      pipe_buffer_destroy(pipe->screen, st->bitmap.vbuf);
       st->bitmap.vbuf = NULL;
    }