00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00033 #include "pipe/p_defines.h"
00034 #include "pipe/p_format.h"
00035 #include "pipe/p_context.h"
00036 #include "pipe/p_screen.h"
00037 #include "util/u_rect.h"
00038
00039
00045 void
00046 pipe_copy_rect(ubyte * dst,
00047 const struct pipe_format_block *block,
00048 unsigned dst_stride,
00049 unsigned dst_x,
00050 unsigned dst_y,
00051 unsigned width,
00052 unsigned height,
00053 const ubyte * src,
00054 int src_stride,
00055 unsigned src_x,
00056 int src_y)
00057 {
00058 unsigned i;
00059 int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
00060
00061 assert(block->size > 0);
00062 assert(block->width > 0);
00063 assert(block->height > 0);
00064 assert(src_x >= 0);
00065 assert(src_y >= 0);
00066 assert(dst_x >= 0);
00067 assert(dst_y >= 0);
00068
00069 dst_x /= block->width;
00070 dst_y /= block->height;
00071 width = (width + block->width - 1)/block->width;
00072 height = (height + block->height - 1)/block->height;
00073 src_x /= block->width;
00074 src_y /= block->height;
00075
00076 dst += dst_x * block->size;
00077 src += src_x * block->size;
00078 dst += dst_y * dst_stride;
00079 src += src_y * src_stride_pos;
00080 width *= block->size;
00081
00082 if (width == dst_stride && width == src_stride)
00083 memcpy(dst, src, height * width);
00084 else {
00085 for (i = 0; i < height; i++) {
00086 memcpy(dst, src, width);
00087 dst += dst_stride;
00088 src += src_stride;
00089 }
00090 }
00091 }
00092
00093 void
00094 pipe_fill_rect(ubyte * dst,
00095 const struct pipe_format_block *block,
00096 unsigned dst_stride,
00097 unsigned dst_x,
00098 unsigned dst_y,
00099 unsigned width,
00100 unsigned height,
00101 uint32_t value)
00102 {
00103 unsigned i, j;
00104 unsigned width_size;
00105
00106 assert(block->size > 0);
00107 assert(block->width > 0);
00108 assert(block->height > 0);
00109 assert(dst_x >= 0);
00110 assert(dst_y >= 0);
00111
00112 dst_x /= block->width;
00113 dst_y /= block->height;
00114 width = (width + block->width - 1)/block->width;
00115 height = (height + block->height - 1)/block->height;
00116
00117 dst += dst_x * block->size;
00118 dst += dst_y * dst_stride;
00119 width_size = width * block->size;
00120
00121 switch (block->size) {
00122 case 1:
00123 if(dst_stride == width_size)
00124 memset(dst, (ubyte) value, height * width_size);
00125 else {
00126 for (i = 0; i < height; i++) {
00127 memset(dst, (ubyte) value, width_size);
00128 dst += dst_stride;
00129 }
00130 }
00131 break;
00132 case 2:
00133 for (i = 0; i < height; i++) {
00134 uint16_t *row = (uint16_t *)dst;
00135 for (j = 0; j < width; j++)
00136 *row++ = (uint16_t) value;
00137 dst += dst_stride;
00138 }
00139 break;
00140 case 4:
00141 for (i = 0; i < height; i++) {
00142 uint32_t *row = (uint32_t *)dst;
00143 for (j = 0; j < width; j++)
00144 *row++ = value;
00145 dst += dst_stride;
00146 }
00147 break;
00148 default:
00149 assert(0);
00150 break;
00151 }
00152 }
00153
00154
00155
00162 void
00163 util_surface_copy(struct pipe_context *pipe,
00164 boolean do_flip,
00165 struct pipe_surface *dst,
00166 unsigned dst_x, unsigned dst_y,
00167 struct pipe_surface *src,
00168 unsigned src_x, unsigned src_y,
00169 unsigned w, unsigned h)
00170 {
00171 struct pipe_screen *screen = pipe->screen;
00172 struct pipe_surface *new_src = NULL, *new_dst = NULL;
00173 void *dst_map;
00174 const void *src_map;
00175
00176 assert(dst->block.size == src->block.size);
00177 assert(dst->block.width == src->block.width);
00178 assert(dst->block.height == src->block.height);
00179
00180 if ((src->usage & PIPE_BUFFER_USAGE_CPU_READ) == 0) {
00181
00182 assert(src->texture);
00183 if (!src->texture)
00184 return;
00185 new_src = screen->get_tex_surface(screen,
00186 src->texture,
00187 src->face,
00188 src->level,
00189 src->zslice,
00190 PIPE_BUFFER_USAGE_CPU_READ);
00191 src = new_src;
00192 }
00193
00194 if ((dst->usage & PIPE_BUFFER_USAGE_CPU_WRITE) == 0) {
00195
00196 assert(dst->texture);
00197 if (!dst->texture)
00198 return;
00199 new_dst = screen->get_tex_surface(screen,
00200 dst->texture,
00201 dst->face,
00202 dst->level,
00203 dst->zslice,
00204 PIPE_BUFFER_USAGE_CPU_WRITE);
00205 dst = new_dst;
00206 }
00207
00208 src_map = pipe->screen->surface_map(screen,
00209 src, PIPE_BUFFER_USAGE_CPU_READ);
00210 dst_map = pipe->screen->surface_map(screen,
00211 dst, PIPE_BUFFER_USAGE_CPU_WRITE);
00212
00213 assert(src_map);
00214 assert(dst_map);
00215
00216 if (src_map && dst_map) {
00217
00218 pipe_copy_rect(dst_map,
00219 &dst->block,
00220 dst->stride,
00221 dst_x, dst_y,
00222 w, h,
00223 src_map,
00224 do_flip ? -(int) src->stride : src->stride,
00225 src_x,
00226 do_flip ? src_y + h - 1 : src_y);
00227 }
00228
00229 pipe->screen->surface_unmap(pipe->screen, src);
00230 pipe->screen->surface_unmap(pipe->screen, dst);
00231
00232 if (new_src)
00233 screen->tex_surface_release(screen, &new_src);
00234 if (new_dst)
00235 screen->tex_surface_release(screen, &new_dst);
00236 }
00237
00238
00239
00240 static void *
00241 get_pointer(struct pipe_surface *dst, void *dst_map, unsigned x, unsigned y)
00242 {
00243 return (char *)dst_map
00244 + y / dst->block.height * dst->stride
00245 + x / dst->block.width * dst->block.size;
00246 }
00247
00248
00249 #define UBYTE_TO_USHORT(B) ((B) | ((B) << 8))
00250
00251
00256 void
00257 util_surface_fill(struct pipe_context *pipe,
00258 struct pipe_surface *dst,
00259 unsigned dstx, unsigned dsty,
00260 unsigned width, unsigned height, unsigned value)
00261 {
00262 struct pipe_screen *screen = pipe->screen;
00263 struct pipe_surface *new_dst = NULL;
00264 void *dst_map;
00265
00266 if ((dst->usage & PIPE_BUFFER_USAGE_CPU_WRITE) == 0) {
00267
00268 assert(dst->texture);
00269 if (!dst->texture)
00270 return;
00271 new_dst = screen->get_tex_surface(screen,
00272 dst->texture,
00273 dst->face,
00274 dst->level,
00275 dst->zslice,
00276 PIPE_BUFFER_USAGE_CPU_WRITE);
00277 dst = new_dst;
00278 }
00279
00280 dst_map = pipe->screen->surface_map(screen,
00281 dst, PIPE_BUFFER_USAGE_CPU_WRITE);
00282
00283 assert(dst_map);
00284
00285 if (dst_map) {
00286 assert(dst->stride > 0);
00287
00288 switch (dst->block.size) {
00289 case 1:
00290 case 2:
00291 case 4:
00292 pipe_fill_rect(dst_map, &dst->block, dst->stride,
00293 dstx, dsty, width, height, value);
00294 break;
00295 case 8:
00296 {
00297
00298 ushort *row = (ushort *) get_pointer(dst, dst_map, dstx, dsty);
00299 ushort val0 = UBYTE_TO_USHORT((value >> 0) & 0xff);
00300 ushort val1 = UBYTE_TO_USHORT((value >> 8) & 0xff);
00301 ushort val2 = UBYTE_TO_USHORT((value >> 16) & 0xff);
00302 ushort val3 = UBYTE_TO_USHORT((value >> 24) & 0xff);
00303 unsigned i, j;
00304 val0 = (val0 << 8) | val0;
00305 val1 = (val1 << 8) | val1;
00306 val2 = (val2 << 8) | val2;
00307 val3 = (val3 << 8) | val3;
00308 for (i = 0; i < height; i++) {
00309 for (j = 0; j < width; j++) {
00310 row[j*4+0] = val0;
00311 row[j*4+1] = val1;
00312 row[j*4+2] = val2;
00313 row[j*4+3] = val3;
00314 }
00315 row += dst->stride/2;
00316 }
00317 }
00318 break;
00319 default:
00320 assert(0);
00321 break;
00322 }
00323 }
00324
00325 pipe->screen->surface_unmap(pipe->screen, dst);
00326
00327 if (new_dst)
00328 screen->tex_surface_release(screen, &new_dst);
00329 }