gecko-dev/gfx/layers/RotatedBuffer.cpp

530 строки
17 KiB
C++
Исходник Обычный вид История

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
2012-05-21 15:12:37 +04:00
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RotatedBuffer.h"
#include <sys/types.h> // for int32_t
#include <algorithm> // for max
#include "BasicImplData.h" // for BasicImplData
#include "BasicLayersImpl.h" // for ToData
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange. This patch makes the following changes to the macros. - Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was mostly misused. - Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is universally available now anyway. - Combines the first two string literal arguments of PROFILER_LABEL and PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for them to be separate, and it forced a '::' in the label, which isn't always appropriate. Also, the meaning of the "name_space" argument was interpreted in an interesting variety of ways. - Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make it clearer they construct RAII objects rather than just being function calls. (I myself have screwed up the scoping because of this in the past.) - Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so the caller doesn't need to. This makes a *lot* more of the uses fit onto a single line. The patch also makes the following changes to the macro uses (beyond those required by the changes described above). - Fixes a bunch of labels that had gotten out of sync with the name of the class and/or function that encloses them. - Removes a useless PROFILER_LABEL use within a trivial scope in EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving any useful purpose. It also serves as extra evidence that the AUTO_ prefix is a good idea. - Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is done within them, instead of at their callsites, because that's a more standard way of doing things. --HG-- extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
#include "GeckoProfiler.h" // for AUTO_PROFILER_LABEL
#include "Layers.h" // for PaintedLayer, Layer, etc
#include "gfxPlatform.h" // for gfxPlatform
#include "gfxPrefs.h" // for gfxPrefs
#include "gfxUtils.h" // for gfxUtils
#include "mozilla/ArrayUtils.h" // for ArrayLength
#include "mozilla/gfx/BasePoint.h" // for BasePoint
#include "mozilla/gfx/BaseRect.h" // for BaseRect
#include "mozilla/gfx/BaseSize.h" // for BaseSize
#include "mozilla/gfx/Matrix.h" // for Matrix
#include "mozilla/gfx/Point.h" // for Point, IntPoint
#include "mozilla/gfx/Rect.h" // for Rect, IntRect
#include "mozilla/gfx/Types.h" // for ExtendMode::ExtendMode::CLAMP, etc
#include "mozilla/layers/ShadowLayers.h" // for ShadowableLayer
#include "mozilla/layers/TextureClient.h" // for TextureClient
#include "mozilla/Move.h" // for Move
#include "mozilla/gfx/Point.h" // for IntSize
#include "gfx2DGlue.h"
#include "nsLayoutUtils.h" // for invalidation debugging
#include "PaintThread.h"
namespace mozilla {
using namespace gfx;
namespace layers {
void
BorrowDrawTarget::ReturnDrawTarget(gfx::DrawTarget*& aReturned)
{
MOZ_ASSERT(mLoanedDrawTarget);
MOZ_ASSERT(aReturned == mLoanedDrawTarget);
if (mLoanedDrawTarget) {
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
mLoanedDrawTarget->SetTransform(mLoanedTransform);
mLoanedDrawTarget = nullptr;
}
aReturned = nullptr;
}
IntRect
RotatedBuffer::GetQuadrantRectangle(XSide aXSide, YSide aYSide) const
{
// quadrantTranslation is the amount we translate the top-left
// of the quadrant by to get coordinates relative to the layer
IntPoint quadrantTranslation = -mBufferRotation;
quadrantTranslation.x += aXSide == LEFT ? mBufferRect.Width() : 0;
quadrantTranslation.y += aYSide == TOP ? mBufferRect.Height() : 0;
return mBufferRect + quadrantTranslation;
}
Rect
RotatedBuffer::GetSourceRectangle(XSide aXSide, YSide aYSide) const
{
Rect result;
if (aXSide == LEFT) {
result.SetBoxX(0, mBufferRotation.x);
} else {
result.SetBoxX(mBufferRotation.x, mBufferRect.Width());
}
if (aYSide == TOP) {
result.SetBoxY(0, mBufferRotation.y);
} else {
result.SetBoxY(mBufferRotation.y, mBufferRect.Height());
}
return result;
}
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
void
RotatedBuffer::BeginCapture()
{
RefPtr<gfx::DrawTarget> target = GetBufferTarget();
MOZ_ASSERT(!mCapture);
MOZ_ASSERT(target);
mCapture = Factory::CreateCaptureDrawTargetForTarget(target, gfxPrefs::LayersOMTPCaptureLimit());
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
}
RefPtr<gfx::DrawTargetCapture>
RotatedBuffer::EndCapture()
{
MOZ_ASSERT(mCapture);
return std::move(mCapture);
}
/**
* @param aXSide LEFT means we draw from the left side of the buffer (which
* is drawn on the right side of mBufferRect). RIGHT means we draw from
* the right side of the buffer (which is drawn on the left side of
* mBufferRect).
* @param aYSide TOP means we draw from the top side of the buffer (which
* is drawn on the bottom side of mBufferRect). BOTTOM means we draw from
* the bottom side of the buffer (which is drawn on the top side of
* mBufferRect).
*/
void
RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
XSide aXSide, YSide aYSide,
float aOpacity,
gfx::CompositionOp aOperator,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform) const
{
// The rectangle that we're going to fill. Basically we're going to
// render the buffer at mBufferRect + quadrantTranslation to get the
// pixels in the right place, but we're only going to paint within
// mBufferRect
IntRect quadrantRect = GetQuadrantRectangle(aXSide, aYSide);
IntRect fillRect;
if (!fillRect.IntersectRect(mBufferRect, quadrantRect))
return;
gfx::Point quadrantTranslation(quadrantRect.X(), quadrantRect.Y());
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
RefPtr<SourceSurface> snapshot = GetBufferSource();
if (!snapshot) {
gfxCriticalError() << "Invalid snapshot in RotatedBuffer::DrawBufferQuadrant";
return;
}
// direct2d is much slower when using OP_SOURCE so use OP_OVER and
// (maybe) a clear instead. Normally we need to draw in a single operation
// (to avoid flickering) but direct2d is ok since it defers rendering.
// We should try abstract this logic in a helper when we have other use
// cases.
if ((aTarget->GetBackendType() == BackendType::DIRECT2D ||
aTarget->GetBackendType() == BackendType::DIRECT2D1_1) &&
aOperator == CompositionOp::OP_SOURCE) {
aOperator = CompositionOp::OP_OVER;
if (snapshot->GetFormat() == SurfaceFormat::B8G8R8A8) {
aTarget->ClearRect(IntRectToRect(fillRect));
}
}
// OP_SOURCE is unbounded in Azure, and we really don't want that behaviour here.
// We also can't do a ClearRect+FillRect since we need the drawing to happen
// as an atomic operation (to prevent flickering).
// We also need this clip in the case where we have a mask, since the mask surface
// might cover more than fillRect, but we only want to touch the pixels inside
// fillRect.
aTarget->PushClipRect(IntRectToRect(fillRect));
if (aMask) {
Matrix oldTransform = aTarget->GetTransform();
// Transform from user -> buffer space.
Matrix transform =
Matrix::Translation(quadrantTranslation.x, quadrantTranslation.y);
Matrix inverseMask = *aMaskTransform;
inverseMask.Invert();
transform *= oldTransform;
transform *= inverseMask;
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
SurfacePattern source(snapshot, ExtendMode::CLAMP, transform, SamplingFilter::POINT);
#else
SurfacePattern source(snapshot, ExtendMode::CLAMP, transform);
#endif
aTarget->SetTransform(*aMaskTransform);
aTarget->MaskSurface(source, aMask, Point(0, 0), DrawOptions(aOpacity, aOperator));
aTarget->SetTransform(oldTransform);
} else {
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
DrawSurfaceOptions options(SamplingFilter::POINT);
#else
DrawSurfaceOptions options;
#endif
aTarget->DrawSurface(snapshot, IntRectToRect(fillRect),
GetSourceRectangle(aXSide, aYSide),
options,
DrawOptions(aOpacity, aOperator));
}
aTarget->PopClip();
}
void
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget,
float aOpacity,
gfx::CompositionOp aOperator,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform) const
{
Bug 1375392 - Tweak the PROFILER_LABEL* macros. r=mstange. This patch makes the following changes to the macros. - Removes PROFILER_LABEL_FUNC. It's only suitable for use in functions outside classes, due to PROFILER_FUNCTION_NAME not getting class names, and it was mostly misused. - Removes PROFILER_FUNCTION_NAME. It's no longer used, and __func__ is universally available now anyway. - Combines the first two string literal arguments of PROFILER_LABEL and PROFILER_LABEL_DYNAMIC into a single argument. There was no good reason for them to be separate, and it forced a '::' in the label, which isn't always appropriate. Also, the meaning of the "name_space" argument was interpreted in an interesting variety of ways. - Adds an "AUTO_" prefix to PROFILER_LABEL and PROFILER_LABEL_DYNAMIC, to make it clearer they construct RAII objects rather than just being function calls. (I myself have screwed up the scoping because of this in the past.) - Fills in the 'js::ProfileEntry::Category::' qualifier within the macro, so the caller doesn't need to. This makes a *lot* more of the uses fit onto a single line. The patch also makes the following changes to the macro uses (beyond those required by the changes described above). - Fixes a bunch of labels that had gotten out of sync with the name of the class and/or function that encloses them. - Removes a useless PROFILER_LABEL use within a trivial scope in EventStateManager::DispatchMouseOrPointerEvent(). It clearly wasn't serving any useful purpose. It also serves as extra evidence that the AUTO_ prefix is a good idea. - Tweaks DecodePool::SyncRunIf{Preferred,Possible} so that the labelling is done within them, instead of at their callsites, because that's a more standard way of doing things. --HG-- extra : rebase_source : 318d1bc6fc1425a94aacbf489dd46e4f83211de4
2017-06-22 10:08:53 +03:00
AUTO_PROFILER_LABEL("RotatedBuffer::DrawBufferWithRotation", GRAPHICS);
// See above, in Azure Repeat should always be a safe, even faster choice
// though! Particularly on D2D Repeat should be a lot faster, need to look
// into that. TODO[Bas]
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
DrawBufferQuadrant(aTarget, LEFT, TOP, aOpacity, aOperator, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, RIGHT, TOP, aOpacity, aOperator, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aOpacity, aOperator, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aOpacity, aOperator,aMask, aMaskTransform);
}
bool IsClippingCheap(gfx::DrawTarget* aTarget, const nsIntRegion& aRegion)
{
// Assume clipping is cheap if the draw target just has an integer
// translation, and the visible region is simple.
return !aTarget->GetTransform().HasNonIntegerTranslation() &&
aRegion.GetNumRects() <= 1;
}
void
RotatedBuffer::DrawTo(PaintedLayer* aLayer,
DrawTarget* aTarget,
float aOpacity,
CompositionOp aOp,
SourceSurface* aMask,
const Matrix* aMaskTransform)
{
bool clipped = false;
// If the entire buffer is valid, we can just draw the whole thing,
// no need to clip. But we'll still clip if clipping is cheap ---
// that might let us copy a smaller region of the buffer.
// Also clip to the visible region if we're told to.
if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
(ToData(aLayer)->GetClipToVisibleRegion() &&
!aLayer->GetVisibleRegion().ToUnknownRegion().Contains(BufferRect())) ||
IsClippingCheap(aTarget, aLayer->GetLocalVisibleRegion().ToUnknownRegion())) {
// We don't want to draw invalid stuff, so we need to clip. Might as
// well clip to the smallest area possible --- the visible region.
// Bug 599189 if there is a non-integer-translation transform in aTarget,
// we might sample pixels outside GetLocalVisibleRegion(), which is wrong
// and may cause gray lines.
gfxUtils::ClipToRegion(aTarget, aLayer->GetLocalVisibleRegion().ToUnknownRegion());
clipped = true;
}
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
DrawBufferWithRotation(aTarget, aOpacity, aOp, aMask, aMaskTransform);
if (clipped) {
aTarget->PopClip();
}
}
void
RotatedBuffer::UpdateDestinationFrom(const RotatedBuffer& aSource,
const gfx::IntRect& aUpdateRect)
{
DrawIterator iter;
while (DrawTarget* destDT =
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
BorrowDrawTargetForQuadrantUpdate(aUpdateRect, &iter)) {
bool isClippingCheap = IsClippingCheap(destDT, iter.mDrawRegion);
if (isClippingCheap) {
gfxUtils::ClipToRegion(destDT, iter.mDrawRegion);
}
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
aSource.DrawBufferWithRotation(destDT, 1.0, CompositionOp::OP_SOURCE);
if (isClippingCheap) {
destDT->PopClip();
}
ReturnDrawTarget(destDT);
}
}
static void
WrapRotationAxis(int32_t* aRotationPoint, int32_t aSize)
{
if (*aRotationPoint < 0) {
*aRotationPoint += aSize;
} else if (*aRotationPoint >= aSize) {
*aRotationPoint -= aSize;
}
}
bool
RotatedBuffer::Parameters::IsRotated() const
{
return mBufferRotation != IntPoint(0,0);
}
bool
RotatedBuffer::Parameters::RectWrapsBuffer(const gfx::IntRect& aRect) const
{
int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x;
int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y;
return (aRect.X() < xBoundary && xBoundary < aRect.XMost()) ||
(aRect.Y() < yBoundary && yBoundary < aRect.YMost());
}
void
RotatedBuffer::Parameters::SetUnrotated()
{
mBufferRotation = IntPoint(0,0);
mDidSelfCopy = true;
}
RotatedBuffer::Parameters
RotatedBuffer::AdjustedParameters(const gfx::IntRect& aDestBufferRect) const
{
IntRect keepArea;
if (keepArea.IntersectRect(aDestBufferRect, mBufferRect)) {
// Set mBufferRotation so that the pixels currently in mDTBuffer
// will still be rendered in the right place when mBufferRect
// changes to aDestBufferRect.
IntPoint newRotation = mBufferRotation +
(aDestBufferRect.TopLeft() - mBufferRect.TopLeft());
WrapRotationAxis(&newRotation.x, mBufferRect.Width());
WrapRotationAxis(&newRotation.y, mBufferRect.Height());
NS_ASSERTION(gfx::IntRect(gfx::IntPoint(0,0), mBufferRect.Size()).Contains(newRotation),
"newRotation out of bounds");
return Parameters{aDestBufferRect, newRotation};
}
// No pixels are going to be kept. The whole visible region
// will be redrawn, so we don't need to copy anything, so we don't
// set destBuffer.
return Parameters{aDestBufferRect, IntPoint(0,0)};
}
bool
RotatedBuffer::UnrotateBufferTo(const Parameters& aParameters)
{
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
RefPtr<gfx::DrawTarget> drawTarget = GetDrawTarget();
MOZ_ASSERT(drawTarget && drawTarget->IsValid());
if (mBufferRotation == IntPoint(0,0)) {
IntRect srcRect(IntPoint(0, 0), mBufferRect.Size());
IntPoint dest = mBufferRect.TopLeft() - aParameters.mBufferRect.TopLeft();
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
drawTarget->CopyRect(srcRect, dest);
return true;
} else {
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
return drawTarget->Unrotate(aParameters.mBufferRotation);
}
}
void
RotatedBuffer::SetParameters(const RotatedBuffer::Parameters& aParameters)
{
mBufferRect = aParameters.mBufferRect;
mBufferRotation = aParameters.mBufferRotation;
mDidSelfCopy = aParameters.mDidSelfCopy;
}
RotatedBuffer::ContentType
RotatedBuffer::GetContentType() const
{
return ContentForFormat(GetFormat());
}
DrawTarget*
RotatedBuffer::BorrowDrawTargetForQuadrantUpdate(const IntRect& aBounds,
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
DrawIterator* aIter)
{
IntRect bounds = aBounds;
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) {
IntRect quadrant = GetQuadrantRectangle((aIter->mCount & 1) ? LEFT : RIGHT,
(aIter->mCount & 2) ? TOP : BOTTOM);
aIter->mDrawRegion.And(aBounds, quadrant);
aIter->mCount++;
if (!aIter->mDrawRegion.IsEmpty()) {
break;
}
}
if (aIter->mDrawRegion.IsEmpty()) {
return nullptr;
}
bounds = aIter->mDrawRegion.GetBounds();
}
MOZ_ASSERT(!mLoanedDrawTarget, "draw target has been borrowed and not returned");
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
mLoanedDrawTarget = GetDrawTarget();
// Figure out which quadrant to draw in
int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x;
int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y;
XSide sideX = bounds.XMost() <= xBoundary ? RIGHT : LEFT;
YSide sideY = bounds.YMost() <= yBoundary ? BOTTOM : TOP;
IntRect quadrantRect = GetQuadrantRectangle(sideX, sideY);
NS_ASSERTION(quadrantRect.Contains(bounds), "Messed up quadrants");
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
mLoanedTransform = mLoanedDrawTarget->GetTransform();
Matrix transform = Matrix(mLoanedTransform)
.PreTranslate(-quadrantRect.X(),
-quadrantRect.Y());
mLoanedDrawTarget->SetTransform(transform);
return mLoanedDrawTarget;
}
gfx::SurfaceFormat
RemoteRotatedBuffer::GetFormat() const
{
return mClient->GetFormat();
}
bool
RemoteRotatedBuffer::IsLocked()
{
return mClient->IsLocked();
}
bool
RemoteRotatedBuffer::Lock(OpenMode aMode)
{
MOZ_ASSERT(!mTarget);
MOZ_ASSERT(!mTargetOnWhite);
bool locked = mClient->Lock(aMode) &&
(!mClientOnWhite || mClientOnWhite->Lock(aMode));
if (!locked) {
Unlock();
return false;
}
mTarget = mClient->BorrowDrawTarget();
if (!mTarget || !mTarget->IsValid()) {
gfxCriticalNote << "Invalid draw target " << hexa(mTarget)
<< " in RemoteRotatedBuffer::Lock";
Unlock();
return false;
}
if (mClientOnWhite) {
mTargetOnWhite = mClientOnWhite->BorrowDrawTarget();
if (!mTargetOnWhite || !mTargetOnWhite->IsValid()) {
gfxCriticalNote << "Invalid draw target(s) " << hexa(mTarget)
<< " and " << hexa(mTargetOnWhite)
<< " in RemoteRotatedBuffer::Lock";
Unlock();
return false;
}
}
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
if (mTargetOnWhite) {
mTargetDual = Factory::CreateDualDrawTarget(mTarget, mTargetOnWhite);
if (!mTargetDual || !mTargetDual->IsValid()) {
gfxCriticalNote << "Invalid dual draw target " << hexa(mTargetDual)
<< " in RemoteRotatedBuffer::Lock";
Unlock();
return false;
}
} else {
mTargetDual = mTarget;
}
return true;
}
void
RemoteRotatedBuffer::Unlock()
{
mTarget = nullptr;
mTargetOnWhite = nullptr;
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
mTargetDual = nullptr;
if (mClient->IsLocked()) {
mClient->Unlock();
}
if (mClientOnWhite && mClientOnWhite->IsLocked()) {
mClientOnWhite->Unlock();
}
}
void
RemoteRotatedBuffer::SyncWithObject(SyncObjectClient* aSyncObject)
{
mClient->SyncWithObject(aSyncObject);
if (mClientOnWhite) {
mClientOnWhite->SyncWithObject(aSyncObject);
}
}
void
RemoteRotatedBuffer::Clear()
{
MOZ_ASSERT(!mTarget && !mTargetOnWhite);
mClient = nullptr;
mClientOnWhite = nullptr;
}
gfx::DrawTarget*
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
RemoteRotatedBuffer::GetBufferTarget() const
{
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
return mTargetDual;
}
gfx::SurfaceFormat
DrawTargetRotatedBuffer::GetFormat() const
{
return mTarget->GetFormat();
}
gfx::DrawTarget*
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
DrawTargetRotatedBuffer::GetBufferTarget() const
{
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
return mTargetDual;
}
gfx::SurfaceFormat
SourceRotatedBuffer::GetFormat() const
{
return mSource->GetFormat();
}
already_AddRefed<SourceSurface>
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
SourceRotatedBuffer::GetBufferSource() const
{
Bug 1478815 part 8 - Remove buffer operations for ContentClient. r=nical This commit moves ContentClient from creating a CapturedBufferState for buffer operations, to performing all of those operations on the DrawTarget(Capture). Creating a DrawTargetCapture is now performed by the RotatedBuffer when we BeginPaint, all operations are performed on this capture, and then it's returned to the ClientPaintedLayer as a PaintTask. This commit is an involved refactoring of ContentClient and RotatedBuffer to get this all to work. Here are the major parts: 1. RotatedBuffer is refactored to always perform operations on a single DrawTarget, which may be a single DT, dual DT, or capture. 2. RotatedBuffer adds BeginCapture and EndCapture methods to switch which DT is used in operations 3. ContentClient uses the RB capture methods when we are async painting 4. CC::BeginPaint is refactored to only perform capturing on a single RotatedBuffer. This is because we can't have the output of one PaintTask be the input of a different PaintTask due to the design of the Snapshot API. a. This can occur, today, by doing a FinalizeFrame only to later fail to Unrotate the buffer, causing a new RB to be created and painted into b. The previous PaintThread code worked because it used the buffer operations which didn't use Snapshot's c. This is fixed by not doing FinalizeFrame on a buffer if we realize we cannot unrotate it, and switching to initializing a buffer using the front buffer which should be up to date. d. I don't like touching this code, but it passes reftests, might be a performance improvement, and I've tested it on known regressions from the last time I messed up this code. 5. CC::PrepareForPaint is inlined into BeginPaint because dual draw targets can be cleared correctly from a previous commit 6. The code paths in ClientPaintedLayer are unified because we no longer need to special case this beyond setting the correct ContentClient flag. 7. CapturedPaintState and CapturedBufferState are removed in favor of PaintTask. Additionally EndLayer is no longer needed as all quadrants of a rotated buffer are in the same capture, so we don't need special case flushing code. MozReview-Commit-ID: 9UI40dwran --HG-- extra : rebase_source : 809d9816970648468de972c30b0c230c2f21e27b extra : source : 405ad351821813333c0e989b93e2aeb49ba8552c
2018-07-26 19:23:26 +03:00
RefPtr<SourceSurface> sourceDual = mSourceDual;
return sourceDual.forget();
}
} // namespace layers
} // namespace mozilla