author | Jeff Muizelaar <jmuizelaar@mozilla.com> |
Tue, 16 Aug 2011 19:07:49 -0400 | |
changeset 75416 | be62b6c4392a9eb07d5a570ba9a1450c1aa8d805 |
parent 75415 | 0c4897315acce9bc8fc97cd1b9bb810cbd356f64 |
child 75417 | 8f315a50dcc9736e0efa47d8110fc14dc3d80415 |
push id | 21023 |
push user | mak77@bonardo.net |
push date | Thu, 18 Aug 2011 09:39:20 +0000 |
treeherder | mozilla-central@f69a10f23bf3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bas |
bugs | 671428 |
milestone | 9.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
gfx/cairo/cairo/src/cairo-d2d-surface.cpp | file | annotate | diff | comparison | revisions | |
gfx/cairo/cairo/src/cairoint.h | file | annotate | diff | comparison | revisions |
--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp +++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp @@ -2505,21 +2505,38 @@ static cairo_status_t // We need to release the device after calling the constructor, since the // device destruction may release the D3D/D2D libraries. cairo_device_t *device = &d2dsurf->device->base; d2dsurf->~cairo_d2d_surface_t(); cairo_release_device(device); return CAIRO_STATUS_SUCCESS; } +/* The input types for src and dst don't match because in our particular use case, copying from a texture, + * those types don't match. */ +static void +_copy_data_to_different_stride(unsigned char *dst, int dst_stride, void *src, UINT src_stride, int height) +{ + + unsigned char *src_p = (unsigned char *)src; + int min_stride = MIN(dst_stride, src_stride); + while (height) { + memcpy(dst, src_p, min_stride); + height--; + dst += dst_stride; + src_p += src_stride; + } +} + static cairo_status_t _cairo_d2d_acquire_source_image(void *abstract_surface, - cairo_image_surface_t **image_out, + cairo_image_surface_t **image_out_ret, void **image_extra) { + cairo_surface_t *image_out; cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(abstract_surface); _cairo_d2d_flush(d2dsurf); HRESULT hr; D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize(); RefPtr<ID3D10Texture2D> softTexture; @@ -2547,34 +2564,46 @@ static cairo_status_t d2dsurf->device->mD3D10Device->CopyResource(softTexture, d2dsurf->surface); D3D10_MAPPED_TEXTURE2D data; hr = softTexture->Map(0, D3D10_MAP_READ_WRITE, 0, &data); if (FAILED(hr)) { return _cairo_error(CAIRO_STATUS_NO_DEVICE); } - *image_out = - (cairo_image_surface_t*)cairo_image_surface_create_for_data((unsigned char*)data.pData, - d2dsurf->format, - size.width, - size.height, - data.RowPitch); - - if (cairo_surface_status(&((*image_out)->base))) { - volatile cairo_status_t flambo[10]; - for (int i=0; i<10; i++) { - flambo[i] = cairo_surface_status(&((*image_out)->base)); - } - volatile int p = 0; - p = 5/p; + + if (_cairo_valid_stride_alignment(data.RowPitch)) { + image_out = cairo_image_surface_create_for_data((unsigned char*)data.pData, + d2dsurf->format, + size.width, + size.height, + data.RowPitch); + } else { + /* Slow path used when the stride doesn't match our requirements. + * This is possible on at least the Intel driver 8.15.10.2302. + * + * Create a new image surface and copy our data into it */ + image_out = cairo_image_surface_create(d2dsurf->format, + size.width, + size.height); + _copy_data_to_different_stride(cairo_image_surface_get_data(image_out), + cairo_image_surface_get_stride(image_out), + data.pData, + data.RowPitch, + size.height); + } + /* these are the only surface statuses we expect */ + assert(cairo_surface_status(image_out) == CAIRO_STATUS_SUCCESS || + cairo_surface_status(image_out) == CAIRO_STATUS_NO_MEMORY); + *image_extra = softTexture.forget(); - - return CAIRO_STATUS_SUCCESS; + *image_out_ret = (cairo_image_surface_t*)image_out; + + return cairo_surface_status(image_out); } static void _cairo_d2d_release_source_image(void *abstract_surface, cairo_image_surface_t *image, void *image_extra) { if (((cairo_surface_t*)abstract_surface)->type != CAIRO_SURFACE_TYPE_D2D) {
--- a/gfx/cairo/cairo/src/cairoint.h +++ b/gfx/cairo/cairo/src/cairoint.h @@ -1903,16 +1903,22 @@ cairo_private void ((((bpp)*(w)+7)/8 + CAIRO_STRIDE_ALIGNMENT-1) & -CAIRO_STRIDE_ALIGNMENT) #define CAIRO_CONTENT_VALID(content) ((content) && \ (((content) & ~(CAIRO_CONTENT_COLOR | \ CAIRO_CONTENT_ALPHA | \ CAIRO_CONTENT_COLOR_ALPHA))\ == 0)) +static inline cairo_bool_t +_cairo_valid_stride_alignment(int stride) +{ + return !(stride & (CAIRO_STRIDE_ALIGNMENT-1)); +} + cairo_private int _cairo_format_bits_per_pixel (cairo_format_t format) cairo_const; cairo_private cairo_format_t _cairo_format_from_content (cairo_content_t content) cairo_const; cairo_private cairo_format_t _cairo_format_from_pixman_format (pixman_format_code_t pixman_format);