зеркало из 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/. */
|
||||
|
||||
#include "nsIconDecoder.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nspr.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsError.h"
|
||||
#include "RasterImage.h"
|
||||
#include <algorithm>
|
||||
#include "SurfacePipeFactory.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
using std::min;
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
|
@ -24,10 +18,7 @@ static const uint32_t ICON_HEADER_SIZE = 2;
|
|||
nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
||||
: Decoder(aImage)
|
||||
, mLexer(Transition::To(State::HEADER, ICON_HEADER_SIZE))
|
||||
, mWidth() // set by ReadHeader()
|
||||
, mHeight() // set by ReadHeader()
|
||||
, mBytesPerRow() // set by ReadHeader()
|
||||
, mCurrentRow(0)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
@ -66,14 +57,14 @@ LexerTransition<nsIconDecoder::State>
|
|||
nsIconDecoder::ReadHeader(const char* aData)
|
||||
{
|
||||
// Grab the width and height.
|
||||
mWidth = uint8_t(aData[0]);
|
||||
mHeight = uint8_t(aData[1]);
|
||||
uint8_t width = uint8_t(aData[0]);
|
||||
uint8_t height = uint8_t(aData[1]);
|
||||
|
||||
// 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.
|
||||
PostSize(mWidth, mHeight);
|
||||
PostSize(width, height);
|
||||
|
||||
// Icons have alpha.
|
||||
PostHasTransparency();
|
||||
|
@ -85,21 +76,19 @@ nsIconDecoder::ReadHeader(const char* aData)
|
|||
|
||||
MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
|
||||
IntSize targetSize = mDownscaler ? mDownscaler->TargetSize() : GetSize();
|
||||
nsresult rv = AllocateFrame(0, targetSize,
|
||||
IntRect(IntPoint(), targetSize),
|
||||
gfx::SurfaceFormat::B8G8R8A8);
|
||||
if (NS_FAILED(rv)) {
|
||||
IntRect targetFrameRect(IntPoint(0, 0), targetSize);
|
||||
|
||||
Maybe<SurfacePipe> pipe =
|
||||
SurfacePipeFactory::CreateSurfacePipe(this, 0, GetSize(), targetSize,
|
||||
targetFrameRect, SurfaceFormat::B8G8R8A8,
|
||||
SurfacePipeFlags());
|
||||
if (!pipe) {
|
||||
return Transition::TerminateFailure();
|
||||
}
|
||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||
|
||||
if (mDownscaler) {
|
||||
nsresult rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
|
||||
mImageData, /* aHasAlpha = */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
return Transition::TerminateFailure();
|
||||
}
|
||||
}
|
||||
mPipe = Move(*pipe);
|
||||
|
||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||
|
||||
return Transition::To(State::ROW_OF_PIXELS, mBytesPerRow);
|
||||
}
|
||||
|
@ -107,25 +96,31 @@ nsIconDecoder::ReadHeader(const char* aData)
|
|||
LexerTransition<nsIconDecoder::State>
|
||||
nsIconDecoder::ReadRowOfPixels(const char* aData, size_t aLength)
|
||||
{
|
||||
if (mDownscaler) {
|
||||
memcpy(mDownscaler->RowBuffer(), aData, mBytesPerRow);
|
||||
mDownscaler->CommitRow();
|
||||
MOZ_ASSERT(aLength % 4 == 0, "Rows should contain a multiple of four bytes");
|
||||
|
||||
if (mDownscaler->HasInvalidation()) {
|
||||
DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
|
||||
PostInvalidation(invalidRect.mOriginalSizeRect,
|
||||
Some(invalidRect.mTargetSizeRect));
|
||||
auto result = mPipe.WritePixels<uint32_t>([&]() -> NextPixel<uint32_t> {
|
||||
if (aLength == 0) {
|
||||
return AsVariant(WriteState::NEED_MORE_DATA); // Done with this row.
|
||||
}
|
||||
} 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)
|
||||
? Transition::To(State::ROW_OF_PIXELS, mBytesPerRow)
|
||||
: Transition::To(State::FINISH, 0);
|
||||
return result == WriteState::FINISHED
|
||||
? Transition::To(State::FINISH, 0)
|
||||
: Transition::To(State::ROW_OF_PIXELS, mBytesPerRow);
|
||||
}
|
||||
|
||||
LexerTransition<nsIconDecoder::State>
|
||||
|
|
|
@ -9,10 +9,11 @@
|
|||
|
||||
#include "Decoder.h"
|
||||
#include "StreamingLexer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "SurfacePipe.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
class RasterImage;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -21,16 +22,13 @@ class RasterImage;
|
|||
// 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.
|
||||
//
|
||||
// Assumptions about the decoder:
|
||||
// (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 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -58,11 +56,8 @@ private:
|
|||
LexerTransition<State> Finish();
|
||||
|
||||
StreamingLexer<State> mLexer;
|
||||
uint8_t mWidth;
|
||||
uint8_t mHeight;
|
||||
SurfacePipe mPipe;
|
||||
uint32_t mBytesPerRow;
|
||||
uint32_t mBytesTotal;
|
||||
uint32_t mCurrentRow;
|
||||
};
|
||||
|
||||
} // namespace image
|
||||
|
|
Загрузка…
Ссылка в новой задаче