mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 992486 - Part 1: Add API to RotatedContentBuffer for drawing in multiple passes. r=roc
This commit is contained in:
parent
166126a333
commit
031f178fa9
@ -531,12 +531,14 @@ RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer,
|
||||
"newRotation out of bounds");
|
||||
int32_t xBoundary = destBufferRect.XMost() - newRotation.x;
|
||||
int32_t yBoundary = destBufferRect.YMost() - newRotation.y;
|
||||
if ((drawBounds.x < xBoundary && xBoundary < drawBounds.XMost()) ||
|
||||
(drawBounds.y < yBoundary && yBoundary < drawBounds.YMost()) ||
|
||||
bool drawWrapsBuffer = (drawBounds.x < xBoundary && xBoundary < drawBounds.XMost()) ||
|
||||
(drawBounds.y < yBoundary && yBoundary < drawBounds.YMost());
|
||||
if ((drawWrapsBuffer && !(aFlags & PAINT_CAN_DRAW_ROTATED)) ||
|
||||
(newRotation != nsIntPoint(0,0) && !canHaveRotation)) {
|
||||
// The stuff we need to redraw will wrap around an edge of the
|
||||
// buffer, so move the pixels we can keep into a position that
|
||||
// lets us redraw in just one quadrant.
|
||||
// buffer (and the caller doesn't know how to support that), so
|
||||
// move the pixels we can keep into a position that lets us
|
||||
// redraw in just one quadrant.
|
||||
if (mBufferRotation == nsIntPoint(0,0)) {
|
||||
nsIntRect srcRect(nsIntPoint(0, 0), mBufferRect.Size());
|
||||
nsIntPoint dest = mBufferRect.TopLeft() - destBufferRect.TopLeft();
|
||||
@ -674,19 +676,44 @@ RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer,
|
||||
}
|
||||
|
||||
DrawTarget*
|
||||
RotatedContentBuffer::BorrowDrawTargetForPainting(ThebesLayer* aLayer,
|
||||
const PaintState& aPaintState)
|
||||
RotatedContentBuffer::BorrowDrawTargetForPainting(const PaintState& aPaintState,
|
||||
DrawIterator* aIter /* = nullptr */)
|
||||
{
|
||||
if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DrawTarget* result = BorrowDrawTargetForQuadrantUpdate(aPaintState.mRegionToDraw.GetBounds(),
|
||||
const nsIntRegion* drawPtr;
|
||||
if (aIter) {
|
||||
// If an iterator was provided, then BeginPaint must have been run with
|
||||
// PAINT_CAN_DRAW_ROTATED, and the draw region might cover multiple quadrants.
|
||||
// Iterate over each of them, and return an appropriate buffer each time we find
|
||||
// one that intersects the draw region. The iterator mCount value tracks which
|
||||
// quadrants we have considered across multiple calls to this function.
|
||||
aIter->mDrawRegion.SetEmpty();
|
||||
while (aIter->mCount < 4) {
|
||||
nsIntRect quadrant = GetQuadrantRectangle((aIter->mCount & 1) ? LEFT : RIGHT,
|
||||
(aIter->mCount & 2) ? TOP : BOTTOM);
|
||||
aIter->mDrawRegion.And(aPaintState.mRegionToDraw, quadrant);
|
||||
aIter->mCount++;
|
||||
if (!aIter->mDrawRegion.IsEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (aIter->mDrawRegion.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
drawPtr = &aIter->mDrawRegion;
|
||||
} else {
|
||||
drawPtr = &aPaintState.mRegionToDraw;
|
||||
}
|
||||
|
||||
DrawTarget* result = BorrowDrawTargetForQuadrantUpdate(drawPtr->GetBounds(),
|
||||
BUFFER_BOTH);
|
||||
|
||||
if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
|
||||
MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
|
||||
nsIntRegionRectIterator iter(aPaintState.mRegionToDraw);
|
||||
nsIntRegionRectIterator iter(*drawPtr);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
|
||||
@ -696,7 +723,7 @@ RotatedContentBuffer::BorrowDrawTargetForPainting(ThebesLayer* aLayer,
|
||||
}
|
||||
} else if (aPaintState.mContentType == gfxContentType::COLOR_ALPHA && HaveBuffer()) {
|
||||
// HaveBuffer() => we have an existing buffer that we must clear
|
||||
nsIntRegionRectIterator iter(aPaintState.mRegionToDraw);
|
||||
nsIntRegionRectIterator iter(*drawPtr);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
result->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
||||
|
@ -223,7 +223,8 @@ public:
|
||||
|
||||
enum {
|
||||
PAINT_WILL_RESAMPLE = 0x01,
|
||||
PAINT_NO_ROTATION = 0x02
|
||||
PAINT_NO_ROTATION = 0x02,
|
||||
PAINT_CAN_DRAW_ROTATED = 0x04
|
||||
};
|
||||
/**
|
||||
* Start a drawing operation. This returns a PaintState describing what
|
||||
@ -240,18 +241,44 @@ public:
|
||||
* make the entire buffer contents valid (since we don't want to sample
|
||||
* invalid pixels outside the visible region, if the visible region doesn't
|
||||
* fill the buffer bounds).
|
||||
* PAINT_CAN_DRAW_ROTATED can be passed if the caller supports drawing
|
||||
* rotated content that crosses the physical buffer boundary. The caller
|
||||
* will need to call BorrowDrawTargetForPainting multiple times to achieve
|
||||
* this.
|
||||
*/
|
||||
PaintState BeginPaint(ThebesLayer* aLayer,
|
||||
uint32_t aFlags);
|
||||
|
||||
struct DrawIterator {
|
||||
friend class RotatedContentBuffer;
|
||||
friend class ContentClientIncremental;
|
||||
DrawIterator()
|
||||
: mCount(0)
|
||||
{}
|
||||
|
||||
nsIntRegion mDrawRegion;
|
||||
|
||||
private:
|
||||
uint32_t mCount;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch a DrawTarget for rendering. The DrawTarget remains owned by
|
||||
* this. See notes on BorrowDrawTargetForQuadrantUpdate.
|
||||
* May return null. If the return value is non-null, it must be
|
||||
* 'un-borrowed' using ReturnDrawTarget.
|
||||
*
|
||||
* If PAINT_CAN_DRAW_ROTATED was specified for BeginPaint, then the caller
|
||||
* must call this function repeatedly (with an iterator) until it returns
|
||||
* nullptr. The caller should draw the mDrawRegion of the iterator instead
|
||||
* of mRegionToDraw in the PaintState.
|
||||
*
|
||||
* @param aPaintState Paint state data returned by a call to BeginPaint
|
||||
* @param aIter Paint state iterator. Only required if PAINT_CAN_DRAW_ROTATED
|
||||
* was specified to BeginPaint.
|
||||
*/
|
||||
gfx::DrawTarget* BorrowDrawTargetForPainting(ThebesLayer* aLayer,
|
||||
const PaintState& aPaintState);
|
||||
gfx::DrawTarget* BorrowDrawTargetForPainting(const PaintState& aPaintState,
|
||||
DrawIterator* aIter = nullptr);
|
||||
|
||||
enum {
|
||||
ALLOW_REPEAT = 0x01,
|
||||
|
@ -186,7 +186,7 @@ BasicThebesLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||
mContentClient->BeginPaintBuffer(this, flags);
|
||||
mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
|
||||
|
||||
if (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(this, state)) {
|
||||
if (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state)) {
|
||||
// The area that became invalid and is visible needs to be repainted
|
||||
// (this could be the whole visible area if our buffer switched
|
||||
// from RGB to RGBA, because we might need to repaint with
|
||||
|
@ -56,7 +56,7 @@ ClientThebesLayer::PaintThebes()
|
||||
mContentClient->BeginPaintBuffer(this, flags);
|
||||
mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
|
||||
|
||||
if (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(this, state)) {
|
||||
if (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state)) {
|
||||
// The area that became invalid and is visible needs to be repainted
|
||||
// (this could be the whole visible area if our buffer switched
|
||||
// from RGB to RGBA, because we might need to repaint with
|
||||
|
@ -785,13 +785,20 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
}
|
||||
|
||||
DrawTarget*
|
||||
ContentClientIncremental::BorrowDrawTargetForPainting(ThebesLayer* aLayer,
|
||||
const PaintState& aPaintState)
|
||||
ContentClientIncremental::BorrowDrawTargetForPainting(const PaintState& aPaintState,
|
||||
RotatedContentBuffer::DrawIterator* aIter)
|
||||
{
|
||||
if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aIter) {
|
||||
if (aIter->mCount++ > 0) {
|
||||
return nullptr;
|
||||
}
|
||||
aIter->mDrawRegion = aPaintState.mRegionToDraw;
|
||||
}
|
||||
|
||||
DrawTarget* result = nullptr;
|
||||
|
||||
nsIntRect drawBounds = aPaintState.mRegionToDraw.GetBounds();
|
||||
|
@ -95,8 +95,8 @@ public:
|
||||
virtual void Clear() = 0;
|
||||
virtual RotatedContentBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
uint32_t aFlags) = 0;
|
||||
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(ThebesLayer* aLayer,
|
||||
const RotatedContentBuffer::PaintState& aPaintState) = 0;
|
||||
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(const RotatedContentBuffer::PaintState& aPaintState,
|
||||
RotatedContentBuffer::DrawIterator* aIter = nullptr) = 0;
|
||||
virtual void ReturnDrawTargetToBuffer(gfx::DrawTarget*& aReturned) = 0;
|
||||
|
||||
virtual void PrepareFrame() {}
|
||||
@ -143,10 +143,10 @@ public:
|
||||
{
|
||||
return RotatedContentBuffer::BeginPaint(aLayer, aFlags);
|
||||
}
|
||||
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(ThebesLayer* aLayer,
|
||||
const PaintState& aPaintState) MOZ_OVERRIDE
|
||||
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(const PaintState& aPaintState,
|
||||
RotatedContentBuffer::DrawIterator* aIter = nullptr) MOZ_OVERRIDE
|
||||
{
|
||||
return RotatedContentBuffer::BorrowDrawTargetForPainting(aLayer, aPaintState);
|
||||
return RotatedContentBuffer::BorrowDrawTargetForPainting(aPaintState, aIter);
|
||||
}
|
||||
virtual void ReturnDrawTargetToBuffer(gfx::DrawTarget*& aReturned) MOZ_OVERRIDE
|
||||
{
|
||||
@ -218,10 +218,10 @@ public:
|
||||
{
|
||||
return RotatedContentBuffer::BeginPaint(aLayer, aFlags);
|
||||
}
|
||||
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(ThebesLayer* aLayer,
|
||||
const PaintState& aPaintState) MOZ_OVERRIDE
|
||||
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(const PaintState& aPaintState,
|
||||
RotatedContentBuffer::DrawIterator* aIter = nullptr) MOZ_OVERRIDE
|
||||
{
|
||||
return RotatedContentBuffer::BorrowDrawTargetForPainting(aLayer, aPaintState);
|
||||
return RotatedContentBuffer::BorrowDrawTargetForPainting(aPaintState, aIter);
|
||||
}
|
||||
virtual void ReturnDrawTargetToBuffer(gfx::DrawTarget*& aReturned) MOZ_OVERRIDE
|
||||
{
|
||||
@ -420,8 +420,8 @@ public:
|
||||
|
||||
virtual PaintState BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
uint32_t aFlags) MOZ_OVERRIDE;
|
||||
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(ThebesLayer* aLayer,
|
||||
const PaintState& aPaintState) MOZ_OVERRIDE;
|
||||
virtual gfx::DrawTarget* BorrowDrawTargetForPainting(const PaintState& aPaintState,
|
||||
RotatedContentBuffer::DrawIterator* aIter = nullptr) MOZ_OVERRIDE;
|
||||
virtual void ReturnDrawTargetToBuffer(gfx::DrawTarget*& aReturned) MOZ_OVERRIDE
|
||||
{
|
||||
BorrowDrawTarget::ReturnDrawTarget(aReturned);
|
||||
|
Loading…
Reference in New Issue
Block a user