/*
* Mesa 3-D graphics library
- * Version: 6.5.2
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "glheader.h"
-#include "macros.h"
-#include "imports.h"
-#include "colormac.h"
+#include "main/glheader.h"
+#include "main/macros.h"
+#include "main/imports.h"
+#include "main/format_pack.h"
#include "s_context.h"
#include "s_span.h"
* Compute the bounds of the region resulting from zooming a pixel span.
* The resulting region will be entirely inside the window/scissor bounds
* so no additional clipping is needed.
- * \param imageX, imageY position of the overall image being drawn
+ * \param imageX, imageY position of the mage being drawn (gl WindowPos)
* \param spanX, spanY position of span being drawing
+ * \param width number of pixels in span
* \param x0, x1 returned X bounds of zoomed region [x0, x1)
* \param y0, y1 returned Y bounds of zoomed region [y0, y1)
* \return GL_TRUE if any zoomed pixels visible, GL_FALSE if totally clipped
*/
static GLboolean
-compute_zoomed_bounds(GLcontext *ctx, GLint imageX, GLint imageY,
+compute_zoomed_bounds(struct gl_context *ctx, GLint imageX, GLint imageY,
GLint spanX, GLint spanY, GLint width,
GLint *x0, GLint *x1, GLint *y0, GLint *y1)
{
const struct gl_framebuffer *fb = ctx->DrawBuffer;
GLint c0, c1, r0, r1;
- ASSERT(spanX >= imageX);
- ASSERT(spanY >= imageY);
+ assert(spanX >= imageX);
+ assert(spanY >= imageY);
/*
* Compute destination columns: [c0, c1)
/**
- * Can use this for unzooming X or Y values.
+ * Convert a zoomed x image coordinate back to an unzoomed x coord.
+ * 'zx' is screen position of a pixel in the zoomed image, who's left edge
+ * is at 'imageX'.
+ * return corresponding x coord in the original, unzoomed image.
+ * This can use this for unzooming X or Y values.
*/
-static INLINE GLint
+static inline GLint
unzoom_x(GLfloat zoomX, GLint imageX, GLint zx)
{
/*
zx - imageX = (x - imageX) * zoomX;
(zx - imageX) / zoomX = x - imageX;
*/
- GLint x = imageX + (GLint) ((zx - imageX) / zoomX);
+ GLint x;
+ if (zoomX < 0.0F)
+ zx++;
+ x = imageX + (GLint) ((zx - imageX) / zoomX);
return x;
}
* index/depth_span().
*/
static void
-zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span,
+zoom_span( struct gl_context *ctx, GLint imgX, GLint imgY, const SWspan *span,
const GLvoid *src, GLenum format )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
SWspan zoomed;
- SWspanarrays zoomed_arrays; /* this is big! */
GLint x0, x1, y0, y1;
GLint zoomedWidth;
return; /* totally clipped */
}
+ if (!swrast->ZoomedArrays) {
+ /* allocate on demand */
+ swrast->ZoomedArrays = (SWspanarrays *) calloc(1, sizeof(SWspanarrays));
+ if (!swrast->ZoomedArrays)
+ return;
+ }
+
zoomedWidth = x1 - x0;
- ASSERT(zoomedWidth > 0);
- ASSERT(zoomedWidth <= MAX_WIDTH);
+ assert(zoomedWidth > 0);
+ assert(zoomedWidth <= SWRAST_MAX_WIDTH);
/* no pixel arrays! must be horizontal spans. */
- ASSERT((span->arrayMask & SPAN_XY) == 0);
- ASSERT(span->primitive == GL_BITMAP);
+ assert((span->arrayMask & SPAN_XY) == 0);
+ assert(span->primitive == GL_BITMAP);
- INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0);
+ INIT_SPAN(zoomed, GL_BITMAP);
zoomed.x = x0;
zoomed.end = zoomedWidth;
- zoomed.array = &zoomed_arrays;
- zoomed_arrays.ChanType = span->array->ChanType;
- /* XXX temporary */
-#if CHAN_TYPE == GL_UNSIGNED_BYTE
- zoomed_arrays.rgba = zoomed_arrays.color.sz1.rgba;
- zoomed_arrays.spec = zoomed_arrays.color.sz1.spec;
-#elif CHAN_TYPE == GL_UNSIGNED_SHORT
- zoomed_arrays.rgba = zoomed_arrays.color.sz2.rgba;
- zoomed_arrays.spec = zoomed_arrays.color.sz2.spec;
-#else
- zoomed_arrays.rgba = zoomed_arrays.color.sz4.rgba;
- zoomed_arrays.spec = zoomed_arrays.color.sz4.spec;
-#endif
-
-
- /* copy fog interp info */
- zoomed.fog = span->fog;
- zoomed.fogStep = span->fogStep;
- /* XXX copy texcoord info? */
+ zoomed.array = swrast->ZoomedArrays;
+ zoomed.array->ChanType = span->array->ChanType;
+ if (zoomed.array->ChanType == GL_UNSIGNED_BYTE)
+ zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba8;
+ else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT)
+ zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba16;
+ else
+ zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->attribs[VARYING_SLOT_COL0];
+
+ COPY_4V(zoomed.attrStart[VARYING_SLOT_POS], span->attrStart[VARYING_SLOT_POS]);
+ COPY_4V(zoomed.attrStepX[VARYING_SLOT_POS], span->attrStepX[VARYING_SLOT_POS]);
+ COPY_4V(zoomed.attrStepY[VARYING_SLOT_POS], span->attrStepY[VARYING_SLOT_POS]);
+
+ zoomed.attrStart[VARYING_SLOT_FOGC][0] = span->attrStart[VARYING_SLOT_FOGC][0];
+ zoomed.attrStepX[VARYING_SLOT_FOGC][0] = span->attrStepX[VARYING_SLOT_FOGC][0];
+ zoomed.attrStepY[VARYING_SLOT_FOGC][0] = span->attrStepY[VARYING_SLOT_FOGC][0];
if (format == GL_RGBA || format == GL_RGB) {
/* copy Z info */
/* we'll generate an array of colorss */
zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
zoomed.arrayMask |= SPAN_RGBA;
- ASSERT(span->arrayMask & SPAN_RGBA);
- }
- else if (format == GL_COLOR_INDEX) {
- /* copy Z info */
- zoomed.z = span->z;
- zoomed.zStep = span->zStep;
- /* we'll generate an array of color indexes */
- zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
- zoomed.arrayMask |= SPAN_INDEX;
- ASSERT(span->arrayMask & SPAN_INDEX);
+ zoomed.arrayAttribs |= VARYING_BIT_COL0; /* we'll produce these values */
+ assert(span->arrayMask & SPAN_RGBA);
}
else if (format == GL_DEPTH_COMPONENT) {
/* Copy color info */
/* we'll generate an array of depth values */
zoomed.interpMask = span->interpMask & ~SPAN_Z;
zoomed.arrayMask |= SPAN_Z;
- ASSERT(span->arrayMask & SPAN_Z);
+ assert(span->arrayMask & SPAN_Z);
}
else {
_mesa_problem(ctx, "Bad format in zoom_span");
GLint i;
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
- ASSERT(j >= 0);
- ASSERT(j < span->end);
- COPY_4UBV(zoomed.array->color.sz1.rgba[i], rgba[j]);
+ assert(j >= 0);
+ assert(j < (GLint) span->end);
+ COPY_4UBV(zoomed.array->rgba8[i], rgba[j]);
}
}
else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
GLint i;
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
- ASSERT(j >= 0);
- ASSERT(j < span->end);
- COPY_4V(zoomed.array->color.sz2.rgba[i], rgba[j]);
+ assert(j >= 0);
+ assert(j < (GLint) span->end);
+ COPY_4V(zoomed.array->rgba16[i], rgba[j]);
}
}
else {
GLint i;
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
- ASSERT(j >= 0);
- ASSERT(j < span->end);
- COPY_4V(zoomed.array->color.sz4.rgba[i], rgba[j]);
+ assert(j >= 0);
+ assert(j < (GLint) span->end);
+ COPY_4V(zoomed.array->attribs[VARYING_SLOT_COL0][i], rgba[j]);
}
}
}
GLint i;
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
- ASSERT(j >= 0);
- ASSERT(j < span->end);
- zoomed.array->color.sz1.rgba[i][0] = rgb[j][0];
- zoomed.array->color.sz1.rgba[i][1] = rgb[j][1];
- zoomed.array->color.sz1.rgba[i][2] = rgb[j][2];
- zoomed.array->color.sz1.rgba[i][3] = 0xff;
+ assert(j >= 0);
+ assert(j < (GLint) span->end);
+ zoomed.array->rgba8[i][0] = rgb[j][0];
+ zoomed.array->rgba8[i][1] = rgb[j][1];
+ zoomed.array->rgba8[i][2] = rgb[j][2];
+ zoomed.array->rgba8[i][3] = 0xff;
}
}
else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) {
GLint i;
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
- ASSERT(j >= 0);
- ASSERT(j < span->end);
- zoomed.array->color.sz2.rgba[i][0] = rgb[j][0];
- zoomed.array->color.sz2.rgba[i][1] = rgb[j][1];
- zoomed.array->color.sz2.rgba[i][2] = rgb[j][2];
- zoomed.array->color.sz2.rgba[i][3] = 0xffff;
+ assert(j >= 0);
+ assert(j < (GLint) span->end);
+ zoomed.array->rgba16[i][0] = rgb[j][0];
+ zoomed.array->rgba16[i][1] = rgb[j][1];
+ zoomed.array->rgba16[i][2] = rgb[j][2];
+ zoomed.array->rgba16[i][3] = 0xffff;
}
}
else {
GLint i;
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
- ASSERT(j >= 0);
- ASSERT(j < span->end);
- zoomed.array->color.sz4.rgba[i][0] = rgb[j][0];
- zoomed.array->color.sz4.rgba[i][1] = rgb[j][1];
- zoomed.array->color.sz4.rgba[i][2] = rgb[j][2];
- zoomed.array->color.sz4.rgba[i][3] = 1.0F;
+ assert(j >= 0);
+ assert(j < (GLint) span->end);
+ zoomed.array->attribs[VARYING_SLOT_COL0][i][0] = rgb[j][0];
+ zoomed.array->attribs[VARYING_SLOT_COL0][i][1] = rgb[j][1];
+ zoomed.array->attribs[VARYING_SLOT_COL0][i][2] = rgb[j][2];
+ zoomed.array->attribs[VARYING_SLOT_COL0][i][3] = 1.0F;
}
}
}
- else if (format == GL_COLOR_INDEX) {
- const GLuint *indexes = (const GLuint *) src;
- GLint i;
- for (i = 0; i < zoomedWidth; i++) {
- GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
- ASSERT(j >= 0);
- ASSERT(j < span->end);
- zoomed.array->index[i] = indexes[j];
- }
- }
else if (format == GL_DEPTH_COMPONENT) {
const GLuint *zValues = (const GLuint *) src;
GLint i;
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x;
- ASSERT(j >= 0);
- ASSERT(j < span->end);
+ assert(j >= 0);
+ assert(j < (GLint) span->end);
zoomed.array->z[i] = zValues[j];
}
- /* Now, fall into either the RGB or COLOR_INDEX path below */
- format = ctx->Visual.rgbMode ? GL_RGBA : GL_COLOR_INDEX;
+ /* Now, fall into the RGB path below */
+ format = GL_RGBA;
}
/* write the span in rows [r0, r1) */
* Also, clipping may change the span end value, so store it as well.
*/
const GLint end = zoomed.end; /* save */
- /* use specular color array for temp storage */
- void *rgbaSave = zoomed.array->spec;
+ void *rgbaSave;
const GLint pixelSize =
(zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) :
((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort)
: 4 * sizeof(GLfloat));
- if (y1 - y0 > 1) {
- MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize);
- }
- for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) {
- _swrast_write_rgba_span(ctx, &zoomed);
- zoomed.end = end; /* restore */
- if (y1 - y0 > 1) {
- /* restore the colors */
- MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize);
- }
+
+ rgbaSave = malloc(zoomed.end * pixelSize);
+ if (!rgbaSave) {
+ return;
}
- }
- else if (format == GL_COLOR_INDEX) {
- /* use specular color array for temp storage */
- GLuint *indexSave = (GLuint *) zoomed.array->spec;
- const GLint end = zoomed.end; /* save */
+
if (y1 - y0 > 1) {
- MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
+ memcpy(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize);
}
for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) {
- _swrast_write_index_span(ctx, &zoomed);
+ _swrast_write_rgba_span(ctx, &zoomed);
zoomed.end = end; /* restore */
if (y1 - y0 > 1) {
/* restore the colors */
- MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint));
+ memcpy(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize);
}
}
+
+ free(rgbaSave);
}
}
void
-_swrast_write_zoomed_rgba_span(GLcontext *ctx, GLint imgX, GLint imgY,
+_swrast_write_zoomed_rgba_span(struct gl_context *ctx, GLint imgX, GLint imgY,
const SWspan *span, const GLvoid *rgba)
{
zoom_span(ctx, imgX, imgY, span, rgba, GL_RGBA);
void
-_swrast_write_zoomed_rgb_span(GLcontext *ctx, GLint imgX, GLint imgY,
+_swrast_write_zoomed_rgb_span(struct gl_context *ctx, GLint imgX, GLint imgY,
const SWspan *span, const GLvoid *rgb)
{
zoom_span(ctx, imgX, imgY, span, rgb, GL_RGB);
void
-_swrast_write_zoomed_index_span(GLcontext *ctx, GLint imgX, GLint imgY,
- const SWspan *span)
-{
- zoom_span(ctx, imgX, imgY, span,
- (const GLvoid *) span->array->index, GL_COLOR_INDEX);
-}
-
-
-void
-_swrast_write_zoomed_depth_span(GLcontext *ctx, GLint imgX, GLint imgY,
+_swrast_write_zoomed_depth_span(struct gl_context *ctx, GLint imgX, GLint imgY,
const SWspan *span)
{
zoom_span(ctx, imgX, imgY, span,
* No per-fragment operations are applied.
*/
void
-_swrast_write_zoomed_stencil_span(GLcontext *ctx, GLint imgX, GLint imgY,
+_swrast_write_zoomed_stencil_span(struct gl_context *ctx, GLint imgX, GLint imgY,
GLint width, GLint spanX, GLint spanY,
- const GLstencil stencil[])
+ const GLubyte stencil[])
{
- GLstencil zoomedVals[MAX_WIDTH];
+ GLubyte *zoomedVals;
GLint x0, x1, y0, y1, y;
GLint i, zoomedWidth;
}
zoomedWidth = x1 - x0;
- ASSERT(zoomedWidth > 0);
- ASSERT(zoomedWidth <= MAX_WIDTH);
+ assert(zoomedWidth > 0);
+ assert(zoomedWidth <= SWRAST_MAX_WIDTH);
+
+ zoomedVals = malloc(zoomedWidth * sizeof(GLubyte));
+ if (!zoomedVals)
+ return;
/* zoom the span horizontally */
for (i = 0; i < zoomedWidth; i++) {
GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
- ASSERT(j >= 0);
- ASSERT(j < width);
+ assert(j >= 0);
+ assert(j < width);
zoomedVals[i] = stencil[j];
}
for (y = y0; y < y1; y++) {
_swrast_write_stencil_span(ctx, zoomedWidth, x0, y, zoomedVals);
}
+
+ free(zoomedVals);
}
/**
- * Zoom/write z values (16 or 32-bit).
+ * Zoom/write 32-bit Z values.
* No per-fragment operations are applied.
*/
void
-_swrast_write_zoomed_z_span(GLcontext *ctx, GLint imgX, GLint imgY,
+_swrast_write_zoomed_z_span(struct gl_context *ctx, GLint imgX, GLint imgY,
GLint width, GLint spanX, GLint spanY,
- const GLvoid *z)
+ const GLuint *zVals)
{
- struct gl_renderbuffer *rb = ctx->DrawBuffer->_DepthBuffer;
- GLushort zoomedVals16[MAX_WIDTH];
- GLuint zoomedVals32[MAX_WIDTH];
+ struct gl_renderbuffer *rb =
+ ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+ GLuint *zoomedVals;
GLint x0, x1, y0, y1, y;
GLint i, zoomedWidth;
}
zoomedWidth = x1 - x0;
- ASSERT(zoomedWidth > 0);
- ASSERT(zoomedWidth <= MAX_WIDTH);
+ assert(zoomedWidth > 0);
+ assert(zoomedWidth <= SWRAST_MAX_WIDTH);
+
+ zoomedVals = malloc(zoomedWidth * sizeof(GLuint));
+ if (!zoomedVals)
+ return;
/* zoom the span horizontally */
- if (rb->DataType == GL_UNSIGNED_SHORT) {
- for (i = 0; i < zoomedWidth; i++) {
- GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
- ASSERT(j >= 0);
- ASSERT(j < width);
- zoomedVals16[i] = ((GLushort *) z)[j];
- }
- z = zoomedVals16;
- }
- else {
- ASSERT(rb->DataType == GL_UNSIGNED_INT);
- for (i = 0; i < zoomedWidth; i++) {
- GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
- ASSERT(j >= 0);
- ASSERT(j < width);
- zoomedVals32[i] = ((GLuint *) z)[j];
- }
- z = zoomedVals32;
+ for (i = 0; i < zoomedWidth; i++) {
+ GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX;
+ assert(j >= 0);
+ assert(j < width);
+ zoomedVals[i] = zVals[j];
}
/* write the zoomed spans */
for (y = y0; y < y1; y++) {
- rb->PutRow(ctx, rb, zoomedWidth, x0, y, z, NULL);
+ GLubyte *dst = _swrast_pixel_address(rb, x0, y);
+ _mesa_pack_uint_z_row(rb->Format, zoomedWidth, zoomedVals, dst);
}
+
+ free(zoomedVals);
}