void PixmanBitmap::FlipBlit(int x, int y, Bitmap* _src, Rect src_rect, bool horizontal, bool vertical) { if (!horizontal && !vertical) { Blit(x, y, _src, src_rect, 255); return; } PixmanBitmap* src = (PixmanBitmap*) _src; pixman_transform_t xform; pixman_transform_init_scale(&xform, pixman_int_to_fixed(horizontal ? -1 : 1), pixman_int_to_fixed(vertical ? -1 : 1)); pixman_transform_translate((pixman_transform_t*) NULL, &xform, pixman_int_to_fixed(horizontal ? src_rect.width : 0), pixman_int_to_fixed(vertical ? src_rect.height : 0)); pixman_image_set_transform(bitmap, &xform); pixman_image_composite32(PIXMAN_OP_SRC, src->bitmap, (pixman_image_t*) NULL, bitmap, src_rect.x, src_rect.y, 0, 0, x, y, src_rect.width, src_rect.height); pixman_transform_init_identity(&xform); pixman_image_set_transform(bitmap, &xform); RefreshCallback(); }
Bitmap* PixmanBitmap::Resample(int scale_w, int scale_h, const Rect& src_rect) { PixmanBitmap *dst = new PixmanBitmap(scale_w, scale_h, GetTransparent()); double zoom_x = (double)src_rect.width / scale_w; double zoom_y = (double)src_rect.height / scale_h; pixman_transform_t xform; pixman_transform_init_scale(&xform, pixman_double_to_fixed(zoom_x), pixman_double_to_fixed(zoom_y)); pixman_image_set_transform(bitmap, &xform); pixman_image_composite32(PIXMAN_OP_SRC, bitmap, (pixman_image_t*) NULL, dst->bitmap, src_rect.x, src_rect.y, 0, 0, 0, 0, scale_w, scale_h); pixman_transform_init_identity(&xform); pixman_image_set_transform(bitmap, &xform); return dst; }
/* * Create a CRTC */ RRCrtcPtr RRCrtcCreate (ScreenPtr pScreen, void *devPrivate) { RRCrtcPtr crtc; RRCrtcPtr *crtcs; rrScrPrivPtr pScrPriv; if (!RRInit()) return NULL; pScrPriv = rrGetScrPriv(pScreen); /* make space for the crtc pointer */ if (pScrPriv->numCrtcs) crtcs = realloc(pScrPriv->crtcs, (pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr)); else crtcs = malloc(sizeof (RRCrtcPtr)); if (!crtcs) return FALSE; pScrPriv->crtcs = crtcs; crtc = calloc(1, sizeof (RRCrtcRec)); if (!crtc) return NULL; crtc->id = FakeClientID (0); crtc->pScreen = pScreen; crtc->mode = NULL; crtc->x = 0; crtc->y = 0; crtc->rotation = RR_Rotate_0; crtc->rotations = RR_Rotate_0; crtc->outputs = NULL; crtc->numOutputs = 0; crtc->gammaSize = 0; crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL; crtc->changed = FALSE; crtc->devPrivate = devPrivate; RRTransformInit (&crtc->client_pending_transform); RRTransformInit (&crtc->client_current_transform); pixman_transform_init_identity (&crtc->transform); pixman_f_transform_init_identity (&crtc->f_transform); pixman_f_transform_init_identity (&crtc->f_inverse); if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) return NULL; /* attach the screen and crtc together */ crtc->pScreen = pScreen; pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc; return crtc; }
static void process_image_data(struct fp_img_dev *dev, char **output, int *output_height) { //pixman stuff taken from libfprint/pixman.c, adapted for my purposes. pixman_image_t *orig, *resized; pixman_transform_t transform; struct vfs0050_dev *vfs_dev = dev->priv; struct vfs0050_line *line, *calibration_line; char *buf = malloc(vfs_dev->scanbuf_idx); int lines = vfs_dev->scanbuf_idx / VFS0050_FRAME_SIZE; int i, x, sum, last_sum, diff; int new_height; //just grab one around middle, there should be 100 calibration_line = (struct vfs0050_line *) ((char *) vfs_dev->calbuf + (50 * VFS0050_FRAME_SIZE)); new_height = 0; for (i = 0; i < lines; i++) { line = (struct vfs0050_line *) ((char *) vfs_dev->scanbuf + (i * VFS0050_FRAME_SIZE)); if (!is_noise(line)) memcpy(buf + (new_height++ * VFS0050_IMG_WIDTH), line->row, VFS0050_IMG_WIDTH); else fp_dbg("removed noise at line: %d\n", i); } orig = pixman_image_create_bits(PIXMAN_a8, VFS0050_IMG_WIDTH, new_height, (uint32_t *) buf, VFS0050_IMG_WIDTH); new_height *= VFS0050_SCALE_FACTOR; //scale for resized image resized = pixman_image_create_bits(PIXMAN_a8, VFS0050_IMG_WIDTH, new_height, NULL, VFS0050_IMG_WIDTH); pixman_transform_init_identity(&transform); pixman_transform_scale(NULL, &transform, pixman_int_to_fixed(1), pixman_double_to_fixed(0.2)); pixman_image_set_transform(orig, &transform); pixman_image_set_filter(orig, PIXMAN_FILTER_BEST, NULL, 0); pixman_image_composite32(PIXMAN_OP_SRC, orig, NULL, resized, 0, 0, 0, 0, 0, 0, VFS0050_IMG_WIDTH, new_height ); memcpy(buf, pixman_image_get_data(resized), VFS0050_IMG_WIDTH * new_height); pixman_image_unref(orig); pixman_image_unref(resized); *output_height = new_height; *output = buf; }
void PixmanBitmap::TransformBlit(Rect dst_rect, Bitmap* _src, Rect src_rect, const Matrix& inv, int opacity) { PixmanBitmap* src = (PixmanBitmap*) _src; pixman_transform_t xform = {{ { pixman_double_to_fixed(inv.xx), pixman_double_to_fixed(inv.xy), pixman_double_to_fixed(inv.x0) }, { pixman_double_to_fixed(inv.yx), pixman_double_to_fixed(inv.yy), pixman_double_to_fixed(inv.y0) }, { pixman_double_to_fixed(0.0), pixman_double_to_fixed(0.0), pixman_double_to_fixed(1.0) } }}; pixman_image_set_transform(src->bitmap, &xform); pixman_image_composite32(PIXMAN_OP_OVER, src->bitmap, (pixman_image_t*) NULL, bitmap, dst_rect.x, dst_rect.y, 0, 0, dst_rect.x, dst_rect.y, dst_rect.width, dst_rect.height); pixman_transform_init_identity(&xform); pixman_image_set_transform(src->bitmap, &xform); }
void PixmanBitmap::Blit2x(Rect dst_rect, Bitmap* _src, Rect src_rect) { PixmanBitmap* src = (PixmanBitmap*) _src; pixman_transform_t xform; pixman_transform_init_scale(&xform, pixman_double_to_fixed(0.5), pixman_double_to_fixed(0.5)); pixman_image_set_transform(src->bitmap, &xform); pixman_image_composite32(PIXMAN_OP_SRC, src->bitmap, (pixman_image_t*) NULL, bitmap, src_rect.x, src_rect.y, 0, 0, dst_rect.x, dst_rect.y, dst_rect.width, dst_rect.height); pixman_transform_init_identity(&xform); pixman_image_set_transform(src->bitmap, &xform); RefreshCallback(); }
struct fp_img *fpi_im_resize(struct fp_img *img, unsigned int w_factor, unsigned int h_factor) { int new_width = img->width * w_factor; int new_height = img->height * h_factor; pixman_image_t *orig, *resized; pixman_transform_t transform; struct fp_img *newimg; orig = pixman_image_create_bits(PIXMAN_a8, img->width, img->height, (uint32_t *)img->data, img->width); resized = pixman_image_create_bits(PIXMAN_a8, new_width, new_height, NULL, new_width); pixman_transform_init_identity(&transform); pixman_transform_scale(NULL, &transform, pixman_int_to_fixed(w_factor), pixman_int_to_fixed(h_factor)); pixman_image_set_transform(orig, &transform); pixman_image_set_filter(orig, PIXMAN_FILTER_BILINEAR, NULL, 0); pixman_image_composite32(PIXMAN_OP_SRC, orig, /* src */ NULL, /* mask */ resized, /* dst */ 0, 0, /* src x y */ 0, 0, /* mask x y */ 0, 0, /* dst x y */ new_width, new_height /* width height */ ); newimg = fpi_img_new(new_width * new_height); newimg->width = new_width; newimg->height = new_height; newimg->flags = img->flags; memcpy(newimg->data, pixman_image_get_data(resized), new_width * new_height); pixman_image_unref(orig); pixman_image_unref(resized); return newimg; }
void PixmanBitmap::StretchBlit(Rect dst_rect, Bitmap* _src, Rect src_rect, int opacity) { if (opacity < 0) return; PixmanBitmap* src = (PixmanBitmap*) _src; pixman_image_t* mask = (pixman_image_t*) NULL; if (opacity < 255) { pixman_color_t tcolor = {0, 0, 0, opacity << 8}; mask = pixman_image_create_solid_fill(&tcolor); } double zoom_x = (double)src_rect.width / dst_rect.width; double zoom_y = (double)src_rect.height / dst_rect.height; pixman_transform_t xform; pixman_transform_init_scale(&xform, pixman_double_to_fixed(zoom_x), pixman_double_to_fixed(zoom_y)); pixman_image_set_transform(src->bitmap, &xform); pixman_image_composite32(PIXMAN_OP_OVER, src->bitmap, mask, bitmap, src_rect.x / zoom_x, src_rect.y / zoom_y, 0, 0, dst_rect.x, dst_rect.y, dst_rect.width, dst_rect.height); pixman_transform_init_identity(&xform); pixman_image_set_transform(src->bitmap, &xform); if (mask != NULL) pixman_image_unref(mask); RefreshCallback(); }
bool mSDLSWInit(struct mSDLRenderer* renderer) { #if !SDL_VERSION_ATLEAST(2, 0, 0) #ifdef COLOR_16_BIT SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 16, SDL_DOUBLEBUF | SDL_HWSURFACE); #else SDL_SetVideoMode(renderer->viewportWidth, renderer->viewportHeight, 32, SDL_DOUBLEBUF | SDL_HWSURFACE); #endif #endif unsigned width, height; renderer->core->desiredVideoDimensions(renderer->core, &width, &height); #if SDL_VERSION_ATLEAST(2, 0, 0) renderer->window = SDL_CreateWindow(projectName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, renderer->viewportWidth, renderer->viewportHeight, SDL_WINDOW_OPENGL | (SDL_WINDOW_FULLSCREEN_DESKTOP * renderer->player.fullscreen)); SDL_GetWindowSize(renderer->window, &renderer->viewportWidth, &renderer->viewportHeight); renderer->player.window = renderer->window; renderer->sdlRenderer = SDL_CreateRenderer(renderer->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, width, height); #else renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR1555, SDL_TEXTUREACCESS_STREAMING, width, height); #endif #else renderer->sdlTex = SDL_CreateTexture(renderer->sdlRenderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, width, height); #endif int stride; SDL_LockTexture(renderer->sdlTex, 0, (void**) &renderer->outputBuffer, &stride); renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, stride / BYTES_PER_PIXEL); #else SDL_Surface* surface = SDL_GetVideoSurface(); SDL_LockSurface(surface); if (renderer->ratio == 1) { renderer->core->setVideoBuffer(renderer->core, surface->pixels, surface->pitch / BYTES_PER_PIXEL); } else { #ifdef USE_PIXMAN renderer->outputBuffer = malloc(width * height * BYTES_PER_PIXEL); renderer->core->setVideoBuffer(renderer->core, renderer->outputBuffer, width); #ifdef COLOR_16_BIT #ifdef COLOR_5_6_5 pixman_format_code_t format = PIXMAN_r5g6b5; #else pixman_format_code_t format = PIXMAN_x1b5g5r5; #endif #else pixman_format_code_t format = PIXMAN_x8b8g8r8; #endif renderer->pix = pixman_image_create_bits(format, width, height, renderer->outputBuffer, width * BYTES_PER_PIXEL); renderer->screenpix = pixman_image_create_bits(format, renderer->viewportWidth, renderer->viewportHeight, surface->pixels, surface->pitch); pixman_transform_t transform; pixman_transform_init_identity(&transform); pixman_transform_scale(0, &transform, pixman_int_to_fixed(renderer->ratio), pixman_int_to_fixed(renderer->ratio)); pixman_image_set_transform(renderer->pix, &transform); pixman_image_set_filter(renderer->pix, PIXMAN_FILTER_NEAREST, 0, 0); #else return false; #endif } #endif return true; }
static void repaint_region(struct weston_view *ev, struct weston_output *output, pixman_region32_t *region, pixman_region32_t *surf_region, pixman_op_t pixman_op) { struct pixman_renderer *pr = (struct pixman_renderer *) output->compositor->renderer; struct pixman_surface_state *ps = get_surface_state(ev->surface); struct pixman_output_state *po = get_output_state(output); pixman_region32_t final_region; float view_x, view_y; pixman_transform_t transform; pixman_fixed_t fw, fh; /* The final region to be painted is the intersection of * 'region' and 'surf_region'. However, 'region' is in the global * coordinates, and 'surf_region' is in the surface-local * coordinates */ pixman_region32_init(&final_region); if (surf_region) { pixman_region32_copy(&final_region, surf_region); /* Convert from surface to global coordinates */ if (!ev->transform.enabled) { pixman_region32_translate(&final_region, ev->geometry.x, ev->geometry.y); } else { weston_view_to_global_float(ev, 0, 0, &view_x, &view_y); pixman_region32_translate(&final_region, (int)view_x, (int)view_y); } /* We need to paint the intersection */ pixman_region32_intersect(&final_region, &final_region, region); } else { /* If there is no surface region, just use the global region */ pixman_region32_copy(&final_region, region); } /* Convert from global to output coord */ region_global_to_output(output, &final_region); /* And clip to it */ pixman_image_set_clip_region32 (po->shadow_image, &final_region); /* Set up the source transformation based on the surface position, the output position/transform/scale and the client specified buffer transform/scale */ pixman_transform_init_identity(&transform); pixman_transform_scale(&transform, NULL, pixman_double_to_fixed ((double)1.0/output->current_scale), pixman_double_to_fixed ((double)1.0/output->current_scale)); fw = pixman_int_to_fixed(output->width); fh = pixman_int_to_fixed(output->height); switch (output->transform) { default: case WL_OUTPUT_TRANSFORM_NORMAL: case WL_OUTPUT_TRANSFORM_FLIPPED: break; case WL_OUTPUT_TRANSFORM_90: case WL_OUTPUT_TRANSFORM_FLIPPED_90: pixman_transform_rotate(&transform, NULL, 0, -pixman_fixed_1); pixman_transform_translate(&transform, NULL, 0, fh); break; case WL_OUTPUT_TRANSFORM_180: case WL_OUTPUT_TRANSFORM_FLIPPED_180: pixman_transform_rotate(&transform, NULL, -pixman_fixed_1, 0); pixman_transform_translate(&transform, NULL, fw, fh); break; case WL_OUTPUT_TRANSFORM_270: case WL_OUTPUT_TRANSFORM_FLIPPED_270: pixman_transform_rotate(&transform, NULL, 0, pixman_fixed_1); pixman_transform_translate(&transform, NULL, fw, 0); break; } switch (output->transform) { case WL_OUTPUT_TRANSFORM_FLIPPED: case WL_OUTPUT_TRANSFORM_FLIPPED_90: case WL_OUTPUT_TRANSFORM_FLIPPED_180: case WL_OUTPUT_TRANSFORM_FLIPPED_270: pixman_transform_scale(&transform, NULL, pixman_int_to_fixed (-1), pixman_int_to_fixed (1)); pixman_transform_translate(&transform, NULL, fw, 0); break; } pixman_transform_translate(&transform, NULL, pixman_double_to_fixed (output->x), pixman_double_to_fixed (output->y)); if (ev->transform.enabled) { /* Pixman supports only 2D transform matrix, but Weston uses 3D, * so we're omitting Z coordinate here */ pixman_transform_t surface_transform = {{ { D2F(ev->transform.matrix.d[0]), D2F(ev->transform.matrix.d[4]), D2F(ev->transform.matrix.d[12]), }, { D2F(ev->transform.matrix.d[1]), D2F(ev->transform.matrix.d[5]), D2F(ev->transform.matrix.d[13]), }, { D2F(ev->transform.matrix.d[3]), D2F(ev->transform.matrix.d[7]), D2F(ev->transform.matrix.d[15]), } }}; pixman_transform_invert(&surface_transform, &surface_transform); pixman_transform_multiply (&transform, &surface_transform, &transform); } else { pixman_transform_translate(&transform, NULL, pixman_double_to_fixed ((double)-ev->geometry.x), pixman_double_to_fixed ((double)-ev->geometry.y)); } if (ev->surface->buffer_viewport.scaler_set) { double scaler_x, scaler_y, scaler_width, scaler_height; double ratio_x, ratio_y; scaler_x = wl_fixed_to_double(ev->surface->buffer_viewport.src_x); scaler_y = wl_fixed_to_double(ev->surface->buffer_viewport.src_y); scaler_width = wl_fixed_to_double(ev->surface->buffer_viewport.src_width); scaler_height = wl_fixed_to_double(ev->surface->buffer_viewport.src_height); ratio_x = scaler_width / ev->surface->buffer_viewport.dst_width; ratio_y = scaler_height / ev->surface->buffer_viewport.dst_height; pixman_transform_scale(&transform, NULL, pixman_double_to_fixed(ratio_x), pixman_double_to_fixed(ratio_y)); pixman_transform_translate(&transform, NULL, pixman_double_to_fixed(scaler_x), pixman_double_to_fixed(scaler_y)); } pixman_transform_scale(&transform, NULL, pixman_double_to_fixed(ev->surface->buffer_viewport.scale), pixman_double_to_fixed(ev->surface->buffer_viewport.scale)); fw = pixman_int_to_fixed(pixman_image_get_width(ps->image)); fh = pixman_int_to_fixed(pixman_image_get_height(ps->image)); switch (ev->surface->buffer_viewport.transform) { case WL_OUTPUT_TRANSFORM_FLIPPED: case WL_OUTPUT_TRANSFORM_FLIPPED_90: case WL_OUTPUT_TRANSFORM_FLIPPED_180: case WL_OUTPUT_TRANSFORM_FLIPPED_270: pixman_transform_scale(&transform, NULL, pixman_int_to_fixed (-1), pixman_int_to_fixed (1)); pixman_transform_translate(&transform, NULL, fw, 0); break; } switch (ev->surface->buffer_viewport.transform) { default: case WL_OUTPUT_TRANSFORM_NORMAL: case WL_OUTPUT_TRANSFORM_FLIPPED: break; case WL_OUTPUT_TRANSFORM_90: case WL_OUTPUT_TRANSFORM_FLIPPED_90: pixman_transform_rotate(&transform, NULL, 0, pixman_fixed_1); pixman_transform_translate(&transform, NULL, fh, 0); break; case WL_OUTPUT_TRANSFORM_180: case WL_OUTPUT_TRANSFORM_FLIPPED_180: pixman_transform_rotate(&transform, NULL, -pixman_fixed_1, 0); pixman_transform_translate(&transform, NULL, fw, fh); break; case WL_OUTPUT_TRANSFORM_270: case WL_OUTPUT_TRANSFORM_FLIPPED_270: pixman_transform_rotate(&transform, NULL, 0, -pixman_fixed_1); pixman_transform_translate(&transform, NULL, 0, fw); break; } pixman_image_set_transform(ps->image, &transform); if (ev->transform.enabled || output->current_scale != ev->surface->buffer_viewport.scale) pixman_image_set_filter(ps->image, PIXMAN_FILTER_BILINEAR, NULL, 0); else pixman_image_set_filter(ps->image, PIXMAN_FILTER_NEAREST, NULL, 0); if (ps->buffer_ref.buffer) wl_shm_buffer_begin_access(ps->buffer_ref.buffer->shm_buffer); pixman_image_composite32(pixman_op, ps->image, /* src */ NULL /* mask */, po->shadow_image, /* dest */ 0, 0, /* src_x, src_y */ 0, 0, /* mask_x, mask_y */ 0, 0, /* dest_x, dest_y */ pixman_image_get_width (po->shadow_image), /* width */ pixman_image_get_height (po->shadow_image) /* height */); if (ps->buffer_ref.buffer) wl_shm_buffer_end_access(ps->buffer_ref.buffer->shm_buffer); if (pr->repaint_debug) pixman_image_composite32(PIXMAN_OP_OVER, pr->debug_color, /* src */ NULL /* mask */, po->shadow_image, /* dest */ 0, 0, /* src_x, src_y */ 0, 0, /* mask_x, mask_y */ 0, 0, /* dest_x, dest_y */ pixman_image_get_width (po->shadow_image), /* width */ pixman_image_get_height (po->shadow_image) /* height */); pixman_image_set_clip_region32 (po->shadow_image, NULL); pixman_region32_fini(&final_region); }
int main (int argc, char *argv[]) { bench_info_t binfo; pixman_filter_t filter = PIXMAN_FILTER_NEAREST; pixman_format_code_t src_format = PIXMAN_a8r8g8b8; pixman_format_code_t mask_format = 0; pixman_format_code_t dest_format = PIXMAN_a8r8g8b8; pixman_box32_t dest_box = { 0, 0, WIDTH, HEIGHT }; box_48_16_t transformed = { 0 }; int32_t xmin, ymin, xmax, ymax; uint32_t *src, *mask, *dest; binfo.op = PIXMAN_OP_SRC; binfo.mask_image = NULL; pixman_transform_init_identity (&binfo.transform); ++argv; if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'n') { filter = PIXMAN_FILTER_NEAREST; ++argv; --argc; } if (*argv && (*argv)[0] == '-' && (*argv)[1] == 'b') { filter = PIXMAN_FILTER_BILINEAR; ++argv; --argc; } if (argc == 1 || !parse_arguments (argc, argv, &binfo.transform, &binfo.op, &src_format, &mask_format, &dest_format)) { printf ("Usage: affine-bench [-n] [-b] axx [axy] [ayx] [ayy] [combine type]\n"); printf (" [src format] [mask format] [dest format]\n"); printf (" -n : nearest scaling (default)\n"); printf (" -b : bilinear scaling\n"); printf (" axx : x_out:x_in factor\n"); printf (" axy : x_out:y_in factor (default 0)\n"); printf (" ayx : y_out:x_in factor (default 0)\n"); printf (" ayy : y_out:y_in factor (default 1)\n"); printf (" combine type : src, over, in etc (default src)\n"); printf (" src format : a8r8g8b8, r5g6b5 etc (default a8r8g8b8)\n"); printf (" mask format : as for src format, but no mask used if omitted\n"); printf (" dest format : as for src format (default a8r8g8b8)\n"); printf ("The output is a single number in megapixels/second.\n"); return EXIT_FAILURE; } /* Compute required extents for source and mask image so they qualify * for COVER fast paths and get the flags in pixman.c:analyze_extent(). * These computations are for FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR, * but at the same time they also allow COVER_CLIP_NEAREST. */ compute_transformed_extents (&binfo.transform, &dest_box, &transformed); xmin = pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2); ymin = pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2); xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2); ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2); /* Note: * The upper limits can be reduced to the following when fetchers * are guaranteed to not access pixels with zero weight. This concerns * particularly all bilinear samplers. * * xmax = pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2 - pixman_fixed_e); * ymax = pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2 - pixman_fixed_e); * This is equivalent to subtracting 0.5 and rounding up, rather than * subtracting 0.5, rounding down and adding 1. */ binfo.src_x = -xmin; binfo.src_y = -ymin; /* Always over-allocate width by 64 pixels for all src, mask and dst, * so that we can iterate over an x-offset 0..63 in bench (). * This is similar to lowlevel-blt-bench, which uses the same method * to hit different cacheline misalignments. */ create_image (xmax - xmin + 64, ymax - ymin + 1, src_format, filter, &src, &binfo.src_image); if (mask_format) { create_image (xmax - xmin + 64, ymax - ymin + 1, mask_format, filter, &mask, &binfo.mask_image); if ((PIXMAN_FORMAT_R(mask_format) || PIXMAN_FORMAT_G(mask_format) || PIXMAN_FORMAT_B(mask_format))) { pixman_image_set_component_alpha (binfo.mask_image, 1); } } create_image (WIDTH + 64, HEIGHT, dest_format, filter, &dest, &binfo.dest_image); run_benchmark (&binfo); return EXIT_SUCCESS; }
/* * Composite operation with pseudorandom images */ uint32_t test_composite (int testnum, int verbose) { int i; pixman_image_t * src_img; pixman_image_t * dst_img; pixman_transform_t transform; pixman_region16_t clip; int src_width, src_height; int dst_width, dst_height; int src_stride, dst_stride; int src_x, src_y; int dst_x, dst_y; int src_bpp; int dst_bpp; int w, h; pixman_fixed_t scale_x = 65536, scale_y = 65536; pixman_fixed_t translate_x = 0, translate_y = 0; int op; int repeat = 0; int src_fmt, dst_fmt; uint32_t * srcbuf; uint32_t * dstbuf; uint32_t crc32; FLOAT_REGS_CORRUPTION_DETECTOR_START (); lcg_srand (testnum); src_bpp = (lcg_rand_n (2) == 0) ? 2 : 4; dst_bpp = (lcg_rand_n (2) == 0) ? 2 : 4; op = (lcg_rand_n (2) == 0) ? PIXMAN_OP_SRC : PIXMAN_OP_OVER; src_width = lcg_rand_n (MAX_SRC_WIDTH) + 1; src_height = lcg_rand_n (MAX_SRC_HEIGHT) + 1; dst_width = lcg_rand_n (MAX_DST_WIDTH) + 1; dst_height = lcg_rand_n (MAX_DST_HEIGHT) + 1; src_stride = src_width * src_bpp + lcg_rand_n (MAX_STRIDE) * src_bpp; dst_stride = dst_width * dst_bpp + lcg_rand_n (MAX_STRIDE) * dst_bpp; if (src_stride & 3) src_stride += 2; if (dst_stride & 3) dst_stride += 2; src_x = -(src_width / 4) + lcg_rand_n (src_width * 3 / 2); src_y = -(src_height / 4) + lcg_rand_n (src_height * 3 / 2); dst_x = -(dst_width / 4) + lcg_rand_n (dst_width * 3 / 2); dst_y = -(dst_height / 4) + lcg_rand_n (dst_height * 3 / 2); w = lcg_rand_n (dst_width * 3 / 2 - dst_x); h = lcg_rand_n (dst_height * 3 / 2 - dst_y); srcbuf = (uint32_t *)malloc (src_stride * src_height); dstbuf = (uint32_t *)malloc (dst_stride * dst_height); for (i = 0; i < src_stride * src_height; i++) *((uint8_t *)srcbuf + i) = lcg_rand_n (256); for (i = 0; i < dst_stride * dst_height; i++) *((uint8_t *)dstbuf + i) = lcg_rand_n (256); src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5; src_img = pixman_image_create_bits ( src_fmt, src_width, src_height, srcbuf, src_stride); dst_img = pixman_image_create_bits ( dst_fmt, dst_width, dst_height, dstbuf, dst_stride); image_endian_swap (src_img, src_bpp * 8); image_endian_swap (dst_img, dst_bpp * 8); pixman_transform_init_identity (&transform); if (lcg_rand_n (8) > 0) { scale_x = -32768 * 3 + lcg_rand_N (65536 * 5); scale_y = -32768 * 3 + lcg_rand_N (65536 * 5); translate_x = lcg_rand_N (65536); translate_y = lcg_rand_N (65536); pixman_transform_init_scale (&transform, scale_x, scale_y); pixman_transform_translate (&transform, NULL, translate_x, translate_y); } if (lcg_rand_n (4) > 0) { int c = lcg_rand_N (2 * 65536) - 65536; int s = lcg_rand_N (2 * 65536) - 65536; pixman_transform_rotate (&transform, NULL, c, s); } pixman_image_set_transform (src_img, &transform); switch (lcg_rand_n (4)) { case 0: repeat = PIXMAN_REPEAT_NONE; break; case 1: repeat = PIXMAN_REPEAT_NORMAL; break; case 2: repeat = PIXMAN_REPEAT_PAD; break; case 3: repeat = PIXMAN_REPEAT_REFLECT; break; default: break; } pixman_image_set_repeat (src_img, repeat); if (lcg_rand_n (2)) pixman_image_set_filter (src_img, PIXMAN_FILTER_NEAREST, NULL, 0); else pixman_image_set_filter (src_img, PIXMAN_FILTER_BILINEAR, NULL, 0); if (verbose) { printf ("src_fmt=%08X, dst_fmt=%08X\n", src_fmt, dst_fmt); printf ("op=%d, scale_x=%d, scale_y=%d, repeat=%d\n", op, scale_x, scale_y, repeat); printf ("translate_x=%d, translate_y=%d\n", translate_x, translate_y); printf ("src_width=%d, src_height=%d, dst_width=%d, dst_height=%d\n", src_width, src_height, dst_width, dst_height); printf ("src_x=%d, src_y=%d, dst_x=%d, dst_y=%d\n", src_x, src_y, dst_x, dst_y); printf ("w=%d, h=%d\n", w, h); } if (lcg_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; int n = lcg_rand_n (2) + 1; for (i = 0; i < n; i++) { clip_boxes[i].x1 = lcg_rand_n (src_width); clip_boxes[i].y1 = lcg_rand_n (src_height); clip_boxes[i].x2 = clip_boxes[i].x1 + lcg_rand_n (src_width - clip_boxes[i].x1); clip_boxes[i].y2 = clip_boxes[i].y1 + lcg_rand_n (src_height - clip_boxes[i].y1); if (verbose) { printf ("source clip box: [%d,%d-%d,%d]\n", clip_boxes[i].x1, clip_boxes[i].y1, clip_boxes[i].x2, clip_boxes[i].y2); } } pixman_region_init_rects (&clip, clip_boxes, n); pixman_image_set_clip_region (src_img, &clip); pixman_image_set_source_clipping (src_img, 1); pixman_region_fini (&clip); } if (lcg_rand_n (8) == 0) { pixman_box16_t clip_boxes[2]; int n = lcg_rand_n (2) + 1; for (i = 0; i < n; i++) { clip_boxes[i].x1 = lcg_rand_n (dst_width); clip_boxes[i].y1 = lcg_rand_n (dst_height); clip_boxes[i].x2 = clip_boxes[i].x1 + lcg_rand_n (dst_width - clip_boxes[i].x1); clip_boxes[i].y2 = clip_boxes[i].y1 + lcg_rand_n (dst_height - clip_boxes[i].y1); if (verbose) { printf ("destination clip box: [%d,%d-%d,%d]\n", clip_boxes[i].x1, clip_boxes[i].y1, clip_boxes[i].x2, clip_boxes[i].y2); } } pixman_region_init_rects (&clip, clip_boxes, n); pixman_image_set_clip_region (dst_img, &clip); pixman_region_fini (&clip); } pixman_image_composite (op, src_img, NULL, dst_img, src_x, src_y, 0, 0, dst_x, dst_y, w, h); if (dst_fmt == PIXMAN_x8r8g8b8) { /* ignore unused part */ for (i = 0; i < dst_stride * dst_height / 4; i++) dstbuf[i] &= 0xFFFFFF; } image_endian_swap (dst_img, dst_bpp * 8); if (verbose) { int j; for (i = 0; i < dst_height; i++) { for (j = 0; j < dst_stride; j++) printf ("%02X ", *((uint8_t *)dstbuf + i * dst_stride + j)); printf ("\n"); } } pixman_image_unref (src_img); pixman_image_unref (dst_img); crc32 = compute_crc32 (0, dstbuf, dst_stride * dst_height); free (srcbuf); free (dstbuf); FLOAT_REGS_CORRUPTION_DETECTOR_FINISH (); return crc32; }
int main (int argc, char **argv) { pixman_transform_t transform; pixman_image_t *src_img, *dest_img; int i, j; enable_fp_exceptions (); dest_img = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, NULL, 0); pixman_transform_init_identity (&transform); /* * The create_radial() function returns gradients centered in the * origin and whose interesting part fits a 1x1 square. We want to * paint these gradients on a SIZExSIZE square and to make things * easier we want the origin in the top-left corner of the square * we want to see. */ pixman_transform_translate (NULL, &transform, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.5)); pixman_transform_scale (NULL, &transform, pixman_double_to_fixed (SIZE), pixman_double_to_fixed (SIZE)); /* * Gradients are evaluated at the center of each pixel, so we need * to translate by half a pixel to trigger some interesting * cornercases. In particular, the original implementation of PDF * radial gradients tried to divide by 0 when using this transform * on the "tangent circles" cases. */ pixman_transform_translate (NULL, &transform, pixman_double_to_fixed (0.5), pixman_double_to_fixed (0.5)); for (i = 0; i < NUM_GRADIENTS; i++) { src_img = create_radial (i); pixman_image_set_transform (src_img, &transform); for (j = 0; j < NUM_REPEAT; j++) { pixman_image_set_repeat (src_img, repeat[j]); pixman_image_composite32 (PIXMAN_OP_OVER, src_img, NULL, dest_img, 0, 0, 0, 0, i * SIZE, j * SIZE, SIZE, SIZE); } pixman_image_unref (src_img); } show_image (dest_img); pixman_image_unref (dest_img); return 0; }