1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "SurfacePipe.h"
9 #include <algorithm> // for min
20 Maybe
<SurfaceInvalidRect
> AbstractSurfaceSink::TakeInvalidRect() {
21 if (mInvalidRect
.IsEmpty()) {
25 SurfaceInvalidRect invalidRect
;
26 invalidRect
.mInputSpaceRect
= invalidRect
.mOutputSpaceRect
= mInvalidRect
;
28 // Forget about the invalid rect we're returning.
29 mInvalidRect
= OrientedIntRect();
31 return Some(invalidRect
);
34 uint8_t* AbstractSurfaceSink::DoResetToFirstRow() {
36 return GetRowPointer();
39 uint8_t* SurfaceSink::DoAdvanceRowFromBuffer(const uint8_t* aInputRow
) {
40 CopyInputRow(aInputRow
);
41 return DoAdvanceRow();
44 uint8_t* SurfaceSink::DoAdvanceRow() {
45 if (mRow
>= uint32_t(InputSize().height
)) {
49 // If we're vertically flipping the output, we need to flip the invalid rect.
50 // Since we're dealing with an axis-aligned rect, only the y coordinate needs
52 int32_t invalidY
= mFlipVertically
? InputSize().height
- (mRow
+ 1) : mRow
;
53 mInvalidRect
.UnionRect(mInvalidRect
,
54 OrientedIntRect(0, invalidY
, InputSize().width
, 1));
56 mRow
= min(uint32_t(InputSize().height
), mRow
+ 1);
58 return mRow
< uint32_t(InputSize().height
) ? GetRowPointer() : nullptr;
61 nsresult
SurfaceSink::Configure(const SurfaceConfig
& aConfig
) {
62 IntSize surfaceSize
= aConfig
.mOutputSize
;
64 // Allocate the frame.
65 // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
66 // to allocate the frame directly here and get rid of Decoder::AllocateFrame
68 nsresult rv
= aConfig
.mDecoder
->AllocateFrame(surfaceSize
, aConfig
.mFormat
,
74 mImageData
= aConfig
.mDecoder
->mImageData
;
75 mImageDataLength
= aConfig
.mDecoder
->mImageDataLength
;
76 mFlipVertically
= aConfig
.mFlipVertically
;
78 MOZ_ASSERT(mImageData
);
79 MOZ_ASSERT(uint64_t(mImageDataLength
) == uint64_t(surfaceSize
.width
) *
80 uint64_t(surfaceSize
.height
) *
83 ConfigureFilter(surfaceSize
, sizeof(uint32_t));
87 uint8_t* SurfaceSink::GetRowPointer() const {
88 // If we're flipping vertically, reverse the order in which we traverse the
90 uint32_t row
= mFlipVertically
? InputSize().height
- (mRow
+ 1) : mRow
;
92 uint8_t* rowPtr
= mImageData
+ row
* InputSize().width
* sizeof(uint32_t);
94 MOZ_ASSERT(rowPtr
>= mImageData
);
95 MOZ_ASSERT(rowPtr
< mImageData
+ mImageDataLength
);
96 MOZ_ASSERT(rowPtr
+ InputSize().width
* sizeof(uint32_t) <=
97 mImageData
+ mImageDataLength
);
102 uint8_t* ReorientSurfaceSink::DoAdvanceRowFromBuffer(const uint8_t* aInputRow
) {
103 if (mRow
>= uint32_t(InputSize().height
)) {
107 IntRect dirty
= mReorientFn(aInputRow
, mRow
, mImageData
, mSurfaceSize
,
108 mSurfaceSize
.width
* sizeof(uint32_t));
109 auto orientedDirty
= OrientedIntRect::FromUnknownRect(dirty
);
110 mInvalidRect
.UnionRect(mInvalidRect
, orientedDirty
);
112 mRow
= min(uint32_t(InputSize().height
), mRow
+ 1);
114 return mRow
< uint32_t(InputSize().height
) ? GetRowPointer() : nullptr;
117 uint8_t* ReorientSurfaceSink::DoAdvanceRow() {
118 return DoAdvanceRowFromBuffer(mBuffer
.get());
121 nsresult
ReorientSurfaceSink::Configure(const ReorientSurfaceConfig
& aConfig
) {
122 mSurfaceSize
= aConfig
.mOutputSize
.ToUnknownSize();
124 // Allocate the frame.
125 // XXX(seth): Once every Decoder subclass uses SurfacePipe, we probably want
126 // to allocate the frame directly here and get rid of Decoder::AllocateFrame
129 aConfig
.mDecoder
->AllocateFrame(mSurfaceSize
, aConfig
.mFormat
, Nothing());
134 // The filters above us need the unoriented size as the input.
136 aConfig
.mOrientation
.ToUnoriented(aConfig
.mOutputSize
).ToUnknownSize();
137 mBuffer
.reset(new (fallible
) uint8_t[inputSize
.width
* sizeof(uint32_t)]);
138 if (MOZ_UNLIKELY(!mBuffer
)) {
139 return NS_ERROR_OUT_OF_MEMORY
;
142 memset(mBuffer
.get(), 0xFF, inputSize
.width
* sizeof(uint32_t));
144 mReorientFn
= ReorientRow(aConfig
.mOrientation
);
145 MOZ_ASSERT(mReorientFn
);
147 mImageData
= aConfig
.mDecoder
->mImageData
;
148 mImageDataLength
= aConfig
.mDecoder
->mImageDataLength
;
150 MOZ_ASSERT(mImageData
);
151 MOZ_ASSERT(uint64_t(mImageDataLength
) == uint64_t(mSurfaceSize
.width
) *
152 uint64_t(mSurfaceSize
.height
) *
155 ConfigureFilter(inputSize
, sizeof(uint32_t));
159 uint8_t* ReorientSurfaceSink::GetRowPointer() const { return mBuffer
.get(); }
162 } // namespace mozilla