author | Bas Schouten <bschouten@mozilla.com> |
Wed, 04 Jul 2012 20:23:16 +0200 | |
changeset 98335 | 94d461c799fd965451180ed91862b3433c7eb538 |
parent 98334 | a5b33148ae58dcb75935648bde60dab70c4bf8ba |
child 98336 | 555989fb3764d50b107fa7cd49c0f1d4fdfb5622 |
child 98386 | 1ccd7094cd5e8ded37777bdd053a47bf47985f46 |
push id | 23043 |
push user | ryanvm@gmail.com |
push date | Wed, 04 Jul 2012 23:22:35 +0000 |
treeherder | mozilla-central@555989fb3764 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jrmuizel |
bugs | 770033 |
milestone | 16.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/2d/DrawTargetD2D.cpp | file | annotate | diff | comparison | revisions | |
gfx/2d/DrawTargetD2D.h | file | annotate | diff | comparison | revisions |
--- a/gfx/2d/DrawTargetD2D.cpp +++ b/gfx/2d/DrawTargetD2D.cpp @@ -2061,17 +2061,17 @@ DrawTargetD2D::CreateBrushForPattern(con bitmap = surf->GetBitmap(mRT); AddDependencyOnSource(surf); } break; case SURFACE_DATA: { DataSourceSurface *dataSurf = static_cast<DataSourceSurface*>(pat->mSurface.get()); - bitmap = CreatePartialBitmapForSurface(dataSurf, mat); + bitmap = CreatePartialBitmapForSurface(dataSurf, mat, pat->mExtendMode); if (!bitmap) { return NULL; } } break; default: break; @@ -2296,18 +2296,19 @@ DrawTargetD2D::CreateTextureForAnalysis( delete [] texture; if (FAILED(hr)) { return NULL; } return tex; } + TemporaryRef<ID2D1Bitmap> -DrawTargetD2D::CreatePartialBitmapForSurface(DataSourceSurface *aSurface, Matrix &aMatrix) +DrawTargetD2D::CreatePartialBitmapForSurface(DataSourceSurface *aSurface, Matrix &aMatrix, ExtendMode aExtendMode) { RefPtr<ID2D1Bitmap> bitmap; // This is where things get complicated. The source surface was // created for a surface that was too large to fit in a texture. // We'll need to figure out if we can work with a partial upload // or downsample in software. @@ -2323,26 +2324,50 @@ DrawTargetD2D::CreatePartialBitmapForSur // Calculate the rectangle of the source mapped to our surface. rect = invTransform.TransformBounds(rect); rect.RoundOut(); IntSize size = aSurface->GetSize(); Rect uploadRect(0, 0, size.width, size.height); - // Calculate the rectangle on the source bitmap that touches our - // surface. - uploadRect = uploadRect.Intersect(rect); - - if (uploadRect.IsEmpty()) { - // This bitmap does not cover anything on the screen. XXX - - // we need to deal with EXTEND modes here! - return NULL; + // Limit the uploadRect as much as possible without supporting discontiguous uploads + // + // region we will paint from + // uploadRect + // .---------------. .---------------. resulting uploadRect + // | |rect | | + // | .---------. .----. .----. .---------------. + // | | | ----> | | | | ----> | | + // | '---------' '----' '----' '---------------' + // '---------------' '---------------' + // + // + + if (uploadRect.Contains(rect)) { + // Extend mode is irrelevant, the displayed rect is completely contained + // by the source bitmap. + uploadRect = rect; + } else if (aExtendMode == EXTEND_CLAMP && uploadRect.Intersects(rect)) { + // Calculate the rectangle on the source bitmap that touches our + // surface, and upload that, for EXTEND_CLAMP we can actually guarantee + // correct behaviour in this case. + uploadRect = uploadRect.Intersect(rect); + + // We now proceed to check if we can limit at least one dimension of the + // upload rect safely without looking at extend mode. + } else if (rect.x >= 0 && rect.XMost() < size.width) { + uploadRect.x = rect.x; + uploadRect.width = rect.width; + } else if (rect.y >= 0 && rect.YMost() < size.height) { + uploadRect.y = rect.y; + uploadRect.height = rect.height; } + int stride = aSurface->Stride(); if (uploadRect.width <= mRT->GetMaximumBitmapSize() && uploadRect.height <= mRT->GetMaximumBitmapSize()) { // A partial upload will suffice. mRT->CreateBitmap(D2D1::SizeU(uint32_t(uploadRect.width), uint32_t(uploadRect.height)), aSurface->GetData() + int(uploadRect.x) * 4 + int(uploadRect.y) * stride,
--- a/gfx/2d/DrawTargetD2D.h +++ b/gfx/2d/DrawTargetD2D.h @@ -187,17 +187,18 @@ private: TemporaryRef<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f); TemporaryRef<ID3D10Texture2D> CreateGradientTexture(const GradientStopsD2D *aStops); TemporaryRef<ID3D10Texture2D> CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, const IntRect &aBounds); // This creates a (partially) uploaded bitmap for a DataSourceSurface. It // uploads the minimum requirement and possibly downscales. It adjusts the // input Matrix to compensate. - TemporaryRef<ID2D1Bitmap> CreatePartialBitmapForSurface(DataSourceSurface *aSurface, Matrix &aMatrix); + TemporaryRef<ID2D1Bitmap> CreatePartialBitmapForSurface(DataSourceSurface *aSurface, Matrix &aMatrix, + ExtendMode aExtendMode); void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern); void SetupStateForRendering(); static const uint32_t test = 4; IntSize mSize;