mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 20:22:00 +00:00
Bug 1551088 - Part 5. Expose SurfaceFilter input row directly to avoid copy if possible. r=tnikkel
Some filters can do the copy of the given data into the working buffer as part of the filter operation. For those that cannot, we will just copy the data first, and then advance the row. Differential Revision: https://phabricator.services.mozilla.com/D46448 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
b1bffae1bc
commit
7b2fde0d05
@ -78,6 +78,10 @@ class DownscalingFilter final : public SurfaceFilter {
|
||||
MOZ_CRASH();
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
|
||||
MOZ_CRASH();
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
MOZ_CRASH();
|
||||
return nullptr;
|
||||
@ -206,7 +210,7 @@ class DownscalingFilter final : public SurfaceFilter {
|
||||
return GetRowPointer();
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
|
||||
if (mInputRow >= mInputSize.height) {
|
||||
NS_WARNING("Advancing DownscalingFilter past the end of the input");
|
||||
return nullptr;
|
||||
@ -226,7 +230,7 @@ class DownscalingFilter final : public SurfaceFilter {
|
||||
if (mInputRow == inputRowToRead) {
|
||||
MOZ_RELEASE_ASSERT(mRowsInWindow < mWindowCapacity,
|
||||
"Need more rows than capacity!");
|
||||
mXFilter.ConvolveHorizontally(mRowBuffer.get(), mWindow[mRowsInWindow++],
|
||||
mXFilter.ConvolveHorizontally(aInputRow, mWindow[mRowsInWindow++],
|
||||
mHasAlpha);
|
||||
}
|
||||
|
||||
@ -249,6 +253,10 @@ class DownscalingFilter final : public SurfaceFilter {
|
||||
return mInputRow < mInputSize.height ? GetRowPointer() : nullptr;
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
return DoAdvanceRowFromBuffer(mRowBuffer.get());
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t* GetRowPointer() const { return mRowBuffer.get(); }
|
||||
|
||||
|
@ -80,12 +80,16 @@ class ColorManagementFilter final : public SurfaceFilter {
|
||||
protected:
|
||||
uint8_t* DoResetToFirstRow() override { return mNext.ResetToFirstRow(); }
|
||||
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
uint8_t* rowPtr = mNext.CurrentRowPointer();
|
||||
qcms_transform_data(mTransform, rowPtr, rowPtr, mNext.InputSize().width);
|
||||
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
|
||||
qcms_transform_data(mTransform, aInputRow, mNext.CurrentRowPointer(),
|
||||
mNext.InputSize().width);
|
||||
return mNext.AdvanceRow();
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
return DoAdvanceRowFromBuffer(mNext.CurrentRowPointer());
|
||||
}
|
||||
|
||||
Next mNext; /// The next SurfaceFilter in the chain.
|
||||
|
||||
qcms_transform* mTransform;
|
||||
@ -182,6 +186,11 @@ class DeinterlacingFilter final : public SurfaceFilter {
|
||||
return GetRowPointer(mOutputRow);
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
|
||||
CopyInputRow(aInputRow);
|
||||
return DoAdvanceRow();
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
if (mPass >= 4) {
|
||||
return nullptr; // We already finished all passes.
|
||||
@ -638,6 +647,11 @@ class BlendAnimationFilter final : public SurfaceFilter {
|
||||
return nullptr; // We're done.
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
|
||||
CopyInputRow(aInputRow);
|
||||
return DoAdvanceRow();
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
uint8_t* rowPtr = nullptr;
|
||||
|
||||
@ -912,6 +926,11 @@ class RemoveFrameRectFilter final : public SurfaceFilter {
|
||||
return nullptr; // We're done.
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
|
||||
CopyInputRow(aInputRow);
|
||||
return DoAdvanceRow();
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
uint8_t* rowPtr = nullptr;
|
||||
|
||||
@ -1097,6 +1116,11 @@ class ADAM7InterpolatingFilter final : public SurfaceFilter {
|
||||
return mCurrentRow.get();
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
|
||||
CopyInputRow(aInputRow);
|
||||
return DoAdvanceRow();
|
||||
}
|
||||
|
||||
uint8_t* DoAdvanceRow() override {
|
||||
MOZ_ASSERT(0 < mPass && mPass <= 7, "Invalid pass");
|
||||
|
||||
|
@ -36,6 +36,11 @@ uint8_t* AbstractSurfaceSink::DoResetToFirstRow() {
|
||||
return GetRowPointer();
|
||||
}
|
||||
|
||||
uint8_t* AbstractSurfaceSink::DoAdvanceRowFromBuffer(const uint8_t* aInputRow) {
|
||||
CopyInputRow(aInputRow);
|
||||
return DoAdvanceRow();
|
||||
}
|
||||
|
||||
uint8_t* AbstractSurfaceSink::DoAdvanceRow() {
|
||||
if (mRow >= uint32_t(InputSize().height)) {
|
||||
return nullptr;
|
||||
|
@ -127,6 +127,19 @@ class SurfaceFilter {
|
||||
return mRowPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by WriteBuffer() to advance this filter to the next row, if the
|
||||
* supplied row is a full row.
|
||||
*
|
||||
* @return a pointer to the buffer for the next row, or nullptr to indicate
|
||||
* that we've finished the entire surface.
|
||||
*/
|
||||
uint8_t* AdvanceRow(const uint8_t* aInputRow) {
|
||||
mCol = 0;
|
||||
mRowPointer = DoAdvanceRowFromBuffer(aInputRow);
|
||||
return mRowPointer;
|
||||
}
|
||||
|
||||
/// @return a pointer to the buffer for the current row.
|
||||
uint8_t* CurrentRowPointer() const { return mRowPointer; }
|
||||
|
||||
@ -269,7 +282,22 @@ class SurfaceFilter {
|
||||
*/
|
||||
template <typename PixelType>
|
||||
WriteState WriteBuffer(const PixelType* aSource) {
|
||||
return WriteBuffer(aSource, 0, mInputSize.width);
|
||||
MOZ_ASSERT(mPixelSize == 1 || mPixelSize == 4);
|
||||
MOZ_ASSERT_IF(mPixelSize == 1, sizeof(PixelType) == sizeof(uint8_t));
|
||||
MOZ_ASSERT_IF(mPixelSize == 4, sizeof(PixelType) == sizeof(uint32_t));
|
||||
|
||||
if (IsSurfaceFinished()) {
|
||||
return WriteState::FINISHED; // Already done.
|
||||
}
|
||||
|
||||
if (MOZ_UNLIKELY(!aSource)) {
|
||||
NS_WARNING("Passed a null pointer to WriteBuffer");
|
||||
return WriteState::FAILURE;
|
||||
}
|
||||
|
||||
AdvanceRow(reinterpret_cast<const uint8_t*>(aSource));
|
||||
return IsSurfaceFinished() ? WriteState::FINISHED
|
||||
: WriteState::NEED_MORE_DATA;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -440,6 +468,16 @@ class SurfaceFilter {
|
||||
*/
|
||||
virtual uint8_t* DoResetToFirstRow() = 0;
|
||||
|
||||
/**
|
||||
* Called by AdvanceRow() to actually advance this filter to the next row.
|
||||
*
|
||||
* @param aInputRow The input row supplied by the decoder.
|
||||
*
|
||||
* @return a pointer to the buffer for the next row, or nullptr to indicate
|
||||
* that we've finished the entire surface.
|
||||
*/
|
||||
virtual uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) = 0;
|
||||
|
||||
/**
|
||||
* Called by AdvanceRow() to actually advance this filter to the next row.
|
||||
*
|
||||
@ -470,6 +508,20 @@ class SurfaceFilter {
|
||||
ResetToFirstRow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by subclasses' DoAdvanceRowFromBuffer() methods to copy a decoder
|
||||
* supplied row buffer into its internal row pointer. Ideally filters at the
|
||||
* top of the filter pipeline are able to consume the decoder row buffer
|
||||
* directly without the extra copy prior to performing its transformation.
|
||||
*
|
||||
* @param aInputRow The input row supplied by the decoder.
|
||||
*/
|
||||
void CopyInputRow(const uint8_t* aInputRow) {
|
||||
MOZ_ASSERT(aInputRow);
|
||||
MOZ_ASSERT(mCol == 0);
|
||||
memcpy(mRowPointer, aInputRow, mPixelSize * mInputSize.width);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* An internal method used to implement WritePixelBlocks. This method writes
|
||||
@ -719,6 +771,7 @@ class AbstractSurfaceSink : public SurfaceFilter {
|
||||
|
||||
protected:
|
||||
uint8_t* DoResetToFirstRow() final;
|
||||
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) final;
|
||||
uint8_t* DoAdvanceRow() final;
|
||||
virtual uint8_t* GetRowPointer() const = 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user