mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1096633 - Allow webgl/experimental-webgl aliasing. - r=kamidphish
This commit is contained in:
parent
30da52aa2b
commit
48006b5d6e
@ -4,47 +4,48 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGL1Context.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
namespace mozilla {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// CONSTRUCTOR & DESTRUCTOR
|
||||
/*static*/ WebGL1Context*
|
||||
WebGL1Context::Create()
|
||||
{
|
||||
return new WebGL1Context();
|
||||
}
|
||||
|
||||
WebGL1Context::WebGL1Context()
|
||||
: WebGLContext()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WebGL1Context::~WebGL1Context()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// IMPLEMENT nsWrapperCache
|
||||
////////////////////////////////////////
|
||||
// nsWrapperCache
|
||||
|
||||
JSObject*
|
||||
WebGL1Context::WrapObject(JSContext *cx)
|
||||
WebGL1Context::WrapObject(JSContext* cx)
|
||||
{
|
||||
return dom::WebGLRenderingContextBinding::Wrap(cx, this);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// INSTANCING nsIDOMWebGLRenderingContext
|
||||
////////////////////////////////////////
|
||||
// nsIDOMWebGLRenderingContext
|
||||
|
||||
nsresult
|
||||
NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult)
|
||||
NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** out_result)
|
||||
{
|
||||
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
|
||||
nsIDOMWebGLRenderingContext* ctx = new WebGL1Context();
|
||||
|
||||
NS_ADDREF(*aResult = ctx);
|
||||
nsIDOMWebGLRenderingContext* ctx = WebGL1Context::Create();
|
||||
|
||||
NS_ADDREF(*out_result = ctx);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef WEBGL1CONTEXT_H_
|
||||
#define WEBGL1CONTEXT_H_
|
||||
#ifndef WEBGL_1_CONTEXT_H_
|
||||
#define WEBGL_1_CONTEXT_H_
|
||||
|
||||
#include "WebGLContext.h"
|
||||
|
||||
@ -13,34 +13,23 @@ namespace mozilla {
|
||||
class WebGL1Context
|
||||
: public WebGLContext
|
||||
{
|
||||
// -----------------------------------------------------------------------------
|
||||
// PUBLIC
|
||||
public:
|
||||
static WebGL1Context* Create();
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// CONSTRUCTOR & DESTRUCTOR
|
||||
|
||||
private:
|
||||
WebGL1Context();
|
||||
|
||||
public:
|
||||
virtual ~WebGL1Context();
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// IMPLEMENT WebGLContext
|
||||
|
||||
virtual bool IsWebGL2() const MOZ_OVERRIDE
|
||||
{
|
||||
virtual bool IsWebGL2() const MOZ_OVERRIDE {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// IMPLEMENT nsWrapperCache
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
|
||||
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext* cx) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
#endif // WEBGL_1_CONTEXT_H_
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsStreamUtils.h"
|
||||
#include "ActiveLayerTracker.h"
|
||||
#include "WebGL1Context.h"
|
||||
#include "WebGL2Context.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
@ -648,71 +649,71 @@ HTMLCanvasElement::MozGetAsFileImpl(const nsAString& aName,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HTMLCanvasElement::GetContextHelper(const nsAString& aContextId,
|
||||
nsICanvasRenderingContextInternal **aContext)
|
||||
static bool
|
||||
GetCanvasContextType(const nsAString& str, CanvasContextType* const out_type)
|
||||
{
|
||||
NS_ENSURE_ARG(aContext);
|
||||
if (str.EqualsLiteral("2d")) {
|
||||
*out_type = CanvasContextType::Canvas2D;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aContextId.EqualsLiteral("2d")) {
|
||||
if (str.EqualsLiteral("experimental-webgl")) {
|
||||
*out_type = CanvasContextType::WebGL1;
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WEBGL_CONFORMANT
|
||||
if (str.EqualsLiteral("webgl")) {
|
||||
/* WebGL 1.0, $2.1 "Context Creation":
|
||||
* If the user agent supports both the webgl and experimental-webgl
|
||||
* canvas context types, they shall be treated as aliases.
|
||||
*/
|
||||
*out_type = CanvasContextType::WebGL1;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (WebGL2Context::IsSupported()) {
|
||||
if (str.EqualsLiteral("experimental-webgl2")) {
|
||||
*out_type = CanvasContextType::WebGL2;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static already_AddRefed<nsICanvasRenderingContextInternal>
|
||||
CreateContextForCanvas(CanvasContextType contextType, HTMLCanvasElement* canvas)
|
||||
{
|
||||
nsRefPtr<nsICanvasRenderingContextInternal> ret;
|
||||
|
||||
switch (contextType) {
|
||||
case CanvasContextType::Canvas2D:
|
||||
Telemetry::Accumulate(Telemetry::CANVAS_2D_USED, 1);
|
||||
nsRefPtr<CanvasRenderingContext2D> ctx =
|
||||
new CanvasRenderingContext2D();
|
||||
ret = new CanvasRenderingContext2D();
|
||||
break;
|
||||
|
||||
ctx->SetCanvasElement(this);
|
||||
ctx.forget(aContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (WebGL2Context::IsSupported() &&
|
||||
aContextId.EqualsLiteral("experimental-webgl2"))
|
||||
{
|
||||
case CanvasContextType::WebGL1:
|
||||
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
|
||||
nsRefPtr<WebGL2Context> ctx = WebGL2Context::Create();
|
||||
|
||||
if (ctx == nullptr) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
ret = WebGL1Context::Create();
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
break;
|
||||
|
||||
case CanvasContextType::WebGL2:
|
||||
Telemetry::Accumulate(Telemetry::CANVAS_WEBGL_USED, 1);
|
||||
|
||||
ret = WebGL2Context::Create();
|
||||
if (!ret)
|
||||
return nullptr;
|
||||
break;
|
||||
}
|
||||
MOZ_ASSERT(ret);
|
||||
|
||||
ctx->SetCanvasElement(this);
|
||||
ctx.forget(aContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ConvertUTF16toUTF8 ctxId(aContextId);
|
||||
|
||||
// check that ctxId is clamped to A-Za-z0-9_-
|
||||
for (uint32_t i = 0; i < ctxId.Length(); i++) {
|
||||
if ((ctxId[i] < 'A' || ctxId[i] > 'Z') &&
|
||||
(ctxId[i] < 'a' || ctxId[i] > 'z') &&
|
||||
(ctxId[i] < '0' || ctxId[i] > '9') &&
|
||||
(ctxId[i] != '-') &&
|
||||
(ctxId[i] != '_'))
|
||||
{
|
||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCString ctxString("@mozilla.org/content/canvas-rendering-context;1?id=");
|
||||
ctxString.Append(ctxId);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICanvasRenderingContextInternal> ctx =
|
||||
do_CreateInstance(ctxString.get(), &rv);
|
||||
if (rv == NS_ERROR_OUT_OF_MEMORY) {
|
||||
*aContext = nullptr;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
*aContext = nullptr;
|
||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ctx->SetCanvasElement(this);
|
||||
ctx.forget(aContext);
|
||||
return NS_OK;
|
||||
ret->SetCanvasElement(canvas);
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -720,64 +721,48 @@ HTMLCanvasElement::GetContext(const nsAString& aContextId,
|
||||
nsISupports** aContext)
|
||||
{
|
||||
ErrorResult rv;
|
||||
*aContext =
|
||||
GetContext(nullptr, aContextId, JS::NullHandleValue, rv).take();
|
||||
*aContext = GetContext(nullptr, aContextId, JS::NullHandleValue, rv).take();
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
static bool
|
||||
IsContextIdWebGL(const nsAString& str)
|
||||
{
|
||||
return str.EqualsLiteral("webgl") ||
|
||||
str.EqualsLiteral("experimental-webgl");
|
||||
}
|
||||
|
||||
already_AddRefed<nsISupports>
|
||||
HTMLCanvasElement::GetContext(JSContext* aCx,
|
||||
const nsAString& aContextId,
|
||||
JS::Handle<JS::Value> aContextOptions,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (mCurrentContextId.IsEmpty()) {
|
||||
rv = GetContextHelper(aContextId, getter_AddRefs(mCurrentContext));
|
||||
if (rv.Failed() || !mCurrentContext) {
|
||||
CanvasContextType contextType;
|
||||
if (!GetCanvasContextType(aContextId, &contextType))
|
||||
return nullptr;
|
||||
|
||||
if (!mCurrentContext) {
|
||||
// This canvas doesn't have a context yet.
|
||||
|
||||
nsRefPtr<nsICanvasRenderingContextInternal> context;
|
||||
context = CreateContextForCanvas(contextType, this);
|
||||
if (!context)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Ensure that the context participates in CC. Note that returning a
|
||||
// CC participant from QI doesn't addref.
|
||||
nsXPCOMCycleCollectionParticipant *cp = nullptr;
|
||||
CallQueryInterface(mCurrentContext, &cp);
|
||||
nsXPCOMCycleCollectionParticipant* cp = nullptr;
|
||||
CallQueryInterface(context, &cp);
|
||||
if (!cp) {
|
||||
mCurrentContext = nullptr;
|
||||
rv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mCurrentContext = context.forget();
|
||||
mCurrentContextType = contextType;
|
||||
|
||||
rv = UpdateContext(aCx, aContextOptions);
|
||||
if (rv.Failed()) {
|
||||
rv = NS_OK; // See bug 645792
|
||||
return nullptr;
|
||||
}
|
||||
mCurrentContextId.Assign(aContextId);
|
||||
}
|
||||
|
||||
if (!mCurrentContextId.Equals(aContextId)) {
|
||||
if (IsContextIdWebGL(aContextId) &&
|
||||
IsContextIdWebGL(mCurrentContextId))
|
||||
{
|
||||
// Warn when we get a request for a webgl context with an id that differs
|
||||
// from the id it was created with.
|
||||
nsCString creationId = NS_LossyConvertUTF16toASCII(mCurrentContextId);
|
||||
nsCString requestId = NS_LossyConvertUTF16toASCII(aContextId);
|
||||
JS_ReportWarning(aCx, "WebGL: Retrieving a WebGL context from a canvas "
|
||||
"via a request id ('%s') different from the id used "
|
||||
"to create the context ('%s') is not allowed.",
|
||||
requestId.get(),
|
||||
creationId.get());
|
||||
}
|
||||
|
||||
//XXX eventually allow for more than one active context on a given canvas
|
||||
} else {
|
||||
// We already have a context of some type.
|
||||
if (contextType != mCurrentContextType)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -798,21 +783,27 @@ HTMLCanvasElement::MozGetIPCContext(const nsAString& aContextId,
|
||||
if (!aContextId.EqualsLiteral("2d"))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (mCurrentContextId.IsEmpty()) {
|
||||
nsresult rv = GetContextHelper(aContextId, getter_AddRefs(mCurrentContext));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
CanvasContextType contextType = CanvasContextType::Canvas2D;
|
||||
|
||||
if (!mCurrentContext) {
|
||||
// This canvas doesn't have a context yet.
|
||||
|
||||
nsRefPtr<nsICanvasRenderingContextInternal> context;
|
||||
context = CreateContextForCanvas(contextType, this);
|
||||
if (!context) {
|
||||
*aContext = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mCurrentContext = context;
|
||||
mCurrentContext->SetIsIPC(true);
|
||||
mCurrentContextType = contextType;
|
||||
|
||||
rv = UpdateContext(nullptr, JS::NullHandleValue);
|
||||
nsresult rv = UpdateContext(nullptr, JS::NullHandleValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mCurrentContextId.Assign(aContextId);
|
||||
} else if (!mCurrentContextId.Equals(aContextId)) {
|
||||
//XXX eventually allow for more than one active context on a given canvas
|
||||
} else {
|
||||
// We already have a context of some type.
|
||||
if (contextType != mCurrentContextType)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
@ -831,21 +822,18 @@ HTMLCanvasElement::UpdateContext(JSContext* aCx, JS::Handle<JS::Value> aNewConte
|
||||
nsresult rv = mCurrentContext->SetIsOpaque(HasAttr(kNameSpaceID_None, nsGkAtoms::moz_opaque));
|
||||
if (NS_FAILED(rv)) {
|
||||
mCurrentContext = nullptr;
|
||||
mCurrentContextId.Truncate();
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = mCurrentContext->SetContextOptions(aCx, aNewContextOptions);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCurrentContext = nullptr;
|
||||
mCurrentContextId.Truncate();
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = mCurrentContext->SetDimensions(sz.width, sz.height);
|
||||
if (NS_FAILED(rv)) {
|
||||
mCurrentContext = nullptr;
|
||||
mCurrentContextId.Truncate();
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define mozilla_dom_HTMLCanvasElement_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/TypedEnum.h"
|
||||
#include "nsIDOMHTMLCanvasElement.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@ -35,6 +36,12 @@ class FileCallback;
|
||||
class HTMLCanvasPrintState;
|
||||
class PrintCallback;
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(CanvasContextType, uint8_t)
|
||||
Canvas2D,
|
||||
WebGL1,
|
||||
WebGL2
|
||||
MOZ_END_ENUM_CLASS(CanvasContextType)
|
||||
|
||||
class HTMLCanvasElement MOZ_FINAL : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLCanvasElement
|
||||
{
|
||||
@ -229,11 +236,9 @@ protected:
|
||||
nsresult MozGetAsFileImpl(const nsAString& aName,
|
||||
const nsAString& aType,
|
||||
nsIDOMFile** aResult);
|
||||
nsresult GetContextHelper(const nsAString& aContextId,
|
||||
nsICanvasRenderingContextInternal **aContext);
|
||||
void CallPrintCallback();
|
||||
|
||||
nsString mCurrentContextId;
|
||||
CanvasContextType mCurrentContextType;
|
||||
nsRefPtr<HTMLCanvasElement> mOriginalCanvas;
|
||||
nsRefPtr<PrintCallback> mPrintCallback;
|
||||
nsCOMPtr<nsICanvasRenderingContextInternal> mCurrentContext;
|
||||
|
@ -1129,10 +1129,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
||||
{ "@mozilla.org/content/post-content-iterator;1", &kNS_CONTENTITERATOR_CID },
|
||||
{ "@mozilla.org/content/pre-content-iterator;1", &kNS_PRECONTENTITERATOR_CID },
|
||||
{ "@mozilla.org/content/subtree-content-iterator;1", &kNS_SUBTREEITERATOR_CID },
|
||||
{ "@mozilla.org/content/canvas-rendering-context;1?id=experimental-webgl", &kNS_CANVASRENDERINGCONTEXTWEBGL_CID },
|
||||
#ifdef MOZ_WEBGL_CONFORMANT
|
||||
{ "@mozilla.org/content/canvas-rendering-context;1?id=webgl", &kNS_CANVASRENDERINGCONTEXTWEBGL_CID },
|
||||
#endif
|
||||
{ NS_DOC_ENCODER_CONTRACTID_BASE "text/xml", &kNS_TEXT_ENCODER_CID },
|
||||
{ NS_DOC_ENCODER_CONTRACTID_BASE "application/xml", &kNS_TEXT_ENCODER_CID },
|
||||
{ NS_DOC_ENCODER_CONTRACTID_BASE "application/xhtml+xml", &kNS_TEXT_ENCODER_CID },
|
||||
|
@ -29,7 +29,7 @@ GfxInfoWebGL::GetWebGLParameter(const nsAString& aParam, nsAString& aResult)
|
||||
else return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsIDOMWebGLRenderingContext> webgl =
|
||||
do_CreateInstance("@mozilla.org/content/canvas-rendering-context;1?id=experimental-webgl");
|
||||
do_CreateInstance("@mozilla.org/content/canvas-rendering-context;1?id=webgl");
|
||||
if (!webgl)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user