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:
vincentliu
2016-03-04 15:24:00 +08:00
parent a8c155bf79
commit e5802e9840
4 changed files with 71 additions and 25 deletions

View File

@@ -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>

View File

@@ -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();

View File

@@ -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);
}

View File

@@ -30,6 +30,7 @@ class GLContext;
namespace dom {
class HTMLCanvasElement;
class CanvasRenderingContext2D;
}
namespace layers {