зеркало из https://github.com/mozilla/gecko-dev.git
Bug 845125 - Add gfxImageSurface constructor that allocates more space than needed, change AlphaBoxBlur to not hold on to the data and let the callers manage it. r=jmuizelaar
This commit is contained in:
Родитель
a1f1d83c09
Коммит
1de038645a
|
@ -1,3 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
@ -333,8 +335,7 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
|
|||
const Rect* aSkipRect)
|
||||
: mSpreadRadius(aSpreadRadius),
|
||||
mBlurRadius(aBlurRadius),
|
||||
mData(nullptr),
|
||||
mFreeData(true)
|
||||
mSurfaceAllocationSize(-1)
|
||||
{
|
||||
Rect rect(aRect);
|
||||
rect.Inflate(Size(aBlurRadius + aSpreadRadius));
|
||||
|
@ -385,38 +386,30 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
|
|||
// in our blurring code.
|
||||
CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height + 3;
|
||||
if (size.isValid()) {
|
||||
mData = new uint8_t[size.value()];
|
||||
memset(mData, 0, size.value());
|
||||
mSurfaceAllocationSize = size.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AlphaBoxBlur::AlphaBoxBlur(uint8_t* aData,
|
||||
const Rect& aRect,
|
||||
AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
|
||||
int32_t aStride,
|
||||
float aSigma)
|
||||
: mRect(int32_t(aRect.x), int32_t(aRect.y),
|
||||
int32_t(aRect.width), int32_t(aRect.height)),
|
||||
mSpreadRadius(),
|
||||
mBlurRadius(CalculateBlurRadius(Point(aSigma, aSigma))),
|
||||
mData(aData),
|
||||
mFreeData(false),
|
||||
mStride(aStride)
|
||||
mStride(aStride),
|
||||
mSurfaceAllocationSize(-1)
|
||||
{
|
||||
CheckedInt<int32_t> minDataSize = CheckedInt<int32_t>(aRect.width*aRect.height);
|
||||
if (minDataSize.isValid()) {
|
||||
mSurfaceAllocationSize = minDataSize.value();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AlphaBoxBlur::~AlphaBoxBlur()
|
||||
{
|
||||
if (mFreeData) {
|
||||
delete [] mData;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char*
|
||||
AlphaBoxBlur::GetData()
|
||||
{
|
||||
return mData;
|
||||
}
|
||||
|
||||
IntSize
|
||||
|
@ -448,10 +441,16 @@ AlphaBoxBlur::GetDirtyRect()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
AlphaBoxBlur::Blur()
|
||||
int32_t
|
||||
AlphaBoxBlur::GetSurfaceAllocationSize() const
|
||||
{
|
||||
if (!mData) {
|
||||
return mSurfaceAllocationSize;
|
||||
}
|
||||
|
||||
void
|
||||
AlphaBoxBlur::Blur(uint8_t* aData)
|
||||
{
|
||||
if (!aData) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -468,8 +467,8 @@ AlphaBoxBlur::Blur()
|
|||
|
||||
memset(tmpData, 0, szB);
|
||||
|
||||
SpreadHorizontal(mData, tmpData, mSpreadRadius.width, GetSize().width, GetSize().height, stride, mSkipRect);
|
||||
SpreadVertical(tmpData, mData, mSpreadRadius.height, GetSize().width, GetSize().height, stride, mSkipRect);
|
||||
SpreadHorizontal(aData, tmpData, mSpreadRadius.width, GetSize().width, GetSize().height, stride, mSkipRect);
|
||||
SpreadVertical(tmpData, aData, mSpreadRadius.height, GetSize().width, GetSize().height, stride, mSkipRect);
|
||||
|
||||
delete [] tmpData;
|
||||
}
|
||||
|
@ -494,7 +493,7 @@ AlphaBoxBlur::Blur()
|
|||
uint8_t* tmpData = new uint8_t[szB];
|
||||
memset(tmpData, 0, szB);
|
||||
|
||||
uint8_t* a = mData;
|
||||
uint8_t* a = aData;
|
||||
uint8_t* b = tmpData;
|
||||
if (mBlurRadius.width > 0) {
|
||||
BoxBlurHorizontal(a, b, horizontalLobes[0][0], horizontalLobes[0][1], stride, GetSize().height, mSkipRect);
|
||||
|
@ -502,7 +501,7 @@ AlphaBoxBlur::Blur()
|
|||
BoxBlurHorizontal(a, b, horizontalLobes[2][0], horizontalLobes[2][1], stride, GetSize().height, mSkipRect);
|
||||
} else {
|
||||
a = tmpData;
|
||||
b = mData;
|
||||
b = aData;
|
||||
}
|
||||
// The result is in 'b' here.
|
||||
if (mBlurRadius.height > 0) {
|
||||
|
@ -514,7 +513,7 @@ AlphaBoxBlur::Blur()
|
|||
}
|
||||
// The result is in 'a' here.
|
||||
if (a == tmpData) {
|
||||
memcpy(mData, tmpData, szB);
|
||||
memcpy(aData, tmpData, szB);
|
||||
}
|
||||
delete [] tmpData;
|
||||
} else {
|
||||
|
@ -526,20 +525,20 @@ AlphaBoxBlur::Blur()
|
|||
|
||||
#ifdef USE_SSE2
|
||||
if (Factory::HasSSE2()) {
|
||||
BoxBlur_SSE2(horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
|
||||
BoxBlur_SSE2(aData, horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
|
||||
verticalLobes[0][1], integralImage, integralImageStride);
|
||||
BoxBlur_SSE2(horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
|
||||
BoxBlur_SSE2(aData, horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
|
||||
verticalLobes[1][1], integralImage, integralImageStride);
|
||||
BoxBlur_SSE2(horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
|
||||
BoxBlur_SSE2(aData, horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
|
||||
verticalLobes[2][1], integralImage, integralImageStride);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
BoxBlur_C(horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
|
||||
BoxBlur_C(aData, horizontalLobes[0][0], horizontalLobes[0][1], verticalLobes[0][0],
|
||||
verticalLobes[0][1], integralImage, integralImageStride);
|
||||
BoxBlur_C(horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
|
||||
BoxBlur_C(aData, horizontalLobes[1][0], horizontalLobes[1][1], verticalLobes[1][0],
|
||||
verticalLobes[1][1], integralImage, integralImageStride);
|
||||
BoxBlur_C(horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
|
||||
BoxBlur_C(aData, horizontalLobes[2][0], horizontalLobes[2][1], verticalLobes[2][0],
|
||||
verticalLobes[2][1], integralImage, integralImageStride);
|
||||
}
|
||||
}
|
||||
|
@ -626,7 +625,8 @@ GenerateIntegralImage_C(int32_t aLeftInflation, int32_t aRightInflation,
|
|||
* Attempt to do an in-place box blur using an integral image.
|
||||
*/
|
||||
void
|
||||
AlphaBoxBlur::BoxBlur_C(int32_t aLeftLobe,
|
||||
AlphaBoxBlur::BoxBlur_C(uint8_t* aData,
|
||||
int32_t aLeftLobe,
|
||||
int32_t aRightLobe,
|
||||
int32_t aTopLobe,
|
||||
int32_t aBottomLobe,
|
||||
|
@ -655,7 +655,7 @@ AlphaBoxBlur::BoxBlur_C(int32_t aLeftLobe,
|
|||
int32_t leftInflation = RoundUpToMultipleOf4(aLeftLobe).value();
|
||||
|
||||
GenerateIntegralImage_C(leftInflation, aRightLobe, aTopLobe, aBottomLobe,
|
||||
aIntegralImage, aIntegralImageStride, mData,
|
||||
aIntegralImage, aIntegralImageStride, aData,
|
||||
mStride, size);
|
||||
|
||||
uint32_t reciprocal = uint32_t((uint64_t(1) << 32) / boxSize);
|
||||
|
@ -665,7 +665,7 @@ AlphaBoxBlur::BoxBlur_C(int32_t aLeftLobe,
|
|||
// Storing these locally makes this about 30% faster! Presumably the compiler
|
||||
// can't be sure we're not altering the member variables in this loop.
|
||||
IntRect skipRect = mSkipRect;
|
||||
uint8_t *data = mData;
|
||||
uint8_t *data = aData;
|
||||
int32_t stride = mStride;
|
||||
for (int32_t y = 0; y < size.height; y++) {
|
||||
bool inSkipRectY = y > skipRect.y && y < skipRect.YMost();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
@ -24,21 +26,21 @@ namespace gfx {
|
|||
* would be obtained using a different (rotated) set of axes. A triple
|
||||
* box blur is a very close approximation of a Gaussian.
|
||||
*
|
||||
* Creates an 8-bit alpha channel context for callers to draw in,
|
||||
* spreads the contents of that context, and blurs the contents.
|
||||
* This is a "service" class; the constructors set up all the information
|
||||
* based on the values and compute the minimum size for an 8-bit alpha
|
||||
* channel context.
|
||||
* The callers are responsible for creating and managing the backing surface
|
||||
* and passing the pointer to the data to the Blur() method. This class does
|
||||
* not retain the pointer to the data outside of the Blur() call.
|
||||
*
|
||||
* A spread N makes each output pixel the maximum value of all source
|
||||
* pixels within a square of side length 2N+1 centered on the output pixel.
|
||||
*
|
||||
* A temporary surface is created in the Init function. The caller then draws
|
||||
* any desired content onto the context acquired through GetContext, and lastly
|
||||
* calls Paint to apply the blurred content as an alpha mask.
|
||||
*/
|
||||
class GFX2D_API AlphaBoxBlur
|
||||
{
|
||||
public:
|
||||
|
||||
/** Constructs a box blur and initializes the backing surface.
|
||||
/** Constructs a box blur and computes the backing surface size.
|
||||
*
|
||||
* @param aRect The coordinates of the surface to create in device units.
|
||||
*
|
||||
|
@ -62,29 +64,19 @@ public:
|
|||
const Rect* aDirtyRect,
|
||||
const Rect* aSkipRect);
|
||||
|
||||
AlphaBoxBlur(uint8_t* aData,
|
||||
const Rect& aRect,
|
||||
AlphaBoxBlur(const Rect& aRect,
|
||||
int32_t aStride,
|
||||
float aSigma);
|
||||
|
||||
~AlphaBoxBlur();
|
||||
|
||||
/**
|
||||
* Return the pointer to memory allocated by the constructor for the 8-bit
|
||||
* alpha surface you need to be blurred. After you draw to this surface, call
|
||||
* Blur(), below, to have its contents blurred.
|
||||
*/
|
||||
unsigned char* GetData();
|
||||
|
||||
/**
|
||||
* Return the size, in pixels, of the 8-bit alpha surface backed by the
|
||||
* pointer returned by GetData().
|
||||
* Return the size, in pixels, of the 8-bit alpha surface we'd use.
|
||||
*/
|
||||
IntSize GetSize();
|
||||
|
||||
/**
|
||||
* Return the stride, in bytes, of the 8-bit alpha surface backed by the
|
||||
* pointer returned by GetData().
|
||||
* Return the stride, in bytes, of the 8-bit alpha surface we'd use.
|
||||
*/
|
||||
int32_t GetStride();
|
||||
|
||||
|
@ -100,10 +92,20 @@ public:
|
|||
Rect* GetDirtyRect();
|
||||
|
||||
/**
|
||||
* Perform the blur in-place on the surface backed by the pointer returned by
|
||||
* GetData().
|
||||
* Return the minimum buffer size that should be given to Blur() method. If
|
||||
* negative, the class is not properly setup for blurring. Note that this
|
||||
* includes the extra three bytes on top of the stride*width, where something
|
||||
* like gfxImageSurface::GetDataSize() would report without it, even if it
|
||||
* happens to have the extra bytes.
|
||||
*/
|
||||
void Blur();
|
||||
int32_t GetSurfaceAllocationSize() const;
|
||||
|
||||
/**
|
||||
* Perform the blur in-place on the surface backed by specified 8-bit
|
||||
* alpha surface data. The size must be at least that returned by
|
||||
* GetSurfaceAllocationSize() or bad things will happen.
|
||||
*/
|
||||
void Blur(uint8_t* aData);
|
||||
|
||||
/**
|
||||
* Calculates a blur radius that, when used with box blur, approximates a
|
||||
|
@ -115,9 +117,11 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void BoxBlur_C(int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
|
||||
void BoxBlur_C(uint8_t* aData,
|
||||
int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
|
||||
int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
|
||||
void BoxBlur_SSE2(int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
|
||||
void BoxBlur_SSE2(uint8_t* aData,
|
||||
int32_t aLeftLobe, int32_t aRightLobe, int32_t aTopLobe,
|
||||
int32_t aBottomLobe, uint32_t *aIntegralImage, size_t aIntegralImageStride);
|
||||
|
||||
static CheckedInt<int32_t> RoundUpToMultipleOf4(int32_t aVal);
|
||||
|
@ -150,20 +154,15 @@ private:
|
|||
IntSize mBlurRadius;
|
||||
|
||||
/**
|
||||
* A pointer to the backing 8-bit alpha surface.
|
||||
*/
|
||||
uint8_t* mData;
|
||||
|
||||
/**
|
||||
* True if we need to dispose the data.
|
||||
*/
|
||||
bool mFreeData;
|
||||
|
||||
/**
|
||||
* The stride of the data contained in mData.
|
||||
* The stride of the data passed to Blur()
|
||||
*/
|
||||
int32_t mStride;
|
||||
|
||||
/**
|
||||
* The minimum size of the buffer needed for the Blur() operation.
|
||||
*/
|
||||
int32_t mSurfaceAllocationSize;
|
||||
|
||||
/**
|
||||
* Whether mDirtyRect contains valid data.
|
||||
*/
|
||||
|
|
|
@ -174,7 +174,8 @@ GenerateIntegralImage_SSE2(int32_t aLeftInflation, int32_t aRightInflation,
|
|||
* Attempt to do an in-place box blur using an integral image.
|
||||
*/
|
||||
void
|
||||
AlphaBoxBlur::BoxBlur_SSE2(int32_t aLeftLobe,
|
||||
AlphaBoxBlur::BoxBlur_SSE2(uint8_t* aData,
|
||||
int32_t aLeftLobe,
|
||||
int32_t aRightLobe,
|
||||
int32_t aTopLobe,
|
||||
int32_t aBottomLobe,
|
||||
|
@ -204,7 +205,7 @@ AlphaBoxBlur::BoxBlur_SSE2(int32_t aLeftLobe,
|
|||
int32_t leftInflation = RoundUpToMultipleOf4(aLeftLobe).value();
|
||||
|
||||
GenerateIntegralImage_SSE2(leftInflation, aRightLobe, aTopLobe, aBottomLobe,
|
||||
aIntegralImage, aIntegralImageStride, mData,
|
||||
aIntegralImage, aIntegralImageStride, aData,
|
||||
mStride, size);
|
||||
|
||||
__m128i divisor = _mm_set1_epi32(reciprocal);
|
||||
|
@ -216,7 +217,7 @@ AlphaBoxBlur::BoxBlur_SSE2(int32_t aLeftLobe,
|
|||
|
||||
IntRect skipRect = mSkipRect;
|
||||
int32_t stride = mStride;
|
||||
uint8_t *data = mData;
|
||||
uint8_t *data = aData;
|
||||
for (int32_t y = 0; y < size.height; y++) {
|
||||
bool inSkipRectY = y > skipRect.y && y < skipRect.YMost();
|
||||
|
||||
|
|
|
@ -428,11 +428,10 @@ DrawTargetCairo::DrawSurfaceWithShadow(SourceSurface *aSurface,
|
|||
|
||||
MOZ_ASSERT(cairo_surface_get_type(blursurf) == CAIRO_SURFACE_TYPE_IMAGE);
|
||||
Rect extents(0, 0, width, height);
|
||||
AlphaBoxBlur blur(cairo_image_surface_get_data(blursurf),
|
||||
extents,
|
||||
AlphaBoxBlur blur(extents,
|
||||
cairo_image_surface_get_stride(blursurf),
|
||||
aSigma);
|
||||
blur.Blur();
|
||||
blur.Blur(cairo_image_surface_get_data(blursurf));
|
||||
} else {
|
||||
blursurf = sourcesurf;
|
||||
surf = sourcesurf;
|
||||
|
|
|
@ -16,8 +16,6 @@ gfxAlphaBoxBlur::gfxAlphaBoxBlur()
|
|||
|
||||
gfxAlphaBoxBlur::~gfxAlphaBoxBlur()
|
||||
{
|
||||
// Drop references to mContext and mImageSurface before we delete mBlur,
|
||||
// because the image surface points to data in mBlur.
|
||||
mContext = nullptr;
|
||||
mImageSurface = nullptr;
|
||||
delete mBlur;
|
||||
|
@ -50,17 +48,19 @@ gfxAlphaBoxBlur::Init(const gfxRect& aRect,
|
|||
}
|
||||
|
||||
mBlur = new AlphaBoxBlur(rect, spreadRadius, blurRadius, dirtyRect, skipRect);
|
||||
|
||||
unsigned char* data = mBlur->GetData();
|
||||
if (!data)
|
||||
return nullptr;
|
||||
int32_t blurDataSize = mBlur->GetSurfaceAllocationSize();
|
||||
if (blurDataSize <= 0)
|
||||
return nullptr;
|
||||
|
||||
IntSize size = mBlur->GetSize();
|
||||
|
||||
// Make an alpha-only surface to draw on. We will play with the data after
|
||||
// everything is drawn to create a blur effect.
|
||||
mImageSurface = new gfxImageSurface(data, gfxIntSize(size.width, size.height),
|
||||
mImageSurface = new gfxImageSurface(gfxIntSize(size.width, size.height),
|
||||
gfxASurface::ImageFormatA8,
|
||||
mBlur->GetStride(),
|
||||
gfxASurface::ImageFormatA8);
|
||||
blurDataSize,
|
||||
true);
|
||||
if (mImageSurface->CairoStatus())
|
||||
return nullptr;
|
||||
|
||||
|
@ -83,7 +83,7 @@ gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx, const gfxPoint& offset)
|
|||
if (!mContext)
|
||||
return;
|
||||
|
||||
mBlur->Blur();
|
||||
mBlur->Blur(mImageSurface->Data());
|
||||
|
||||
mozilla::gfx::Rect* dirtyrect = mBlur->GetDirtyRect();
|
||||
|
||||
|
|
|
@ -95,12 +95,26 @@ TryAllocAlignedBytes(size_t aSize)
|
|||
#endif
|
||||
}
|
||||
|
||||
gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format, bool aClear) :
|
||||
mSize(size), mOwnsData(false), mData(nullptr), mFormat(format)
|
||||
gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format, bool aClear)
|
||||
: mSize(size), mData(nullptr), mFormat(format)
|
||||
{
|
||||
mStride = ComputeStride();
|
||||
AllocateAndInit(0, 0, aClear);
|
||||
}
|
||||
|
||||
if (!CheckSurfaceSize(size))
|
||||
void
|
||||
gfxImageSurface::AllocateAndInit(long aStride, int32_t aMinimalAllocation,
|
||||
bool aClear)
|
||||
{
|
||||
// The callers should set mSize and mFormat.
|
||||
MOZ_ASSERT(!mData);
|
||||
mData = nullptr;
|
||||
mOwnsData = false;
|
||||
|
||||
mStride = aStride > 0 ? aStride : ComputeStride();
|
||||
if (aMinimalAllocation < mSize.height * mStride)
|
||||
aMinimalAllocation = mSize.height * mStride;
|
||||
|
||||
if (!CheckSurfaceSize(mSize))
|
||||
MakeInvalid();
|
||||
|
||||
// if we have a zero-sized surface, just leave mData nullptr
|
||||
|
@ -108,18 +122,18 @@ gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format,
|
|||
|
||||
// This can fail to allocate memory aligned as we requested,
|
||||
// or it can fail to allocate any memory at all.
|
||||
mData = (unsigned char *) TryAllocAlignedBytes(mSize.height * mStride);
|
||||
mData = (unsigned char *) TryAllocAlignedBytes(aMinimalAllocation);
|
||||
if (!mData)
|
||||
return;
|
||||
if (aClear)
|
||||
memset(mData, 0, mSize.height * mStride);
|
||||
memset(mData, 0, aMinimalAllocation);
|
||||
}
|
||||
|
||||
mOwnsData = true;
|
||||
|
||||
cairo_surface_t *surface =
|
||||
cairo_image_surface_create_for_data((unsigned char*)mData,
|
||||
(cairo_format_t)format,
|
||||
(cairo_format_t)mFormat,
|
||||
mSize.width,
|
||||
mSize.height,
|
||||
mStride);
|
||||
|
@ -132,6 +146,13 @@ gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format,
|
|||
}
|
||||
}
|
||||
|
||||
gfxImageSurface::gfxImageSurface(const gfxIntSize& size, gfxImageFormat format,
|
||||
long aStride, int32_t aExtraBytes, bool aClear)
|
||||
: mSize(size), mData(nullptr), mFormat(format)
|
||||
{
|
||||
AllocateAndInit(aStride, aExtraBytes, aClear);
|
||||
}
|
||||
|
||||
gfxImageSurface::gfxImageSurface(cairo_surface_t *csurf)
|
||||
{
|
||||
mSize.width = cairo_image_surface_get_width(csurf);
|
||||
|
|
|
@ -46,6 +46,25 @@ public:
|
|||
* @see gfxImageFormat
|
||||
*/
|
||||
gfxImageSurface(const gfxIntSize& size, gfxImageFormat format, bool aClear = true);
|
||||
|
||||
/**
|
||||
* Construct an image surface, with a specified stride and allowing the
|
||||
* allocation of more memory than required for the storage of the surface
|
||||
* itself. When aStride and aMinimalAllocation are <=0, this constructor
|
||||
* is the equivalent of the preceeding one.
|
||||
*
|
||||
* @param format Format of the data
|
||||
* @param aSize The size of the buffer
|
||||
* @param aStride The stride of the buffer - if <=0, use ComputeStride()
|
||||
* @param aMinimalAllocation Allocate at least this many bytes. If smaller
|
||||
* than width * stride, or width*stride <=0, this value is ignored.
|
||||
* @param aClear
|
||||
*
|
||||
* @see gfxImageFormat
|
||||
*/
|
||||
gfxImageSurface(const gfxIntSize& aSize, gfxImageFormat aFormat,
|
||||
long aStride, int32_t aMinimalAllocation, bool aClear);
|
||||
|
||||
gfxImageSurface(cairo_surface_t *csurf);
|
||||
|
||||
virtual ~gfxImageSurface();
|
||||
|
@ -104,7 +123,14 @@ protected:
|
|||
gfxImageSurface();
|
||||
void InitWithData(unsigned char *aData, const gfxIntSize& aSize,
|
||||
long aStride, gfxImageFormat aFormat);
|
||||
/**
|
||||
* See the parameters to the matching constructor. This should only
|
||||
* be called once, in the constructor, which has already set mSize
|
||||
* and mFormat.
|
||||
*/
|
||||
void AllocateAndInit(long aStride, int32_t aMinimalAllocation, bool aClear);
|
||||
void InitFromSurface(cairo_surface_t *csurf);
|
||||
|
||||
long ComputeStride() const { return ComputeStride(mSize, mFormat); }
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче