зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1255104 - Use SurfacePipe in nsIconDecoder. r=njn
This commit is contained in:
Родитель
b47c0eea98
Коммит
c987885db6
|
@ -5,17 +5,11 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "nsIconDecoder.h"
|
#include "nsIconDecoder.h"
|
||||||
#include "nsIInputStream.h"
|
|
||||||
#include "nspr.h"
|
|
||||||
#include "nsRect.h"
|
|
||||||
#include "nsError.h"
|
|
||||||
#include "RasterImage.h"
|
#include "RasterImage.h"
|
||||||
#include <algorithm>
|
#include "SurfacePipeFactory.h"
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
using std::min;
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace image {
|
namespace image {
|
||||||
|
|
||||||
|
@ -24,10 +18,7 @@ static const uint32_t ICON_HEADER_SIZE = 2;
|
||||||
nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
||||||
: Decoder(aImage)
|
: Decoder(aImage)
|
||||||
, mLexer(Transition::To(State::HEADER, ICON_HEADER_SIZE))
|
, mLexer(Transition::To(State::HEADER, ICON_HEADER_SIZE))
|
||||||
, mWidth() // set by ReadHeader()
|
|
||||||
, mHeight() // set by ReadHeader()
|
|
||||||
, mBytesPerRow() // set by ReadHeader()
|
, mBytesPerRow() // set by ReadHeader()
|
||||||
, mCurrentRow(0)
|
|
||||||
{
|
{
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
}
|
}
|
||||||
|
@ -66,14 +57,14 @@ LexerTransition<nsIconDecoder::State>
|
||||||
nsIconDecoder::ReadHeader(const char* aData)
|
nsIconDecoder::ReadHeader(const char* aData)
|
||||||
{
|
{
|
||||||
// Grab the width and height.
|
// Grab the width and height.
|
||||||
mWidth = uint8_t(aData[0]);
|
uint8_t width = uint8_t(aData[0]);
|
||||||
mHeight = uint8_t(aData[1]);
|
uint8_t height = uint8_t(aData[1]);
|
||||||
|
|
||||||
// The input is 32bpp, so we expect 4 bytes of data per pixel.
|
// The input is 32bpp, so we expect 4 bytes of data per pixel.
|
||||||
mBytesPerRow = mWidth * 4;
|
mBytesPerRow = width * 4;
|
||||||
|
|
||||||
// Post our size to the superclass.
|
// Post our size to the superclass.
|
||||||
PostSize(mWidth, mHeight);
|
PostSize(width, height);
|
||||||
|
|
||||||
// Icons have alpha.
|
// Icons have alpha.
|
||||||
PostHasTransparency();
|
PostHasTransparency();
|
||||||
|
@ -85,21 +76,19 @@ nsIconDecoder::ReadHeader(const char* aData)
|
||||||
|
|
||||||
MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
|
MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
|
||||||
IntSize targetSize = mDownscaler ? mDownscaler->TargetSize() : GetSize();
|
IntSize targetSize = mDownscaler ? mDownscaler->TargetSize() : GetSize();
|
||||||
nsresult rv = AllocateFrame(0, targetSize,
|
IntRect targetFrameRect(IntPoint(0, 0), targetSize);
|
||||||
IntRect(IntPoint(), targetSize),
|
|
||||||
gfx::SurfaceFormat::B8G8R8A8);
|
Maybe<SurfacePipe> pipe =
|
||||||
if (NS_FAILED(rv)) {
|
SurfacePipeFactory::CreateSurfacePipe(this, 0, GetSize(), targetSize,
|
||||||
|
targetFrameRect, SurfaceFormat::B8G8R8A8,
|
||||||
|
SurfacePipeFlags());
|
||||||
|
if (!pipe) {
|
||||||
return Transition::TerminateFailure();
|
return Transition::TerminateFailure();
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
|
||||||
|
|
||||||
if (mDownscaler) {
|
mPipe = Move(*pipe);
|
||||||
nsresult rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
|
|
||||||
mImageData, /* aHasAlpha = */ true);
|
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return Transition::TerminateFailure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Transition::To(State::ROW_OF_PIXELS, mBytesPerRow);
|
return Transition::To(State::ROW_OF_PIXELS, mBytesPerRow);
|
||||||
}
|
}
|
||||||
|
@ -107,25 +96,31 @@ nsIconDecoder::ReadHeader(const char* aData)
|
||||||
LexerTransition<nsIconDecoder::State>
|
LexerTransition<nsIconDecoder::State>
|
||||||
nsIconDecoder::ReadRowOfPixels(const char* aData, size_t aLength)
|
nsIconDecoder::ReadRowOfPixels(const char* aData, size_t aLength)
|
||||||
{
|
{
|
||||||
if (mDownscaler) {
|
MOZ_ASSERT(aLength % 4 == 0, "Rows should contain a multiple of four bytes");
|
||||||
memcpy(mDownscaler->RowBuffer(), aData, mBytesPerRow);
|
|
||||||
mDownscaler->CommitRow();
|
|
||||||
|
|
||||||
if (mDownscaler->HasInvalidation()) {
|
auto result = mPipe.WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
|
||||||
DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
|
if (aLength == 0) {
|
||||||
PostInvalidation(invalidRect.mOriginalSizeRect,
|
return AsVariant(WriteState::NEED_MORE_DATA); // Done with this row.
|
||||||
Some(invalidRect.mTargetSizeRect));
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
memcpy(mImageData + mCurrentRow * mBytesPerRow, aData, mBytesPerRow);
|
|
||||||
|
|
||||||
PostInvalidation(IntRect(0, mCurrentRow, mWidth, 1));
|
uint32_t pixel = *reinterpret_cast<const uint32_t*>(aData);
|
||||||
|
aData += 4;
|
||||||
|
aLength -= 4;
|
||||||
|
|
||||||
|
return AsVariant(pixel);
|
||||||
|
});
|
||||||
|
|
||||||
|
MOZ_ASSERT(result != WriteState::FAILURE);
|
||||||
|
|
||||||
|
Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect();
|
||||||
|
if (invalidRect) {
|
||||||
|
PostInvalidation(invalidRect->mInputSpaceRect,
|
||||||
|
Some(invalidRect->mOutputSpaceRect));
|
||||||
}
|
}
|
||||||
mCurrentRow++;
|
|
||||||
|
|
||||||
return (mCurrentRow < mHeight)
|
return result == WriteState::FINISHED
|
||||||
? Transition::To(State::ROW_OF_PIXELS, mBytesPerRow)
|
? Transition::To(State::FINISH, 0)
|
||||||
: Transition::To(State::FINISH, 0);
|
: Transition::To(State::ROW_OF_PIXELS, mBytesPerRow);
|
||||||
}
|
}
|
||||||
|
|
||||||
LexerTransition<nsIconDecoder::State>
|
LexerTransition<nsIconDecoder::State>
|
||||||
|
|
|
@ -9,10 +9,11 @@
|
||||||
|
|
||||||
#include "Decoder.h"
|
#include "Decoder.h"
|
||||||
#include "StreamingLexer.h"
|
#include "StreamingLexer.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "SurfacePipe.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace image {
|
namespace image {
|
||||||
|
|
||||||
class RasterImage;
|
class RasterImage;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -21,16 +22,13 @@ class RasterImage;
|
||||||
// and this decoder takes that format and converts it into 24-bit RGB with
|
// and this decoder takes that format and converts it into 24-bit RGB with
|
||||||
// alpha channel support. It was modeled a bit off the PPM decoder.
|
// alpha channel support. It was modeled a bit off the PPM decoder.
|
||||||
//
|
//
|
||||||
// Assumptions about the decoder:
|
// The format of the incoming data is as follows:
|
||||||
// (1) We receive ALL of the data from the icon channel in one OnDataAvailable
|
|
||||||
// call. We don't support multiple ODA calls yet.
|
|
||||||
// (2) the format of the incoming data is as follows:
|
|
||||||
// The first two bytes contain the width and the height of the icon.
|
|
||||||
// The remaining bytes contain the icon data, 4 bytes per pixel, in
|
|
||||||
// ARGB order (platform endianness, A in highest bits, B in lowest
|
|
||||||
// bits), row-primary, top-to-bottom, left-to-right, with
|
|
||||||
// premultiplied alpha.
|
|
||||||
//
|
//
|
||||||
|
// The first two bytes contain the width and the height of the icon.
|
||||||
|
// The remaining bytes contain the icon data, 4 bytes per pixel, in
|
||||||
|
// ARGB order (platform endianness, A in highest bits, B in lowest
|
||||||
|
// bits), row-primary, top-to-bottom, left-to-right, with
|
||||||
|
// premultiplied alpha.
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -58,11 +56,8 @@ private:
|
||||||
LexerTransition<State> Finish();
|
LexerTransition<State> Finish();
|
||||||
|
|
||||||
StreamingLexer<State> mLexer;
|
StreamingLexer<State> mLexer;
|
||||||
uint8_t mWidth;
|
SurfacePipe mPipe;
|
||||||
uint8_t mHeight;
|
|
||||||
uint32_t mBytesPerRow;
|
uint32_t mBytesPerRow;
|
||||||
uint32_t mBytesTotal;
|
|
||||||
uint32_t mCurrentRow;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace image
|
} // namespace image
|
||||||
|
|
Загрузка…
Ссылка в новой задаче