Bug 1309913: Pass the compositor type to canvas on creation. r=dvander

MozReview-Commit-ID: 81HtvWPdLQa

--HG--
extra : rebase_source : a448447fcb573beb320b2b2a352b97f77a5bafe3
This commit is contained in:
Milan Sreckovic 2016-11-03 10:57:33 -04:00
Родитель dbb85be2ac
Коммит 976fdb1420
7 изменённых файлов: 59 добавлений и 18 удалений

Просмотреть файл

@ -1053,8 +1053,9 @@ DrawTarget* CanvasRenderingContext2D::sErrorTarget = nullptr;
CanvasRenderingContext2D::CanvasRenderingContext2D()
CanvasRenderingContext2D::CanvasRenderingContext2D(layers::LayersBackend aCompositorBackend)
: mRenderingMode(RenderingMode::OpenGLBackendMode)
, mCompositorBackend(aCompositorBackend)
// these are the default values from the Canvas spec
, mWidth(0), mHeight(0)
, mZero(false), mOpaque(false)
@ -1075,7 +1076,7 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
nsContentUtils::RegisterShutdownObserver(mShutdownObserver);
// The default is to use OpenGL mode
if (gfxPlatform::GetPlatform()->AllowOpenGLCanvas()) {
if (AllowOpenGLCanvas()) {
mDrawObserver = new CanvasDrawObserver(this);
} else {
mRenderingMode = RenderingMode::SoftwareBackendMode;
@ -1321,6 +1322,26 @@ CanvasRenderingContext2D::RedrawUser(const gfxRect& aR)
Redraw(newr);
}
bool
CanvasRenderingContext2D::AllowOpenGLCanvas() const
{
// If we somehow didn't have the correct compositor in the constructor,
// we could do something like this to get it:
//
// HTMLCanvasElement* el = GetCanvas();
// if (el) {
// mCompositorBackend = el->GetCompositorBackendType();
// }
//
// We could have LAYERS_NONE if there was no widget at the time of
// canvas creation, but in that case the
// HTMLCanvasElement::GetCompositorBackendType would return LAYERS_NONE
// as well, so it wouldn't help much.
return (mCompositorBackend == LayersBackend::LAYERS_OPENGL) &&
gfxPlatform::GetPlatform()->AllowOpenGLCanvas();
}
bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
{
if (!IsTargetValid() || mRenderingMode == aRenderingMode) {
@ -1332,7 +1353,7 @@ bool CanvasRenderingContext2D::SwitchRenderingMode(RenderingMode aRenderingMode)
#ifdef USE_SKIA_GPU
// Do not attempt to switch into GL mode if the platform doesn't allow it.
if ((aRenderingMode == RenderingMode::OpenGLBackendMode) &&
!gfxPlatform::GetPlatform()->AllowOpenGLCanvas()) {
!AllowOpenGLCanvas()) {
return false;
}
#endif
@ -1708,13 +1729,10 @@ CanvasRenderingContext2D::TrySkiaGLTarget(RefPtr<gfx::DrawTarget>& aOutDT,
aOutDT = nullptr;
aOutProvider = nullptr;
mIsSkiaGL = false;
IntSize size(mWidth, mHeight);
if (!gfxPlatform::GetPlatform()->AllowOpenGLCanvas() ||
!CheckSizeForSkiaGL(size)) {
if (!AllowOpenGLCanvas() || !CheckSizeForSkiaGL(size)) {
return false;
}
@ -4760,7 +4778,7 @@ CanvasRenderingContext2D::DrawImage(const CanvasImageSource& aImage,
mIsSkiaGL &&
!srcSurf &&
aImage.IsHTMLVideoElement() &&
gfxPlatform::GetPlatform()->AllowOpenGLCanvas()) {
AllowOpenGLCanvas()) {
mozilla::gl::GLContext* gl = gfxPlatform::GetPlatform()->GetSkiaGLGlue()->GetGLContext();
MOZ_ASSERT(gl);

Просмотреть файл

@ -66,13 +66,13 @@ class CanvasRenderingContext2D final :
virtual ~CanvasRenderingContext2D();
public:
CanvasRenderingContext2D();
explicit CanvasRenderingContext2D(layers::LayersBackend aCompositorBackend);
virtual JSObject* WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
HTMLCanvasElement* GetCanvas() const
{
if (mCanvasElement->IsInNativeAnonymousSubtree()) {
if (!mCanvasElement || mCanvasElement->IsInNativeAnonymousSubtree()) {
return nullptr;
}
@ -538,6 +538,10 @@ public:
bool GetHitRegionRect(Element* aElement, nsRect& aRect) override;
void OnShutdown();
// Check the global setup, as well as the compositor type:
bool AllowOpenGLCanvas() const;
protected:
nsresult GetImageDataArray(JSContext* aCx, int32_t aX, int32_t aY,
uint32_t aWidth, uint32_t aHeight,
@ -733,6 +737,8 @@ protected:
RenderingMode mRenderingMode;
layers::LayersBackend mCompositorBackend;
// Member vars
int32_t mWidth, mHeight;

Просмотреть файл

@ -122,6 +122,13 @@ CanvasRenderingContextHelper::ToBlob(JSContext* aCx,
already_AddRefed<nsICanvasRenderingContextInternal>
CanvasRenderingContextHelper::CreateContext(CanvasContextType aContextType)
{
return CreateContextHelper(aContextType, layers::LayersBackend::LAYERS_NONE);
}
already_AddRefed<nsICanvasRenderingContextInternal>
CanvasRenderingContextHelper::CreateContextHelper(CanvasContextType aContextType,
layers::LayersBackend aCompositorBackend)
{
MOZ_ASSERT(aContextType != CanvasContextType::NoContext);
RefPtr<nsICanvasRenderingContextInternal> ret;
@ -132,7 +139,7 @@ CanvasRenderingContextHelper::CreateContext(CanvasContextType aContextType)
case CanvasContextType::Canvas2D:
Telemetry::Accumulate(Telemetry::CANVAS_2D_USED, 1);
ret = new CanvasRenderingContext2D();
ret = new CanvasRenderingContext2D(aCompositorBackend);
break;
case CanvasContextType::WebGL1:

Просмотреть файл

@ -7,6 +7,7 @@
#define MOZILLA_DOM_CANVASRENDERINGCONTEXTHELPER_H_
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/layers/LayersTypes.h"
#include "nsSize.h"
class nsICanvasRenderingContextInternal;
@ -66,6 +67,10 @@ protected:
virtual already_AddRefed<nsICanvasRenderingContextInternal>
CreateContext(CanvasContextType aContextType);
already_AddRefed<nsICanvasRenderingContextInternal>
CreateContextHelper(CanvasContextType aContextType,
layers::LayersBackend aCompositorBackend);
virtual nsIntSize GetWidthHeight() = 0;
CanvasContextType mCurrentContextType;

Просмотреть файл

@ -402,8 +402,9 @@ HTMLCanvasElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
already_AddRefed<nsICanvasRenderingContextInternal>
HTMLCanvasElement::CreateContext(CanvasContextType aContextType)
{
// Note that the compositor backend will be LAYERS_NONE if there is no widget.
RefPtr<nsICanvasRenderingContextInternal> ret =
CanvasRenderingContextHelper::CreateContext(aContextType);
CreateContextHelper(aContextType, GetCompositorBackendType());
// Add Observer for webgl canvas.
if (aContextType == CanvasContextType::WebGL1 ||

Просмотреть файл

@ -1259,10 +1259,15 @@ bool gfxPlatform::AllowOpenGLCanvas()
// For now, only allow Skia+OpenGL, unless it's blocked.
// Allow acceleration on Skia if the preference is set, unless it's blocked
// as long as we have the accelerated layers
if (gfxPrefs::CanvasAzureAccelerated() &&
mCompositorBackend == LayersBackend::LAYERS_OPENGL &&
(GetContentBackendFor(mCompositorBackend) == BackendType::SKIA))
{
// The compositor backend is only set correctly in the parent process,
// so we let content process always assume correct compositor backend.
// The callers have to do the right thing.
bool correctBackend = !XRE_IsParentProcess() ||
((mCompositorBackend == LayersBackend::LAYERS_OPENGL) &&
(GetContentBackendFor(mCompositorBackend) == BackendType::SKIA));
if (gfxPrefs::CanvasAzureAccelerated() && correctBackend) {
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
int32_t status;
nsCString discardFailureId;

Просмотреть файл

@ -66,8 +66,7 @@ random-if(cocoaWidget&&azureSkia) random-if(!cocoaWidget||OSX==1006||OSX==1007)
# azure quartz uses CGDrawLinearGradient instead of DrawShading
# so we have less control over degenerate behaviour as tested by this
# test
# This test should pass with SkiaGL, but due to bug 1309913, e10s prevents SkiaGL from working.
fails-if((azureSkia&&!azureSkiaGL)||azureQuartz||(azureSkiaGL&&(browserIsRemote||Android))) == linear-gradient-1a.html linear-gradient-1-ref.html
fails-if((azureSkia&&!azureSkiaGL)||azureQuartz||(azureSkiaGL&&Android)) == linear-gradient-1a.html linear-gradient-1-ref.html
# this passes with cairo on 10.7 and 10.8 but not with azure for reasons unknown
# This test should pass with SkiaGL, but due to bug 1309913, e10s prevents SkiaGL from working.