already_AddRefed<DrawTarget> gfxAlphaBoxBlur::InitDrawTarget(const DrawTarget* aReferenceDT, const Rect& aRect, const IntSize& aSpreadRadius, const IntSize& aBlurRadius, const Rect* aDirtyRect, const Rect* aSkipRect) { mBlur.Init(aRect, aSpreadRadius, aBlurRadius, aDirtyRect, aSkipRect); size_t blurDataSize = mBlur.GetSurfaceAllocationSize(); if (blurDataSize == 0) { return nullptr; } BackendType backend = aReferenceDT->GetBackendType(); // Check if the backend has an accelerated DrawSurfaceWithShadow. // Currently, only D2D1.1 supports this. // Otherwise, DrawSurfaceWithShadow only supports square blurs without spread. if (aBlurRadius.IsSquare() && aSpreadRadius.IsEmpty() && backend == BackendType::DIRECT2D1_1) { mAccelerated = true; mDrawTarget = aReferenceDT->CreateShadowDrawTarget(mBlur.GetSize(), SurfaceFormat::A8, AlphaBoxBlur::CalculateBlurSigma(aBlurRadius.width)); } else { // Make an alpha-only surface to draw on. We will play with the data after // everything is drawn to create a blur effect. mData = static_cast<uint8_t*>(calloc(1, blurDataSize)); if (!mData) { return nullptr; } mDrawTarget = Factory::DoesBackendSupportDataDrawtarget(backend) ? Factory::CreateDrawTargetForData(backend, mData, mBlur.GetSize(), mBlur.GetStride(), SurfaceFormat::A8) : gfxPlatform::CreateDrawTargetForData(mData, mBlur.GetSize(), mBlur.GetStride(), SurfaceFormat::A8); } if (!mDrawTarget || !mDrawTarget->IsValid()) { return nullptr; } mDrawTarget->SetTransform(Matrix::Translation(-mBlur.GetRect().TopLeft())); return do_AddRef(mDrawTarget); }
already_AddRefed<DrawTarget> gfxAlphaBoxBlur::InitDrawTarget(const DrawTarget* aReferenceDT, const Rect& aRect, const IntSize& aSpreadRadius, const IntSize& aBlurRadius, const Rect* aDirtyRect, const Rect* aSkipRect, bool aUseHardwareAccel) { mBlur.Init(aRect, aSpreadRadius, aBlurRadius, aDirtyRect, aSkipRect); size_t blurDataSize = mBlur.GetSurfaceAllocationSize(); if (blurDataSize == 0) { return nullptr; } BackendType backend = aReferenceDT->GetBackendType(); // Check if the backend has an accelerated DrawSurfaceWithShadow. // Currently, only D2D1.1 supports this. // Otherwise, DrawSurfaceWithShadow only supports square blurs without spread. // When blurring small draw targets such as short spans text, the cost of // creating and flushing an accelerated draw target may exceed the speedup // gained from the faster blur. It's up to the users of this blur // to determine whether they want to use hardware acceleration. if (aBlurRadius.IsSquare() && aSpreadRadius.IsEmpty() && aUseHardwareAccel && backend == BackendType::DIRECT2D1_1) { mAccelerated = true; mDrawTarget = aReferenceDT->CreateShadowDrawTarget(mBlur.GetSize(), SurfaceFormat::A8, AlphaBoxBlur::CalculateBlurSigma(aBlurRadius.width)); } else { // Make an alpha-only surface to draw on. We will play with the data after // everything is drawn to create a blur effect. // This will be freed when the DrawTarget dies mData = static_cast<uint8_t*>(calloc(1, blurDataSize)); if (!mData) { return nullptr; } mDrawTarget = Factory::DoesBackendSupportDataDrawtarget(backend) ? Factory::CreateDrawTargetForData(backend, mData, mBlur.GetSize(), mBlur.GetStride(), SurfaceFormat::A8) : gfxPlatform::CreateDrawTargetForData(mData, mBlur.GetSize(), mBlur.GetStride(), SurfaceFormat::A8); } if (!mDrawTarget || !mDrawTarget->IsValid()) { if (mData) { free(mData); } return nullptr; } if (mData) { mDrawTarget->AddUserData(reinterpret_cast<UserDataKey*>(mDrawTarget.get()), mData, free); } mDrawTarget->SetTransform(Matrix::Translation(-mBlur.GetRect().TopLeft())); return do_AddRef(mDrawTarget); }