diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp index 81588e0e8fcc..3eb4116d1e48 100644 --- a/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp +++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.cpp @@ -546,7 +546,6 @@ NS_INTERFACE_MAP_END uint32_t nsCanvasRenderingContext2DAzure::sNumLivingContexts = 0; uint8_t (*nsCanvasRenderingContext2DAzure::sUnpremultiplyTable)[256] = nullptr; uint8_t (*nsCanvasRenderingContext2DAzure::sPremultiplyTable)[256] = nullptr; -RefPtr nsCanvasRenderingContext2DAzure::sErrorTarget = nullptr; namespace mozilla { namespace dom { @@ -578,7 +577,7 @@ NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult) } nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure() - : mZero(false), mOpaque(false), mResetLayer(true) + : mValid(false), mZero(false), mOpaque(false), mResetLayer(true) , mIPC(false) , mIsEntireFrameInvalid(false) , mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false) @@ -601,7 +600,6 @@ nsCanvasRenderingContext2DAzure::~nsCanvasRenderingContext2DAzure() delete[] sPremultiplyTable; sUnpremultiplyTable = nullptr; sPremultiplyTable = nullptr; - NS_IF_RELEASE(sErrorTarget); } } @@ -651,7 +649,7 @@ nsCanvasRenderingContext2DAzure::Reset() // only do this for non-docshell created contexts, // since those are the ones that we created a surface for - if (mTarget && IsTargetValid() && !mDocShell) { + if (mValid && !mDocShell) { gCanvasAzureMemoryUsed -= mWidth * mHeight * 4; } @@ -660,6 +658,7 @@ nsCanvasRenderingContext2DAzure::Reset() // Since the target changes the backing texture will change, and this will // no longer be valid. mThebesSurface = nullptr; + mValid = false; mIsEntireFrameInvalid = false; mPredictManyRedrawCalls = false; @@ -836,15 +835,22 @@ nsCanvasRenderingContext2DAzure::RedrawUser(const gfxRect& r) Redraw(newr); } -void -nsCanvasRenderingContext2DAzure::EnsureTarget() +NS_IMETHODIMP +nsCanvasRenderingContext2DAzure::SetDimensions(int32_t width, int32_t height) { - if (mTarget) { - return; + RefPtr target; + + // Zero sized surfaces cause issues, so just go with 1x1. + if (height == 0 || width == 0) { + mZero = true; + height = 1; + width = 1; + } else { + mZero = false; } - // Check that the dimensions are sane - IntSize size(mWidth, mHeight); + // Check that the dimensions are sane + IntSize size(width, height); if (size.width <= 0xFFFF && size.height <= 0xFFFF && size.width >= 0 && size.height >= 0) { SurfaceFormat format = GetSurfaceFormat(); @@ -860,53 +866,41 @@ nsCanvasRenderingContext2DAzure::EnsureTarget() nsContentUtils::PersistentLayerManagerForDocument(ownerDoc); } - if (layerManager) { - mTarget = layerManager->CreateDrawTarget(size, format); - } else { - mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(size, format); - } + if (layerManager) { + target = layerManager->CreateDrawTarget(size, format); + } else { + target = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(size, format); + } } - if (mTarget) { + if (target) { if (gCanvasAzureMemoryReporter == nullptr) { gCanvasAzureMemoryReporter = new NS_MEMORY_REPORTER_NAME(CanvasAzureMemory); NS_RegisterMemoryReporter(gCanvasAzureMemoryReporter); } - gCanvasAzureMemoryUsed += mWidth * mHeight * 4; + gCanvasAzureMemoryUsed += width * height * 4; JSContext* context = nsContentUtils::GetCurrentJSContext(); if (context) { - JS_updateMallocCounter(context, mWidth * mHeight * 4); + JS_updateMallocCounter(context, width * height * 4); } - } else { - EnsureErrorTarget(); - mTarget = sErrorTarget; - } -} - -NS_IMETHODIMP -nsCanvasRenderingContext2DAzure::SetDimensions(int32_t width, int32_t height) -{ - ClearTarget(); - - // Zero sized surfaces cause issues, so just go with 1x1. - if (height == 0 || width == 0) { - mZero = true; - mWidth = 1; - mHeight = 1; - } else { - mZero = false; - mWidth = width; - mHeight = height; } - return NS_OK; + return InitializeWithTarget(target, width, height); } -void -nsCanvasRenderingContext2DAzure::ClearTarget() +nsresult +nsCanvasRenderingContext2DAzure::Initialize(int32_t width, int32_t height) { - Reset(); + mWidth = width; + mHeight = height; + + if (!mValid) { + // Create a dummy target in the hopes that it will help us deal with users + // calling into us after having changed the size where the size resulted + // in an inability to create a correct DrawTarget. + mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8); + } mResetLayer = true; @@ -922,6 +916,42 @@ nsCanvasRenderingContext2DAzure::ClearTarget() state->colorStyles[STYLE_FILL] = NS_RGB(0,0,0); state->colorStyles[STYLE_STROKE] = NS_RGB(0,0,0); state->shadowColor = NS_RGBA(0,0,0,0); + + if (mTarget) { + mTarget->ClearRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight))); + // always force a redraw, because if the surface dimensions were reset + // then the surface became cleared, and we need to redraw everything. + Redraw(); + } + + return mValid ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +nsresult +nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, int32_t width, int32_t height) +{ + Reset(); + + NS_ASSERTION(mCanvasElement, "Must have a canvas element!"); + mDocShell = nullptr; + + // This first time this is called on this object is via + // nsHTMLCanvasElement::GetContext. If target was non-null then mTarget is + // non-null, otherwise we'll return an error here and GetContext won't + // return this context object and we'll never enter this code again. + // All other times this method is called, if target is null then + // mTarget won't be changed, i.e. it will remain non-null, or else it + // will be set to non-null. + // In all cases, any usable canvas context will have non-null mTarget. + + if (target) { + mValid = true; + mTarget = target; + } else { + mValid = false; + } + + return Initialize(width, height); } NS_IMETHODIMP @@ -930,22 +960,25 @@ nsCanvasRenderingContext2DAzure::InitializeWithSurface(nsIDocShell *shell, gfxAS mDocShell = shell; mThebesSurface = surface; - SetDimensions(width, height); mTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, IntSize(width, height)); - if (!mTarget) { - EnsureErrorTarget(); - mTarget = sErrorTarget; - } + mValid = mTarget != nullptr; - return NS_OK; + return Initialize(width, height); } NS_IMETHODIMP nsCanvasRenderingContext2DAzure::SetIsOpaque(bool isOpaque) { - if (isOpaque != mOpaque) { - mOpaque = isOpaque; - ClearTarget(); + if (isOpaque == mOpaque) + return NS_OK; + + mOpaque = isOpaque; + + if (mValid) { + /* If we've already been created, let SetDimensions take care of + * recreating our surface + */ + return SetDimensions(mWidth, mHeight); } return NS_OK; @@ -954,9 +987,16 @@ nsCanvasRenderingContext2DAzure::SetIsOpaque(bool isOpaque) NS_IMETHODIMP nsCanvasRenderingContext2DAzure::SetIsIPC(bool isIPC) { - if (isIPC != mIPC) { - mIPC = isIPC; - ClearTarget(); + if (isIPC == mIPC) + return NS_OK; + + mIPC = isIPC; + + if (mValid) { + /* If we've already been created, let SetDimensions take care of + * recreating our surface + */ + return SetDimensions(mWidth, mHeight); } return NS_OK; @@ -967,8 +1007,7 @@ nsCanvasRenderingContext2DAzure::Render(gfxContext *ctx, gfxPattern::GraphicsFil { nsresult rv = NS_OK; - EnsureTarget(); - if (!IsTargetValid()) { + if (!mValid || !mTarget) { return NS_ERROR_FAILURE; } @@ -1012,8 +1051,7 @@ nsCanvasRenderingContext2DAzure::GetInputStream(const char *aMimeType, const PRUnichar *aEncoderOptions, nsIInputStream **aStream) { - EnsureTarget(); - if (!IsTargetValid()) { + if (!mValid || !mTarget) { return NS_ERROR_FAILURE; } @@ -1100,7 +1138,6 @@ nsCanvasRenderingContext2DAzure::GetCanvas(nsIDOMHTMLCanvasElement **canvas) void nsCanvasRenderingContext2DAzure::Save() { - EnsureTarget(); mStyleStack[mStyleStack.Length() - 1].transform = mTarget->GetTransform(); mStyleStack.SetCapacity(mStyleStack.Length() + 1); mStyleStack.AppendElement(CurrentState()); @@ -1119,14 +1156,14 @@ nsCanvasRenderingContext2DAzure::Restore() if (mStyleStack.Length() - 1 == 0) return; - TransformWillUpdate(); - for (uint32_t i = 0; i < CurrentState().clipsPushed.size(); i++) { mTarget->PopClip(); } mStyleStack.RemoveElementAt(mStyleStack.Length() - 1); + TransformWillUpdate(); + mTarget->SetTransform(CurrentState().transform); } @@ -1144,15 +1181,16 @@ nsCanvasRenderingContext2DAzure::MozRestore() void nsCanvasRenderingContext2DAzure::Scale(double x, double y, ErrorResult& error) { + if (!mTarget) { + error.Throw(NS_ERROR_FAILURE); + return; + } + if (!FloatValidate(x,y)) { return; } TransformWillUpdate(); - if (!IsTargetValid()) { - error.Throw(NS_ERROR_FAILURE); - return; - } Matrix newMatrix = mTarget->GetTransform(); mTarget->SetTransform(newMatrix.Scale(x, y)); @@ -1169,16 +1207,16 @@ nsCanvasRenderingContext2DAzure::Scale(float x, float y) void nsCanvasRenderingContext2DAzure::Rotate(double angle, ErrorResult& error) { + if (!mTarget) { + error.Throw(NS_ERROR_FAILURE); + return; + } + if (!FloatValidate(angle)) { return; } TransformWillUpdate(); - if (!IsTargetValid()) { - error.Throw(NS_ERROR_FAILURE); - return; - } - Matrix rotation = Matrix::Rotation(angle); mTarget->SetTransform(rotation * mTarget->GetTransform()); @@ -1195,15 +1233,16 @@ nsCanvasRenderingContext2DAzure::Rotate(float angle) void nsCanvasRenderingContext2DAzure::Translate(double x, double y, ErrorResult& error) { + if (!mTarget) { + error.Throw(NS_ERROR_FAILURE); + return; + } + if (!FloatValidate(x,y)) { return; } TransformWillUpdate(); - if (!IsTargetValid()) { - error.Throw(NS_ERROR_FAILURE); - return; - } Matrix newMatrix = mTarget->GetTransform(); mTarget->SetTransform(newMatrix.Translate(x, y)); @@ -1222,15 +1261,16 @@ nsCanvasRenderingContext2DAzure::Transform(double m11, double m12, double m21, double m22, double dx, double dy, ErrorResult& error) { + if (!mTarget) { + error.Throw(NS_ERROR_FAILURE); + return; + } + if (!FloatValidate(m11,m12,m21,m22,dx,dy)) { return; } TransformWillUpdate(); - if (!IsTargetValid()) { - error.Throw(NS_ERROR_FAILURE); - return; - } Matrix matrix(m11, m12, m21, m22, dx, dy); mTarget->SetTransform(matrix * mTarget->GetTransform()); @@ -1251,15 +1291,16 @@ nsCanvasRenderingContext2DAzure::SetTransform(double m11, double m12, double dx, double dy, ErrorResult& error) { + if (!mTarget) { + error.Throw(NS_ERROR_FAILURE); + return; + } + if (!FloatValidate(m11,m12,m21,m22,dx,dy)) { return; } TransformWillUpdate(); - if (!IsTargetValid()) { - error.Throw(NS_ERROR_FAILURE); - return; - } Matrix matrix(m11, m12, m21, m22, dx, dy); mTarget->SetTransform(matrix); @@ -1328,8 +1369,7 @@ nsCanvasRenderingContext2DAzure::SetMozCurrentTransform(JSContext* cx, JSObject& currentTransform, ErrorResult& error) { - EnsureTarget(); - if (!IsTargetValid()) { + if (!mTarget) { error.Throw(NS_ERROR_FAILURE); return; } @@ -1357,7 +1397,12 @@ JSObject* nsCanvasRenderingContext2DAzure::GetMozCurrentTransform(JSContext* cx, ErrorResult& error) const { - return MatrixToJSObject(cx, mTarget ? mTarget->GetTransform() : Matrix(), error); + if (!mTarget) { + error.Throw(NS_ERROR_FAILURE); + return NULL; + } + + return MatrixToJSObject(cx, mTarget->GetTransform(), error); } NS_IMETHODIMP @@ -1377,8 +1422,7 @@ nsCanvasRenderingContext2DAzure::SetMozCurrentTransformInverse(JSContext* cx, JSObject& currentTransform, ErrorResult& error) { - EnsureTarget(); - if (!IsTargetValid()) { + if (!mTarget) { error.Throw(NS_ERROR_FAILURE); return; } @@ -1410,7 +1454,8 @@ nsCanvasRenderingContext2DAzure::GetMozCurrentTransformInverse(JSContext* cx, ErrorResult& error) const { if (!mTarget) { - return MatrixToJSObject(cx, Matrix(), error); + error.Throw(NS_ERROR_FAILURE); + return NULL; } Matrix ctm = mTarget->GetTransform(); @@ -1857,7 +1902,6 @@ nsCanvasRenderingContext2DAzure::CreatePattern(const HTMLImageOrCanvasOrVideoEle return NULL; } - EnsureTarget(); RefPtr srcSurf = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, res.mSurface); @@ -1961,7 +2005,7 @@ void nsCanvasRenderingContext2DAzure::ClearRect(double x, double y, double w, double h) { - if (!FloatValidate(x,y,w,h) || !mTarget) { + if (!FloatValidate(x,y,w,h)) { return; } @@ -2035,7 +2079,6 @@ nsCanvasRenderingContext2DAzure::FillRect(double x, double y, double w, mgfx::Rect bounds; - EnsureTarget(); if (NeedToDrawShadow()) { bounds = mgfx::Rect(x, y, w, h); bounds = mTarget->GetTransform().TransformBounds(bounds); @@ -2067,22 +2110,17 @@ nsCanvasRenderingContext2DAzure::StrokeRect(double x, double y, double w, const ContextState &state = CurrentState(); mgfx::Rect bounds; - - if (!w && !h) { - return; - } - - EnsureTarget(); - if (!IsTargetValid()) { - return; - } - + if (NeedToDrawShadow()) { bounds = mgfx::Rect(x - state.lineWidth / 2.0f, y - state.lineWidth / 2.0f, w + state.lineWidth, h + state.lineWidth); bounds = mTarget->GetTransform().TransformBounds(bounds); } + if (!w && !h) { + return; + } + if (!h) { CapStyle cap = CAP_BUTT; if (state.lineJoin == JOIN_ROUND) { @@ -2453,7 +2491,6 @@ nsCanvasRenderingContext2DAzure::EnsureWritablePath() return; } - EnsureTarget(); if (!mPath) { NS_ASSERTION(!mPathTransformWillUpdate, "mPathTransformWillUpdate should be false, if all paths are null"); mPathBuilder = mTarget->CreatePathBuilder(fillRule); @@ -2472,7 +2509,6 @@ nsCanvasRenderingContext2DAzure::EnsureUserSpacePath(bool aCommitTransform /* = FillRule fillRule = CurrentState().fillRule; if (!mPath && !mPathBuilder && !mDSPathBuilder) { - EnsureTarget(); mPathBuilder = mTarget->CreatePathBuilder(fillRule); } @@ -2518,8 +2554,6 @@ nsCanvasRenderingContext2DAzure::EnsureUserSpacePath(bool aCommitTransform /* = void nsCanvasRenderingContext2DAzure::TransformWillUpdate() { - EnsureTarget(); - // Store the matrix that would transform the current path to device // space. if (mPath || mPathBuilder) { @@ -3003,7 +3037,6 @@ struct NS_STACK_CLASS nsCanvasBidiProcessorAzure : public nsBidiPresUtils::BidiP float advanceSum = 0; - mCtx->EnsureTarget(); for (uint32_t c = 0; c < numRuns; c++) { gfxFont *font = runs[c].mFont; uint32_t endRun = 0; @@ -3204,14 +3237,8 @@ nsCanvasRenderingContext2DAzure::DrawOrMeasureText(const nsAString& aRawText, processor.mPt = gfxPoint(aX, aY); processor.mThebes = new gfxContext(gfxPlatform::GetPlatform()->ScreenReferenceSurface()); - - // If we don't have a target then we don't have a transform. A target won't - // be needed in the case where we're measuring the text size. This allows - // to avoid creating a target if it's only being used to measure text sizes. - if (mTarget) { - Matrix matrix = mTarget->GetTransform(); - processor.mThebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32)); - } + Matrix matrix = mTarget->GetTransform(); + processor.mThebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32)); processor.mCtx = this; processor.mOp = aOp; processor.mBoundingBox = gfxRect(0, 0, 0, 0); @@ -3301,7 +3328,6 @@ nsCanvasRenderingContext2DAzure::DrawOrMeasureText(const nsAString& aRawText, processor.mPt.x *= processor.mAppUnitsPerDevPixel; processor.mPt.y *= processor.mAppUnitsPerDevPixel; - EnsureTarget(); Matrix oldTransform = mTarget->GetTransform(); // if text is over aMaxWidth, then scale the text horizontally such that its // width is precisely aMaxWidth @@ -3641,8 +3667,6 @@ nsCanvasRenderingContext2DAzure::DrawImage(const HTMLImageOrCanvasOrVideoElement gfxIntSize imgSize; Element* element; - - EnsureTarget(); if (image.IsHTMLCanvasElement()) { nsHTMLCanvasElement* canvas = image.GetAsHTMLCanvasElement(); element = canvas; @@ -3904,7 +3928,6 @@ nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* window, double x, nsRefPtr thebes = new gfxContext(drawSurf); - EnsureTarget(); Matrix matrix = mTarget->GetTransform(); thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32)); @@ -4123,8 +4146,7 @@ nsCanvasRenderingContext2DAzure::GetImageData(JSContext* aCx, double aSx, double aSy, double aSw, double aSh, ErrorResult& error) { - EnsureTarget(); - if (!IsTargetValid()) { + if (!mValid) { error.Throw(NS_ERROR_FAILURE); return NULL; } @@ -4317,19 +4339,6 @@ nsCanvasRenderingContext2DAzure::EnsurePremultiplyTable() { } } -void -nsCanvasRenderingContext2DAzure::EnsureErrorTarget() -{ - if (sErrorTarget) { - return; - } - - sErrorTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8); - NS_ABORT_IF_FALSE(sErrorTarget, "Failed to allocate the error target!"); - - NS_ADDREF(sErrorTarget); -} - void nsCanvasRenderingContext2DAzure::FillRuleChanged() { @@ -4398,6 +4407,10 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(int32_t x, int32_t y, uin bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY, int32_t dirtyWidth, int32_t dirtyHeight) { + if (!mValid) { + return NS_ERROR_FAILURE; + } + if (w == 0 || h == 0) { return NS_ERROR_DOM_SYNTAX_ERR; } @@ -4486,11 +4499,6 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(int32_t x, int32_t y, uin } } - EnsureTarget(); - if (!IsTargetValid()) { - return NS_ERROR_FAILURE; - } - RefPtr sourceSurface = mTarget->CreateSourceSurfaceFromData(imgsurf->Data(), IntSize(w, h), imgsurf->Stride(), FORMAT_B8G8R8A8); @@ -4508,7 +4516,13 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(int32_t x, int32_t y, uin NS_IMETHODIMP nsCanvasRenderingContext2DAzure::GetThebesSurface(gfxASurface **surface) { - EnsureTarget(); + if (!mTarget) { + nsRefPtr tmpSurf = + gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(1, 1), gfxASurface::CONTENT_COLOR_ALPHA); + *surface = tmpSurf.forget().get(); + return NS_OK; + } + if (!mThebesSurface) { mThebesSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mTarget); @@ -4618,15 +4632,16 @@ nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder, CanvasLayer *aOldLayer, LayerManager *aManager) { - EnsureTarget(); - if (!IsTargetValid()) { + if (!mValid) { // No DidTransactionCallback will be received, so mark the context clean // now so future invalidations will be dispatched. MarkContextClean(); return nullptr; } - mTarget->Flush(); + if (mTarget) { + mTarget->Flush(); + } if (!mResetLayer && aOldLayer) { CanvasRenderingContext2DUserDataAzure* userData = @@ -4692,5 +4707,5 @@ nsCanvasRenderingContext2DAzure::MarkContextClean() bool nsCanvasRenderingContext2DAzure::ShouldForceInactiveLayer(LayerManager *aManager) { - return !aManager->CanUseCanvasLayerForSize(gfxIntSize(mWidth, mHeight)); + return !aManager->CanUseCanvasLayerForSize(gfxIntSize(mWidth, mHeight)); } diff --git a/content/canvas/src/nsCanvasRenderingContext2DAzure.h b/content/canvas/src/nsCanvasRenderingContext2DAzure.h index 08a90d44b0bc..05ccf614b24a 100644 --- a/content/canvas/src/nsCanvasRenderingContext2DAzure.h +++ b/content/canvas/src/nsCanvasRenderingContext2DAzure.h @@ -566,8 +566,6 @@ protected: */ static uint8_t (*sPremultiplyTable)[256]; - static mozilla::RefPtr sErrorTarget; - // Some helpers. Doesn't modify a color on failure. void SetStyleFromJSValue(JSContext* cx, JS::Value& value, Style whichStyle); void SetStyleFromString(const nsAString& str, Style whichStyle); @@ -600,11 +598,6 @@ protected: */ void EnsurePremultiplyTable(); - /** - * Creates the error target, if it doesn't exist - */ - static void EnsureErrorTarget(); - /* This function ensures there is a writable pathbuilder available, this * pathbuilder may be working in user space or in device space or * device space. @@ -617,33 +610,11 @@ protected: // used for the path. void EnsureUserSpacePath(bool aCommitTransform = true); - /** - * Needs to be called before updating the transform. This makes a call to - * EnsureTarget() so you don't have to. - */ void TransformWillUpdate(); // Report the fillRule has changed. void FillRuleChanged(); - /** - * Create the backing surfacing, if it doesn't exist. If there is an error - * in creating the target then it will put sErrorTarget in place. If there - * is in turn an error in creating the sErrorTarget then they would both - * be null so IsTargetValid() would still return null. - */ - void EnsureTarget(); - - /* - * Disposes an old target and prepares to lazily create a new target. - */ - void ClearTarget(); - - /** - * Check if the target is valid after calling EnsureTarget. - */ - bool IsTargetValid() { return mTarget != sErrorTarget; } - /** * Returns the surface format this canvas should be allocated using. Takes * into account mOpaque, platform requirements, etc. @@ -692,6 +663,10 @@ protected: // Member vars int32_t mWidth, mHeight; + // This is true when the canvas is valid, false otherwise, this occurs when + // for some reason initialization of the drawtarget fails. If the canvas + // is invalid certain behavior is expected. + bool mValid; // This is true when the canvas is valid, but of zero size, this requires // specific behavior on some operations. bool mZero; @@ -709,9 +684,7 @@ protected: // If mCanvasElement is not provided, then a docshell is nsCOMPtr mDocShell; - // This is created lazily so it is necessary to call EnsureTarget before - // accessing it. In the event of an error it will be equal to - // sErrorTarget. + // our drawing surfaces, contexts, and layers mozilla::RefPtr mTarget; /**