Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit bd60a92

Browse files
committed
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
1 parent e203ac1 commit bd60a92

4 files changed

Lines changed: 96 additions & 6 deletions

File tree

image/DownscalingFilter.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ class DownscalingFilter final : public SurfaceFilter {
7878
MOZ_CRASH();
7979
return nullptr;
8080
}
81+
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
82+
MOZ_CRASH();
83+
return nullptr;
84+
}
8185
uint8_t* DoAdvanceRow() override {
8286
MOZ_CRASH();
8387
return nullptr;
@@ -206,7 +210,7 @@ class DownscalingFilter final : public SurfaceFilter {
206210
return GetRowPointer();
207211
}
208212

209-
uint8_t* DoAdvanceRow() override {
213+
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
210214
if (mInputRow >= mInputSize.height) {
211215
NS_WARNING("Advancing DownscalingFilter past the end of the input");
212216
return nullptr;
@@ -226,7 +230,7 @@ class DownscalingFilter final : public SurfaceFilter {
226230
if (mInputRow == inputRowToRead) {
227231
MOZ_RELEASE_ASSERT(mRowsInWindow < mWindowCapacity,
228232
"Need more rows than capacity!");
229-
mXFilter.ConvolveHorizontally(mRowBuffer.get(), mWindow[mRowsInWindow++],
233+
mXFilter.ConvolveHorizontally(aInputRow, mWindow[mRowsInWindow++],
230234
mHasAlpha);
231235
}
232236

@@ -249,6 +253,10 @@ class DownscalingFilter final : public SurfaceFilter {
249253
return mInputRow < mInputSize.height ? GetRowPointer() : nullptr;
250254
}
251255

256+
uint8_t* DoAdvanceRow() override {
257+
return DoAdvanceRowFromBuffer(mRowBuffer.get());
258+
}
259+
252260
private:
253261
uint8_t* GetRowPointer() const { return mRowBuffer.get(); }
254262

image/SurfaceFilters.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,16 @@ class ColorManagementFilter final : public SurfaceFilter {
8080
protected:
8181
uint8_t* DoResetToFirstRow() override { return mNext.ResetToFirstRow(); }
8282

83-
uint8_t* DoAdvanceRow() override {
84-
uint8_t* rowPtr = mNext.CurrentRowPointer();
85-
qcms_transform_data(mTransform, rowPtr, rowPtr, mNext.InputSize().width);
83+
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
84+
qcms_transform_data(mTransform, aInputRow, mNext.CurrentRowPointer(),
85+
mNext.InputSize().width);
8686
return mNext.AdvanceRow();
8787
}
8888

89+
uint8_t* DoAdvanceRow() override {
90+
return DoAdvanceRowFromBuffer(mNext.CurrentRowPointer());
91+
}
92+
8993
Next mNext; /// The next SurfaceFilter in the chain.
9094

9195
qcms_transform* mTransform;
@@ -182,6 +186,11 @@ class DeinterlacingFilter final : public SurfaceFilter {
182186
return GetRowPointer(mOutputRow);
183187
}
184188

189+
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
190+
CopyInputRow(aInputRow);
191+
return DoAdvanceRow();
192+
}
193+
185194
uint8_t* DoAdvanceRow() override {
186195
if (mPass >= 4) {
187196
return nullptr; // We already finished all passes.
@@ -638,6 +647,11 @@ class BlendAnimationFilter final : public SurfaceFilter {
638647
return nullptr; // We're done.
639648
}
640649

650+
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
651+
CopyInputRow(aInputRow);
652+
return DoAdvanceRow();
653+
}
654+
641655
uint8_t* DoAdvanceRow() override {
642656
uint8_t* rowPtr = nullptr;
643657

@@ -912,6 +926,11 @@ class RemoveFrameRectFilter final : public SurfaceFilter {
912926
return nullptr; // We're done.
913927
}
914928

929+
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
930+
CopyInputRow(aInputRow);
931+
return DoAdvanceRow();
932+
}
933+
915934
uint8_t* DoAdvanceRow() override {
916935
uint8_t* rowPtr = nullptr;
917936

@@ -1097,6 +1116,11 @@ class ADAM7InterpolatingFilter final : public SurfaceFilter {
10971116
return mCurrentRow.get();
10981117
}
10991118

1119+
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) override {
1120+
CopyInputRow(aInputRow);
1121+
return DoAdvanceRow();
1122+
}
1123+
11001124
uint8_t* DoAdvanceRow() override {
11011125
MOZ_ASSERT(0 < mPass && mPass <= 7, "Invalid pass");
11021126

image/SurfacePipe.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ uint8_t* AbstractSurfaceSink::DoResetToFirstRow() {
3636
return GetRowPointer();
3737
}
3838

39+
uint8_t* AbstractSurfaceSink::DoAdvanceRowFromBuffer(const uint8_t* aInputRow) {
40+
CopyInputRow(aInputRow);
41+
return DoAdvanceRow();
42+
}
43+
3944
uint8_t* AbstractSurfaceSink::DoAdvanceRow() {
4045
if (mRow >= uint32_t(InputSize().height)) {
4146
return nullptr;

image/SurfacePipe.h

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,19 @@ class SurfaceFilter {
127127
return mRowPointer;
128128
}
129129

130+
/**
131+
* Called by WriteBuffer() to advance this filter to the next row, if the
132+
* supplied row is a full row.
133+
*
134+
* @return a pointer to the buffer for the next row, or nullptr to indicate
135+
* that we've finished the entire surface.
136+
*/
137+
uint8_t* AdvanceRow(const uint8_t* aInputRow) {
138+
mCol = 0;
139+
mRowPointer = DoAdvanceRowFromBuffer(aInputRow);
140+
return mRowPointer;
141+
}
142+
130143
/// @return a pointer to the buffer for the current row.
131144
uint8_t* CurrentRowPointer() const { return mRowPointer; }
132145

@@ -269,7 +282,22 @@ class SurfaceFilter {
269282
*/
270283
template <typename PixelType>
271284
WriteState WriteBuffer(const PixelType* aSource) {
272-
return WriteBuffer(aSource, 0, mInputSize.width);
285+
MOZ_ASSERT(mPixelSize == 1 || mPixelSize == 4);
286+
MOZ_ASSERT_IF(mPixelSize == 1, sizeof(PixelType) == sizeof(uint8_t));
287+
MOZ_ASSERT_IF(mPixelSize == 4, sizeof(PixelType) == sizeof(uint32_t));
288+
289+
if (IsSurfaceFinished()) {
290+
return WriteState::FINISHED; // Already done.
291+
}
292+
293+
if (MOZ_UNLIKELY(!aSource)) {
294+
NS_WARNING("Passed a null pointer to WriteBuffer");
295+
return WriteState::FAILURE;
296+
}
297+
298+
AdvanceRow(reinterpret_cast<const uint8_t*>(aSource));
299+
return IsSurfaceFinished() ? WriteState::FINISHED
300+
: WriteState::NEED_MORE_DATA;
273301
}
274302

275303
/**
@@ -440,6 +468,16 @@ class SurfaceFilter {
440468
*/
441469
virtual uint8_t* DoResetToFirstRow() = 0;
442470

471+
/**
472+
* Called by AdvanceRow() to actually advance this filter to the next row.
473+
*
474+
* @param aInputRow The input row supplied by the decoder.
475+
*
476+
* @return a pointer to the buffer for the next row, or nullptr to indicate
477+
* that we've finished the entire surface.
478+
*/
479+
virtual uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) = 0;
480+
443481
/**
444482
* Called by AdvanceRow() to actually advance this filter to the next row.
445483
*
@@ -470,6 +508,20 @@ class SurfaceFilter {
470508
ResetToFirstRow();
471509
}
472510

511+
/**
512+
* Called by subclasses' DoAdvanceRowFromBuffer() methods to copy a decoder
513+
* supplied row buffer into its internal row pointer. Ideally filters at the
514+
* top of the filter pipeline are able to consume the decoder row buffer
515+
* directly without the extra copy prior to performing its transformation.
516+
*
517+
* @param aInputRow The input row supplied by the decoder.
518+
*/
519+
void CopyInputRow(const uint8_t* aInputRow) {
520+
MOZ_ASSERT(aInputRow);
521+
MOZ_ASSERT(mCol == 0);
522+
memcpy(mRowPointer, aInputRow, mPixelSize * mInputSize.width);
523+
}
524+
473525
private:
474526
/**
475527
* An internal method used to implement WritePixelBlocks. This method writes
@@ -719,6 +771,7 @@ class AbstractSurfaceSink : public SurfaceFilter {
719771

720772
protected:
721773
uint8_t* DoResetToFirstRow() final;
774+
uint8_t* DoAdvanceRowFromBuffer(const uint8_t* aInputRow) final;
722775
uint8_t* DoAdvanceRow() final;
723776
virtual uint8_t* GetRowPointer() const = 0;
724777

0 commit comments

Comments
 (0)