Bug 801176 - part6-v1: Modify BufferProvider operations to fix assertions. r=roc
--- dom/canvas/CanvasRenderingContext2D.cpp | 12 +++-- dom/canvas/OffscreenCanvas.cpp | 2 - gfx/layers/AsyncCanvasRenderer.cpp | 85 +++++++++++++++++++++++++-------- gfx/layers/AsyncCanvasRenderer.h | 1 + 4 files changed, 73 insertions(+), 27 deletions(-)
This commit is contained in:
@@ -5667,15 +5667,17 @@ void CanvasRenderingContext2D::RemoveDrawObserver()
|
||||
PersistentBufferProvider*
|
||||
CanvasRenderingContext2D::GetBufferProvider(LayerManager* aManager)
|
||||
{
|
||||
if (!mTarget) {
|
||||
EnsureTarget();
|
||||
}
|
||||
|
||||
if (mBufferProvider) {
|
||||
return mBufferProvider;
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!mTarget) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mBufferProvider = new PersistentBufferProviderBasic(mTarget);
|
||||
|
||||
return mBufferProvider;
|
||||
}
|
||||
|
||||
already_AddRefed<Layer>
|
||||
|
||||
@@ -163,9 +163,7 @@ OffscreenCanvas::GetContext(JSContext* aCx,
|
||||
if (factory)
|
||||
screen->Morph(Move(factory));
|
||||
} else if (contextType == CanvasContextType::Canvas2D) {
|
||||
CanvasRenderingContext2D* context2D = static_cast<CanvasRenderingContext2D*>(mCurrentContext.get());
|
||||
mCanvasRenderer->mGLContext = nullptr;
|
||||
mCanvasRenderer->mBufferProvider = context2D->GetBufferProvider(nullptr);
|
||||
|
||||
mCanvasClient = ImageBridgeChild::GetSingleton()->
|
||||
CreateCanvasClient(CanvasClient::CanvasClientSurface, flags).take();
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/dom/CanvasRenderingContext2D.h"
|
||||
#include "mozilla/layers/BufferTexture.h"
|
||||
#include "mozilla/layers/CanvasClient.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
@@ -21,6 +22,11 @@
|
||||
#include "PersistentBufferProvider.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class CanvasRenderingContext2D;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
AsyncCanvasRenderer::AsyncCanvasRenderer()
|
||||
@@ -238,6 +244,18 @@ AsyncCanvasRenderer::UpdateTarget()
|
||||
void
|
||||
AsyncCanvasRenderer::UpdateTarget(TextureClient* aTexture)
|
||||
{
|
||||
if (!mContext) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBufferProvider = nullptr;
|
||||
|
||||
dom::CanvasRenderingContext2D* context2D = static_cast<dom::CanvasRenderingContext2D*>(mContext);
|
||||
if (!context2D) {
|
||||
return;
|
||||
}
|
||||
|
||||
mBufferProvider = context2D->GetBufferProvider(nullptr);
|
||||
if (!mBufferProvider) {
|
||||
return;
|
||||
}
|
||||
@@ -256,27 +274,52 @@ AsyncCanvasRenderer::GetSurface()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mSurfaceForBasic) {
|
||||
// Since SourceSurface isn't thread-safe, we need copy to a new SourceSurface.
|
||||
RefPtr<gfx::DataSourceSurface> result =
|
||||
gfx::Factory::CreateDataSourceSurfaceWithStride(mSurfaceForBasic->GetSize(),
|
||||
mSurfaceForBasic->GetFormat(),
|
||||
mSurfaceForBasic->Stride());
|
||||
|
||||
gfx::DataSourceSurface::ScopedMap srcMap(mSurfaceForBasic, gfx::DataSourceSurface::READ);
|
||||
gfx::DataSourceSurface::ScopedMap dstMap(result, gfx::DataSourceSurface::WRITE);
|
||||
if (!mContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!srcMap.IsMapped()) ||
|
||||
NS_WARN_IF(!dstMap.IsMapped())) {
|
||||
if (mGLContext) {
|
||||
if (mSurfaceForBasic) {
|
||||
// Since SourceSurface isn't thread-safe, we need copy to a new SourceSurface.
|
||||
RefPtr<gfx::DataSourceSurface> result =
|
||||
gfx::Factory::CreateDataSourceSurfaceWithStride(mSurfaceForBasic->GetSize(),
|
||||
mSurfaceForBasic->GetFormat(),
|
||||
mSurfaceForBasic->Stride());
|
||||
|
||||
gfx::DataSourceSurface::ScopedMap srcMap(mSurfaceForBasic, gfx::DataSourceSurface::READ);
|
||||
gfx::DataSourceSurface::ScopedMap dstMap(result, gfx::DataSourceSurface::WRITE);
|
||||
|
||||
if (NS_WARN_IF(!srcMap.IsMapped()) ||
|
||||
NS_WARN_IF(!dstMap.IsMapped())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memcpy(dstMap.GetData(),
|
||||
srcMap.GetData(),
|
||||
srcMap.GetStride() * mSurfaceForBasic->GetSize().height);
|
||||
return result.forget();
|
||||
} else {
|
||||
return UpdateTarget();
|
||||
}
|
||||
} else {
|
||||
dom::CanvasRenderingContext2D* context2D = static_cast<dom::CanvasRenderingContext2D*>(mContext);
|
||||
if (!context2D) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memcpy(dstMap.GetData(),
|
||||
srcMap.GetData(),
|
||||
srcMap.GetStride() * mSurfaceForBasic->GetSize().height);
|
||||
return result.forget();
|
||||
} else {
|
||||
return UpdateTarget();
|
||||
mBufferProvider = context2D->GetBufferProvider(nullptr);
|
||||
|
||||
if (!mBufferProvider) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<gfx::SourceSurface> sourceSurface = mBufferProvider->GetSnapshot();
|
||||
|
||||
if (!sourceSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
return sourceSurface->GetDataSurface();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,8 +334,10 @@ AsyncCanvasRenderer::GetInputStream(const char *aMimeType,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Handle y flip.
|
||||
RefPtr<gfx::DataSourceSurface> dataSurf = gl::YInvertImageSurface(surface);
|
||||
// Only handle y flip in webgl.
|
||||
RefPtr<gfx::DataSourceSurface> dataSurf = mGLContext
|
||||
? gl::YInvertImageSurface(surface)
|
||||
: surface;
|
||||
|
||||
return gfxUtils::GetInputStream(dataSurf, false, aMimeType, aEncoderOptions, aStream);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ class GLContext;
|
||||
|
||||
namespace dom {
|
||||
class HTMLCanvasElement;
|
||||
class CanvasRenderingContext2D;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
Reference in New Issue
Block a user