diff options
| author | Kristian Høgsberg <krh@redhat.com> | 2008-11-02 15:50:55 -0500 |
|---|---|---|
| committer | Kristian Høgsberg <krh@redhat.com> | 2008-11-06 10:53:02 -0500 |
| commit | 1b2f4390f54ed9f5ed0f1440c2fd620ec06e1590 (patch) | |
| tree | 6cb035caf17bb29dd0fec635a4b946c93f4d0868 /pointer.c | |
| parent | d3fa34ca298e734d4e7f14a7023848ff13360109 (diff) | |
| download | wayland-1b2f4390f54ed9f5ed0f1440c2fd620ec06e1590.tar.gz wayland-1b2f4390f54ed9f5ed0f1440c2fd620ec06e1590.tar.xz wayland-1b2f4390f54ed9f5ed0f1440c2fd620ec06e1590.zip | |
Unpremultiply cairo surface data.
Diffstat (limited to 'pointer.c')
| -rw-r--r-- | pointer.c | 37 |
1 files changed, 34 insertions, 3 deletions
@@ -15,16 +15,48 @@ static const char gem_device[] = "/dev/dri/card0"; static const char socket_name[] = "\0wayland"; +static void +unpremultiply_data(uint8_t *data, int width, int height, int stride) +{ + unsigned int i, j; + uint8_t *row; + + for (j = 0; j < height; j++) { + row = data + j * stride; + + for (i = 0; i < width; i++) { + uint8_t *b = &row[i * 4]; + uint32_t pixel; + uint8_t alpha; + + memcpy (&pixel, b, sizeof (uint32_t)); + alpha = (pixel & 0xff000000) >> 24; + if (alpha == 0) { + b[0] = b[1] = b[2] = b[3] = 0; + } else { + b[0] = (((pixel & 0xff0000) >> 16) * 255 + alpha / 2) / alpha; + b[1] = (((pixel & 0x00ff00) >> 8) * 255 + alpha / 2) / alpha; + b[2] = (((pixel & 0x0000ff) >> 0) * 255 + alpha / 2) / alpha; + b[3] = alpha; + } + } + } +} + static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface) { struct drm_i915_gem_create create; struct drm_gem_flink flink; struct drm_i915_gem_pwrite pwrite; int32_t width, height, stride; + void *data; width = cairo_image_surface_get_width(surface); height = cairo_image_surface_get_height(surface); stride = cairo_image_surface_get_stride(surface); + data = cairo_image_surface_get_data(surface); + + unpremultiply_data(data, width, height, stride); memset(&create, 0, sizeof(create)); create.size = height * stride; @@ -37,8 +69,7 @@ static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface) pwrite.handle = create.handle; pwrite.offset = 0; pwrite.size = height * stride; - pwrite.data_ptr = (uint64_t) (uintptr_t) - cairo_image_surface_get_data(surface); + pwrite.data_ptr = (uint64_t) (uintptr_t) data; if (ioctl(fd, DRM_IOCTL_I915_GEM_PWRITE, &pwrite) < 0) { fprintf(stderr, "gem pwrite failed: %m\n"); return 0; @@ -68,7 +99,7 @@ static uint32_t name_cairo_surface(int fd, cairo_surface_t *surface) static void * draw_pointer(int width, int height) { - const int d = 2, end = 4, tx = 2, ty = 6, dx = 5, dy = 4; + const int d = 2, end = 4, tx = 2, ty = 6, dx = 4, dy = 4; cairo_surface_t *surface; cairo_t *cr; |
