зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge on a CLOSED TREE
This commit is contained in:
Коммит
5bb0fde6e9
|
@ -76,9 +76,7 @@ pref("extensions.geckoProfiler.getSymbolRules", "localBreakpad,remoteBreakpad,du
|
|||
pref("extensions.webextensions.base-content-security-policy", "script-src 'self' https://* moz-extension: blob: filesystem: 'unsafe-eval' 'unsafe-inline'; object-src 'self' https://* moz-extension: blob: filesystem:;");
|
||||
pref("extensions.webextensions.default-content-security-policy", "script-src 'self'; object-src 'self';");
|
||||
|
||||
#if defined(XP_WIN)
|
||||
pref("extensions.webextensions.remote", true);
|
||||
#elif defined(XP_MACOSX) && !defined(RELEASE_OR_BETA)
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
pref("extensions.webextensions.remote", true);
|
||||
#endif
|
||||
|
||||
|
@ -86,6 +84,7 @@ pref("extensions.webextensions.remote", true);
|
|||
pref("extensions.legacy.exceptions", "{972ce4c6-7e08-4474-a285-3208198ce6fd},testpilot@cliqz.com,@testpilot-containers,jid1-NeEaf3sAHdKHPA@jetpack,@activity-streams,pulse@mozilla.com,@testpilot-addon,@min-vid,tabcentertest1@mozilla.com,snoozetabs@mozilla.com,speaktome@mozilla.com,hoverpad@mozilla.com");
|
||||
|
||||
// Require signed add-ons by default
|
||||
pref("extensions.langpacks.signatures.required", true);
|
||||
pref("xpinstall.signatures.required", true);
|
||||
pref("xpinstall.signatures.devInfoURL", "https://wiki.mozilla.org/Addons/Extension_Signing");
|
||||
|
||||
|
|
|
@ -441,7 +441,7 @@
|
|||
<hbox align="center">
|
||||
<vbox flex="1">
|
||||
<description id="updateAppInfo">
|
||||
<html:a id="releasenotes" data-l10n-name="learn-more" class="learnMore text-link" hidden="true"/>
|
||||
<html:a id="releasenotes" target="_blank" data-l10n-name="learn-more" class="learnMore text-link" hidden="true"/>
|
||||
</description>
|
||||
<description id="distribution" class="text-blurb" hidden="true"/>
|
||||
<description id="distributionId" class="text-blurb" hidden="true"/>
|
||||
|
|
|
@ -9,6 +9,7 @@ var EXPORTED_SYMBOLS = [ "TranslationDocument" ];
|
|||
const TEXT_NODE = Ci.nsIDOMNode.TEXT_NODE;
|
||||
|
||||
ChromeUtils.import("resource://services-common/async.js");
|
||||
Cu.importGlobalProperties(["DOMParser"]);
|
||||
|
||||
/**
|
||||
* This class represents a document that is being translated,
|
||||
|
@ -301,8 +302,7 @@ TranslationItem.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
let domParser = Cc["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Ci.nsIDOMParser);
|
||||
let domParser = new DOMParser();
|
||||
|
||||
let doc = domParser.parseFromString(result, "text/html");
|
||||
parseResultNode(this, doc.body.firstChild);
|
||||
|
|
|
@ -8,6 +8,7 @@ const CC = Components.Constructor;
|
|||
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
|
||||
"nsIBinaryInputStream",
|
||||
"setInputStream");
|
||||
Cu.importGlobalProperties(["DOMParser"]);
|
||||
|
||||
function handleRequest(req, res) {
|
||||
try {
|
||||
|
@ -98,9 +99,8 @@ function sha1(str) {
|
|||
}
|
||||
|
||||
function parseXml(body) {
|
||||
let DOMParser = Cc["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Ci.nsIDOMParser);
|
||||
let xml = DOMParser.parseFromString(body, "text/xml");
|
||||
let parser = new DOMParser();
|
||||
let xml = parser.parseFromString(body, "text/xml");
|
||||
if (xml.documentElement.localName == "parsererror")
|
||||
throw new Error("Invalid XML");
|
||||
return xml;
|
||||
|
|
|
@ -31,6 +31,7 @@ var { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {}
|
|||
|
||||
var { gDevTools } = require("devtools/client/framework/devtools");
|
||||
var Services = require("Services");
|
||||
var { globals } = require("devtools/shared/builtin-modules");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["AppCacheUtils"];
|
||||
|
||||
|
@ -617,5 +618,5 @@ XPCOMUtils.defineLazyGetter(this, "appcacheservice", function() {
|
|||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_DOMParser", function() {
|
||||
return Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
|
||||
return globals.DOMParser();
|
||||
});
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
|
||||
// Test that VariablesView._doSearch() works even without an attached
|
||||
// VariablesViewController (bug 1196341).
|
||||
|
||||
const DOMParser = Cc["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Ci.nsIDOMParser);
|
||||
const { VariablesView } =
|
||||
ChromeUtils.import("resource://devtools/client/shared/widgets/VariablesView.jsm", {});
|
||||
const { require } =
|
||||
ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
||||
const { globals } = require("devtools/shared/builtin-modules");
|
||||
|
||||
const DOMParser = new globals.DOMParser();
|
||||
|
||||
function run_test() {
|
||||
let doc = DOMParser.parseFromString("<div>", "text/html");
|
||||
|
|
|
@ -34,9 +34,6 @@ loader.lazyRequireGetter(this, "WalkerSearch", "devtools/server/actors/utils/wal
|
|||
loader.lazyServiceGetter(this, "eventListenerService",
|
||||
"@mozilla.org/eventlistenerservice;1", "nsIEventListenerService");
|
||||
|
||||
loader.lazyServiceGetter(this, "DOMParser",
|
||||
"@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
|
||||
|
||||
// Minimum delay between two "new-mutations" events.
|
||||
const MUTATIONS_THROTTLING_DELAY = 100;
|
||||
// List of mutation types that should -not- be throttled.
|
||||
|
@ -1259,7 +1256,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
|
|||
return;
|
||||
}
|
||||
|
||||
let parsedDOM = DOMParser.parseFromString(value, "text/html");
|
||||
let parsedDOM = new DOMParser().parseFromString(value, "text/html");
|
||||
let rawNode = node.rawNode;
|
||||
let parentNode = rawNode.parentNode;
|
||||
|
||||
|
|
|
@ -20,12 +20,14 @@ function run_test() {
|
|||
|
||||
let g2 = testGlobal("test2");
|
||||
g2.g = g;
|
||||
g2.eval("(" + function createBadEvent() {
|
||||
let parser = Cc["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Ci.nsIDOMParser);
|
||||
// Not using the "stringify a function" trick because that runs afoul of the
|
||||
// Cu.importGlobalProperties lint and we don't need it here anyway.
|
||||
g2.eval(`(function createBadEvent() {
|
||||
Cu.importGlobalProperties(["DOMParser"]);
|
||||
let parser = new DOMParser();
|
||||
let doc = parser.parseFromString("<foo></foo>", "text/xml");
|
||||
g.stopMe(doc.createEvent("MouseEvent"));
|
||||
} + ")()");
|
||||
} )()`);
|
||||
|
||||
dbg.enabled = false;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ const {
|
|||
ChromeUtils,
|
||||
CSS,
|
||||
CSSRule,
|
||||
DOMParser,
|
||||
Event,
|
||||
FileReader,
|
||||
FormData,
|
||||
|
@ -48,6 +49,7 @@ const {
|
|||
"ChromeUtils",
|
||||
"CSS",
|
||||
"CSSRule",
|
||||
"DOMParser",
|
||||
"Event",
|
||||
"FileReader",
|
||||
"FormData",
|
||||
|
@ -264,6 +266,7 @@ exports.globals = {
|
|||
define(factory) {
|
||||
factory(this.require, this.exports, this.module);
|
||||
},
|
||||
DOMParser,
|
||||
Element: Ci.nsIDOMElement,
|
||||
Event,
|
||||
FormData,
|
||||
|
@ -315,9 +318,6 @@ lazyGlobal("clearInterval", () => {
|
|||
lazyGlobal("setInterval", () => {
|
||||
return require("resource://gre/modules/Timer.jsm").setInterval;
|
||||
});
|
||||
lazyGlobal("DOMParser", () => {
|
||||
return CC("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
|
||||
});
|
||||
lazyGlobal("WebSocket", () => {
|
||||
return Services.appShell.hiddenDOMWindow.WebSocket;
|
||||
});
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIAttribute.h"
|
||||
#include "nsIContent.h" // For NS_IMPL_FROMNODE_HELPER, though looks like it
|
||||
// should live in nsINode.h?
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsString.h"
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsDOMString.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsIScriptError.h"
|
||||
|
@ -26,10 +28,16 @@
|
|||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
DOMParser::DOMParser()
|
||||
: mAttemptedInit(false)
|
||||
, mOriginalPrincipalWasSystem(false)
|
||||
DOMParser::DOMParser(nsIGlobalObject* aOwner, nsIPrincipal* aDocPrincipal,
|
||||
nsIURI* aDocumentURI, nsIURI* aBaseURI)
|
||||
: mOwner(aOwner)
|
||||
, mPrincipal(aDocPrincipal)
|
||||
, mDocumentURI(aDocumentURI)
|
||||
, mBaseURI(aBaseURI)
|
||||
, mForceEnableXULXBL(false)
|
||||
{
|
||||
MOZ_ASSERT(aDocPrincipal);
|
||||
MOZ_ASSERT(aDocumentURI);
|
||||
}
|
||||
|
||||
DOMParser::~DOMParser()
|
||||
|
@ -39,9 +47,7 @@ DOMParser::~DOMParser()
|
|||
// QueryInterface implementation for DOMParser
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMParser)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMParser)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMParser)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMParser, mOwner)
|
||||
|
@ -57,124 +63,72 @@ StringFromSupportedType(SupportedType aType)
|
|||
|
||||
already_AddRefed<nsIDocument>
|
||||
DOMParser::ParseFromString(const nsAString& aStr, SupportedType aType,
|
||||
ErrorResult& rv)
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
rv = ParseFromString(aStr,
|
||||
StringFromSupportedType(aType),
|
||||
getter_AddRefs(domDocument));
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
|
||||
return document.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMParser::ParseFromString(const char16_t *str,
|
||||
const char *contentType,
|
||||
nsIDOMDocument **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(str);
|
||||
// Converting a string to an enum value manually is a bit of a pain,
|
||||
// so let's just use a helper that takes a content-type string.
|
||||
return ParseFromString(nsDependentString(str), contentType, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
DOMParser::ParseFromString(const nsAString& str,
|
||||
const char *contentType,
|
||||
nsIDOMDocument **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (!nsCRT::strcmp(contentType, "text/html")) {
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
rv = SetUpDocument(DocumentFlavorHTML, getter_AddRefs(domDocument));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
|
||||
if (aType == SupportedType::Text_html) {
|
||||
nsCOMPtr<nsIDocument> document = SetUpDocument(DocumentFlavorHTML, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Keep the XULXBL state in sync with the XML case.
|
||||
|
||||
if (mOriginalPrincipalWasSystem) {
|
||||
if (mForceEnableXULXBL) {
|
||||
document->ForceEnableXULXBL();
|
||||
}
|
||||
|
||||
rv = nsContentUtils::ParseDocumentHTML(str, document, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv = nsContentUtils::ParseDocumentHTML(aStr, document, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
domDocument.forget(aResult);
|
||||
return rv;
|
||||
return document.forget();
|
||||
}
|
||||
|
||||
nsAutoCString utf8str;
|
||||
// Convert from UTF16 to UTF8 using fallible allocations
|
||||
if (!AppendUTF16toUTF8(str, utf8str, mozilla::fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// The new stream holds a reference to the buffer
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
rv = NS_NewByteInputStream(getter_AddRefs(stream),
|
||||
utf8str.get(), utf8str.Length(),
|
||||
NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return ParseFromStream(stream, "UTF-8", utf8str.Length(), contentType, aResult);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
DOMParser::ParseFromBuffer(const Sequence<uint8_t>& aBuf, uint32_t aBufLen,
|
||||
SupportedType aType, ErrorResult& rv)
|
||||
{
|
||||
if (aBufLen > aBuf.Length()) {
|
||||
rv.Throw(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY);
|
||||
if (!AppendUTF16toUTF8(aStr, utf8str, mozilla::fallible)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
rv = DOMParser::ParseFromBuffer(aBuf.Elements(), aBufLen,
|
||||
StringFromSupportedType(aType),
|
||||
getter_AddRefs(domDocument));
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
|
||||
return document.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
DOMParser::ParseFromBuffer(const Uint8Array& aBuf, uint32_t aBufLen,
|
||||
SupportedType aType, ErrorResult& rv)
|
||||
{
|
||||
aBuf.ComputeLengthAndData();
|
||||
|
||||
if (aBufLen > aBuf.Length()) {
|
||||
rv.Throw(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY);
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
rv = DOMParser::ParseFromBuffer(aBuf.Data(), aBufLen,
|
||||
StringFromSupportedType(aType),
|
||||
getter_AddRefs(domDocument));
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
|
||||
return document.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMParser::ParseFromBuffer(const uint8_t *buf,
|
||||
uint32_t bufLen,
|
||||
const char *contentType,
|
||||
nsIDOMDocument **aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(buf);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
// The new stream holds a reference to the buffer
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
|
||||
reinterpret_cast<const char *>(buf),
|
||||
bufLen, NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
utf8str.get(), utf8str.Length(),
|
||||
NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ParseFromStream(stream, nullptr, bufLen, contentType, aResult);
|
||||
return ParseFromStream(stream, NS_LITERAL_STRING("UTF-8"),
|
||||
utf8str.Length(), aType, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
DOMParser::ParseFromBuffer(const Uint8Array& aBuf, SupportedType aType,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aBuf.ComputeLengthAndData();
|
||||
return ParseFromBuffer(MakeSpan(aBuf.Data(), aBuf.Length()), aType, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
DOMParser::ParseFromBuffer(Span<const uint8_t> aBuf, SupportedType aType,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// The new stream holds a reference to the buffer
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
|
||||
reinterpret_cast<const char *>(aBuf.Elements()),
|
||||
aBuf.Length(), NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ParseFromStream(stream, VoidString(), aBuf.Length(), aType, aRv);
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,58 +137,40 @@ DOMParser::ParseFromStream(nsIInputStream* aStream,
|
|||
const nsAString& aCharset,
|
||||
int32_t aContentLength,
|
||||
SupportedType aType,
|
||||
ErrorResult& rv)
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
rv = DOMParser::ParseFromStream(aStream,
|
||||
NS_ConvertUTF16toUTF8(aCharset).get(),
|
||||
aContentLength,
|
||||
StringFromSupportedType(aType),
|
||||
getter_AddRefs(domDocument));
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
|
||||
return document.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMParser::ParseFromStream(nsIInputStream* aStream,
|
||||
const char* aCharset,
|
||||
int32_t aContentLength,
|
||||
const char* aContentType,
|
||||
nsIDOMDocument** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG(aStream);
|
||||
NS_ENSURE_ARG(aContentType);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = nullptr;
|
||||
|
||||
bool svg = nsCRT::strcmp(aContentType, "image/svg+xml") == 0;
|
||||
bool svg = (aType == SupportedType::Image_svg_xml);
|
||||
|
||||
// For now, we can only create XML documents.
|
||||
//XXXsmaug Should we create an HTMLDocument (in XHTML mode)
|
||||
// for "application/xhtml+xml"?
|
||||
if ((nsCRT::strcmp(aContentType, "text/xml") != 0) &&
|
||||
(nsCRT::strcmp(aContentType, "application/xml") != 0) &&
|
||||
(nsCRT::strcmp(aContentType, "application/xhtml+xml") != 0) &&
|
||||
!svg)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
nsresult rv;
|
||||
if (aType != SupportedType::Text_xml &&
|
||||
aType != SupportedType::Application_xml &&
|
||||
aType != SupportedType::Application_xhtml_xml &&
|
||||
!svg) {
|
||||
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Put the nsCOMPtr out here so we hold a ref to the stream as needed
|
||||
nsCOMPtr<nsIInputStream> stream = aStream;
|
||||
if (!NS_InputStreamIsBuffered(stream)) {
|
||||
nsCOMPtr<nsIInputStream> bufferedStream;
|
||||
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
|
||||
nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
|
||||
stream.forget(), 4096);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
stream = bufferedStream;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
rv = SetUpDocument(svg ? DocumentFlavorSVG : DocumentFlavorLegacyGuess,
|
||||
getter_AddRefs(domDocument));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIDocument> document =
|
||||
SetUpDocument(svg ? DocumentFlavorSVG : DocumentFlavorLegacyGuess, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create a fake channel
|
||||
nsCOMPtr<nsIChannel> parserChannel;
|
||||
|
@ -244,35 +180,35 @@ DOMParser::ParseFromStream(nsIInputStream* aStream,
|
|||
mPrincipal,
|
||||
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
|
||||
nsIContentPolicy::TYPE_OTHER,
|
||||
nsDependentCString(aContentType));
|
||||
NS_ENSURE_STATE(parserChannel);
|
||||
nsDependentCString(StringFromSupportedType(aType)));
|
||||
if (NS_WARN_IF(!parserChannel)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (aCharset) {
|
||||
parserChannel->SetContentCharset(nsDependentCString(aCharset));
|
||||
if (!DOMStringIsNull(aCharset)) {
|
||||
parserChannel->SetContentCharset(NS_ConvertUTF16toUTF8(aCharset));
|
||||
}
|
||||
|
||||
// Tell the document to start loading
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
|
||||
// Have to pass false for reset here, else the reset will remove
|
||||
// our event listener. Should that listener addition move to later
|
||||
// than this call?
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
|
||||
if (!document) return NS_ERROR_FAILURE;
|
||||
|
||||
// Keep the XULXBL state in sync with the HTML case
|
||||
|
||||
if (mOriginalPrincipalWasSystem) {
|
||||
if (mForceEnableXULXBL) {
|
||||
document->ForceEnableXULXBL();
|
||||
}
|
||||
|
||||
rv = document->StartDocumentLoad(kLoadAsData, parserChannel,
|
||||
nullptr, nullptr,
|
||||
getter_AddRefs(listener),
|
||||
false);
|
||||
// Have to pass false for reset here, else the reset will remove
|
||||
// our event listener. Should that listener addition move to later
|
||||
// than this call?
|
||||
nsresult rv = document->StartDocumentLoad(kLoadAsData, parserChannel,
|
||||
nullptr, nullptr,
|
||||
getter_AddRefs(listener),
|
||||
false);
|
||||
|
||||
if (NS_FAILED(rv) || !listener) {
|
||||
return NS_ERROR_FAILURE;
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Now start pumping data to the listener
|
||||
|
@ -296,180 +232,92 @@ DOMParser::ParseFromStream(nsIInputStream* aStream,
|
|||
// the channel, so we do not need to call Cancel(rv) as we do above.
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
domDocument.swap(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI,
|
||||
nsIURI* baseURI, nsIGlobalObject* aScriptObject)
|
||||
{
|
||||
NS_ENSURE_STATE(!mAttemptedInit);
|
||||
mAttemptedInit = true;
|
||||
NS_ENSURE_ARG(principal || documentURI);
|
||||
mDocumentURI = documentURI;
|
||||
|
||||
if (!mDocumentURI) {
|
||||
principal->GetURI(getter_AddRefs(mDocumentURI));
|
||||
// If we have the system principal, then we'll just use the null principals
|
||||
// uri.
|
||||
if (!mDocumentURI && !nsContentUtils::IsSystemPrincipal(principal)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
mScriptHandlingObject = do_GetWeakReference(aScriptObject);
|
||||
mPrincipal = principal;
|
||||
nsresult rv;
|
||||
if (!mPrincipal) {
|
||||
// BUG 1237080 -- in this case we're getting a chrome privilege scripted
|
||||
// DOMParser object creation without an explicit principal set. This is
|
||||
// now deprecated.
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
|
||||
NS_LITERAL_CSTRING("DOM"),
|
||||
nullptr,
|
||||
nsContentUtils::eDOM_PROPERTIES,
|
||||
"ChromeScriptedDOMParserWithoutPrincipal",
|
||||
nullptr,
|
||||
0,
|
||||
documentURI);
|
||||
|
||||
OriginAttributes attrs;
|
||||
mPrincipal = BasePrincipal::CreateCodebasePrincipal(mDocumentURI, attrs);
|
||||
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_FAILURE);
|
||||
} else {
|
||||
if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
|
||||
// Don't give DOMParsers the system principal. Use a null
|
||||
// principal instead.
|
||||
mOriginalPrincipalWasSystem = true;
|
||||
mPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
|
||||
|
||||
if (!mDocumentURI) {
|
||||
rv = mPrincipal->GetURI(getter_AddRefs(mDocumentURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mBaseURI = baseURI;
|
||||
|
||||
MOZ_ASSERT(mPrincipal, "Must have principal");
|
||||
MOZ_ASSERT(mDocumentURI, "Must have document URI");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*static */already_AddRefed<DOMParser>
|
||||
DOMParser::Constructor(const GlobalObject& aOwner,
|
||||
nsIPrincipal* aPrincipal, nsIURI* aDocumentURI,
|
||||
nsIURI* aBaseURI, ErrorResult& rv)
|
||||
{
|
||||
if (aOwner.CallerType() != CallerType::System) {
|
||||
rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<DOMParser> domParser = new DOMParser(aOwner.GetAsSupports());
|
||||
rv = domParser->InitInternal(aOwner.GetAsSupports(), aPrincipal, aDocumentURI,
|
||||
aBaseURI);
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
return domParser.forget();
|
||||
|
||||
return document.forget();
|
||||
}
|
||||
|
||||
/*static */already_AddRefed<DOMParser>
|
||||
DOMParser::Constructor(const GlobalObject& aOwner,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
RefPtr<DOMParser> domParser = new DOMParser(aOwner.GetAsSupports());
|
||||
rv = domParser->InitInternal(aOwner.GetAsSupports(),
|
||||
nsContentUtils::SubjectPrincipal(),
|
||||
nullptr, nullptr);
|
||||
if (rv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
return domParser.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
DOMParser::InitInternal(nsISupports* aOwner, nsIPrincipal* prin,
|
||||
nsIURI* documentURI, nsIURI* baseURI)
|
||||
{
|
||||
AttemptedInitMarker marker(&mAttemptedInit);
|
||||
if (!documentURI) {
|
||||
// No explicit documentURI; grab document and base URIs off the window our
|
||||
// constructor was called on. Error out if anything untoward happens.
|
||||
|
||||
// Note that this is a behavior change as far as I can tell -- we're now
|
||||
// using the base URI and document URI of the window off of which the
|
||||
// DOMParser is created, not the window in which parse*() is called.
|
||||
// Does that matter?
|
||||
|
||||
// Also note that |cx| matches what GetDocumentFromContext() would return,
|
||||
// while GetDocumentFromCaller() gives us the window that the DOMParser()
|
||||
// call was made on.
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aOwner);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsCOMPtr<nsIPrincipal> docPrincipal = aOwner.GetSubjectPrincipal();
|
||||
nsCOMPtr<nsIURI> documentURI;
|
||||
nsIURI* baseURI = nullptr;
|
||||
if (nsContentUtils::IsSystemPrincipal(docPrincipal)) {
|
||||
docPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
|
||||
docPrincipal->GetURI(getter_AddRefs(documentURI));
|
||||
} else {
|
||||
// Grab document and base URIs off the window our constructor was
|
||||
// called on. Error out if anything untoward happens.
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aOwner.GetAsSupports());
|
||||
if (!window) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
baseURI = window->GetDocBaseURI();
|
||||
documentURI = window->GetDocumentURI();
|
||||
if (!documentURI) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> scriptglobal = do_QueryInterface(aOwner);
|
||||
return Init(prin, documentURI, baseURI, scriptglobal);
|
||||
}
|
||||
|
||||
void
|
||||
DOMParser::Init(nsIPrincipal* aPrincipal, nsIURI* aDocumentURI,
|
||||
nsIURI* aBaseURI, mozilla::ErrorResult& rv)
|
||||
{
|
||||
AttemptedInitMarker marker(&mAttemptedInit);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = aPrincipal;
|
||||
if (!principal && !aDocumentURI) {
|
||||
principal = nsContentUtils::SubjectPrincipal();
|
||||
if (!documentURI) {
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = Init(principal, aDocumentURI, aBaseURI, GetEntryGlobal());
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aOwner.GetAsSupports());
|
||||
MOZ_ASSERT(global);
|
||||
RefPtr<DOMParser> domParser = new DOMParser(global, docPrincipal,
|
||||
documentURI, baseURI);
|
||||
return domParser.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
DOMParser::SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult)
|
||||
// static
|
||||
already_AddRefed<DOMParser>
|
||||
DOMParser::CreateWithoutGlobal(ErrorResult& aRv)
|
||||
{
|
||||
// We should really QI to nsIGlobalObject here, but nsDocument gets confused
|
||||
nsCOMPtr<nsIPrincipal> docPrincipal =
|
||||
NullPrincipal::CreateWithoutOriginAttributes();
|
||||
nsCOMPtr<nsIURI> documentURI;
|
||||
docPrincipal->GetURI(getter_AddRefs(documentURI));
|
||||
|
||||
if (!documentURI) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DOMParser> domParser = new DOMParser(nullptr, docPrincipal,
|
||||
documentURI, nullptr);
|
||||
return domParser.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
DOMParser::SetUpDocument(DocumentFlavor aFlavor, ErrorResult& aRv)
|
||||
{
|
||||
// We should really just use mOwner here, but nsDocument gets confused
|
||||
// if we pass it a scriptHandlingObject that doesn't QI to
|
||||
// nsIScriptGlobalObject, and test_isequalnode.js (an xpcshell test without
|
||||
// a window global) breaks. The correct solution is just to wean nsDocument
|
||||
// off of nsIScriptGlobalObject, but that's a yak to shave another day.
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
|
||||
do_QueryReferent(mScriptHandlingObject);
|
||||
nsresult rv;
|
||||
if (!mPrincipal) {
|
||||
NS_ENSURE_TRUE(!mAttemptedInit, NS_ERROR_NOT_INITIALIZED);
|
||||
AttemptedInitMarker marker(&mAttemptedInit);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> prin = NullPrincipal::CreateWithoutOriginAttributes();
|
||||
rv = Init(prin, nullptr, nullptr, scriptHandlingObject);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
do_QueryInterface(mOwner);
|
||||
|
||||
// Try to inherit a style backend.
|
||||
NS_ASSERTION(mPrincipal, "Must have principal by now");
|
||||
NS_ASSERTION(mDocumentURI, "Must have document URI by now");
|
||||
|
||||
return NS_NewDOMDocument(aResult, EmptyString(), EmptyString(), nullptr,
|
||||
mDocumentURI, mBaseURI,
|
||||
mPrincipal,
|
||||
true,
|
||||
scriptHandlingObject,
|
||||
aFlavor);
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
nsresult rv = NS_NewDOMDocument(getter_AddRefs(domDoc), EmptyString(), EmptyString(),
|
||||
nullptr, mDocumentURI, mBaseURI, mPrincipal,
|
||||
true, scriptHandlingObject, aFlavor);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
return doc.forget();
|
||||
}
|
||||
|
|
|
@ -9,20 +9,19 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMParser.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/Span.h"
|
||||
#include "mozilla/dom/DOMParserBinding.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
|
||||
class nsIDocument;
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class DOMParser final : public nsIDOMParser,
|
||||
public nsSupportsWeakReference,
|
||||
class DOMParser final : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
typedef mozilla::dom::GlobalObject GlobalObject;
|
||||
|
@ -30,48 +29,39 @@ class DOMParser final : public nsIDOMParser,
|
|||
virtual ~DOMParser();
|
||||
|
||||
public:
|
||||
DOMParser();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(DOMParser,
|
||||
nsIDOMParser)
|
||||
|
||||
// nsIDOMParser
|
||||
NS_DECL_NSIDOMPARSER
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMParser)
|
||||
|
||||
// WebIDL API
|
||||
static already_AddRefed<DOMParser>
|
||||
Constructor(const GlobalObject& aOwner,
|
||||
mozilla::ErrorResult& rv);
|
||||
|
||||
static already_AddRefed<DOMParser>
|
||||
Constructor(const GlobalObject& aOwner,
|
||||
nsIPrincipal* aPrincipal, nsIURI* aDocumentURI, nsIURI* aBaseURI,
|
||||
mozilla::ErrorResult& rv);
|
||||
already_AddRefed<nsIDocument>
|
||||
ParseFromString(const nsAString& aStr, SupportedType aType, ErrorResult& aRv);
|
||||
|
||||
// Sequence converts to Span, so we can use this overload for both
|
||||
// the Sequence case and our internal uses.
|
||||
already_AddRefed<nsIDocument>
|
||||
ParseFromBuffer(Span<const uint8_t> aBuf, SupportedType aType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
ParseFromString(const nsAString& aStr, mozilla::dom::SupportedType aType,
|
||||
mozilla::ErrorResult& rv);
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
ParseFromBuffer(const mozilla::dom::Sequence<uint8_t>& aBuf,
|
||||
uint32_t aBufLen, mozilla::dom::SupportedType aType,
|
||||
mozilla::ErrorResult& rv);
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
ParseFromBuffer(const mozilla::dom::Uint8Array& aBuf, uint32_t aBufLen,
|
||||
mozilla::dom::SupportedType aType,
|
||||
mozilla::ErrorResult& rv);
|
||||
ParseFromBuffer(const Uint8Array& aBuf, SupportedType aType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<nsIDocument>
|
||||
ParseFromStream(nsIInputStream* aStream, const nsAString& aCharset,
|
||||
int32_t aContentLength, mozilla::dom::SupportedType aType,
|
||||
mozilla::ErrorResult& rv);
|
||||
int32_t aContentLength, SupportedType aType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Init(nsIPrincipal* aPrincipal, nsIURI* aDocumentURI,
|
||||
nsIURI* aBaseURI, mozilla::ErrorResult& rv);
|
||||
void
|
||||
ForceEnableXULXBL()
|
||||
{
|
||||
mForceEnableXULXBL = true;
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
nsIGlobalObject* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
@ -81,46 +71,22 @@ public:
|
|||
return mozilla::dom::DOMParserBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
// A way to create a non-global-associated DOMParser from C++.
|
||||
static already_AddRefed<DOMParser> CreateWithoutGlobal(ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
explicit DOMParser(nsISupports* aOwner)
|
||||
: mOwner(aOwner)
|
||||
, mAttemptedInit(false)
|
||||
, mOriginalPrincipalWasSystem(false)
|
||||
{
|
||||
MOZ_ASSERT(aOwner);
|
||||
}
|
||||
DOMParser(nsIGlobalObject* aOwner, nsIPrincipal* aDocPrincipal,
|
||||
nsIURI* aDocumentURI, nsIURI* aBaseURI);
|
||||
|
||||
nsresult InitInternal(nsISupports* aOwner, nsIPrincipal* prin,
|
||||
nsIURI* documentURI, nsIURI* baseURI);
|
||||
already_AddRefed<nsIDocument> SetUpDocument(DocumentFlavor aFlavor,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsresult SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult);
|
||||
|
||||
// Helper for ParseFromString
|
||||
nsresult ParseFromString(const nsAString& str, const char *contentType,
|
||||
nsIDOMDocument **aResult);
|
||||
|
||||
class AttemptedInitMarker {
|
||||
public:
|
||||
explicit AttemptedInitMarker(bool* aAttemptedInit) :
|
||||
mAttemptedInit(aAttemptedInit)
|
||||
{}
|
||||
|
||||
~AttemptedInitMarker() {
|
||||
*mAttemptedInit = true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool* mAttemptedInit;
|
||||
};
|
||||
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsIGlobalObject> mOwner;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
nsWeakPtr mScriptHandlingObject;
|
||||
|
||||
bool mAttemptedInit;
|
||||
bool mOriginalPrincipalWasSystem;
|
||||
bool mForceEnableXULXBL;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -16,7 +16,6 @@ XPIDL_SOURCES += [
|
|||
'mozIDOMWindow.idl',
|
||||
'nsIContentPolicy.idl',
|
||||
'nsIDocumentEncoder.idl',
|
||||
'nsIDOMParser.idl',
|
||||
'nsIDOMRequestService.idl',
|
||||
'nsIDroppedLinkHandler.idl',
|
||||
'nsIFrameLoaderOwner.idl',
|
||||
|
|
|
@ -945,41 +945,4 @@ inline const nsIContent* nsINode::AsContent() const
|
|||
return const_cast<nsINode*>(this)->AsContent();
|
||||
}
|
||||
|
||||
// Some checks are faster to do on nsIContent or Element than on
|
||||
// nsINode, so spit out FromNode versions taking those types too.
|
||||
#define NS_IMPL_FROMNODE_HELPER(_class, _check) \
|
||||
template<typename ArgType> \
|
||||
static _class* FromNode(ArgType&& aNode) \
|
||||
{ \
|
||||
/* We need the double-cast in case aNode is a smartptr. Those */ \
|
||||
/* can cast to superclasses of the type they're templated on, */ \
|
||||
/* but not directly to subclasses. */ \
|
||||
return aNode->_check ? \
|
||||
static_cast<_class*>(static_cast<nsINode*>(aNode)) : nullptr; \
|
||||
} \
|
||||
template<typename ArgType> \
|
||||
static _class* FromNodeOrNull(ArgType&& aNode) \
|
||||
{ \
|
||||
return aNode ? FromNode(aNode) : nullptr; \
|
||||
} \
|
||||
template<typename ArgType> \
|
||||
static const _class* FromNode(const ArgType* aNode) \
|
||||
{ \
|
||||
return aNode->_check ? static_cast<const _class*>(aNode) : nullptr; \
|
||||
} \
|
||||
template<typename ArgType> \
|
||||
static const _class* FromNodeOrNull(const ArgType* aNode) \
|
||||
{ \
|
||||
return aNode ? FromNode(aNode) : nullptr; \
|
||||
}
|
||||
|
||||
#define NS_IMPL_FROMNODE(_class, _nsid) \
|
||||
NS_IMPL_FROMNODE_HELPER(_class, IsInNamespace(_nsid))
|
||||
|
||||
#define NS_IMPL_FROMNODE_WITH_TAG(_class, _nsid, _tag) \
|
||||
NS_IMPL_FROMNODE_HELPER(_class, NodeInfo()->Equals(nsGkAtoms::_tag, _nsid))
|
||||
|
||||
#define NS_IMPL_FROMNODE_HTML_WITH_TAG(_class, _tag) \
|
||||
NS_IMPL_FROMNODE_WITH_TAG(_class, kNameSpaceID_XHTML, _tag)
|
||||
|
||||
#endif /* nsIContent_h___ */
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIInputStream;
|
||||
interface nsIDOMDocument;
|
||||
interface nsIURI;
|
||||
interface nsIPrincipal;
|
||||
interface nsIGlobalObject;
|
||||
|
||||
/**
|
||||
* The nsIDOMParser interface is a non-SAX interface that can be used
|
||||
* to parse a string or byte stream containing XML or HTML content
|
||||
* to a DOM document. Parsing is always synchronous - a document is always
|
||||
* returned from the parsing methods. This is as opposed to loading and
|
||||
* parsing with the XMLHttpRequest interface, which can be used for
|
||||
* asynchronous (callback-based) loading.
|
||||
*/
|
||||
[shim(DOMParser), uuid(70b9600e-8622-4c93-9ad8-22c28058dc44)]
|
||||
interface nsIDOMParser : nsISupports
|
||||
{
|
||||
/**
|
||||
* The string passed in is parsed into a DOM document.
|
||||
*
|
||||
* @param str The UTF16 string to be parsed
|
||||
* @param contentType The content type of the string (see parseFromStream)
|
||||
* @returns The DOM document created as a result of parsing the
|
||||
* string
|
||||
*/
|
||||
nsIDOMDocument parseFromString(in wstring str, in string contentType);
|
||||
|
||||
/**
|
||||
* The buffer is parsed into a DOM document.
|
||||
* The charset is determined from the xml entity decl.
|
||||
*
|
||||
* @param buf The octet array data to be parsed
|
||||
* @param bufLen Length (in bytes) of the data
|
||||
* @param contentType The content type of the data (see parseFromStream)
|
||||
* @returns The DOM document created as a result of parsing the
|
||||
* string
|
||||
*/
|
||||
nsIDOMDocument parseFromBuffer([const,array,size_is(bufLen)] in octet buf,
|
||||
in uint32_t bufLen, in string contentType);
|
||||
|
||||
/**
|
||||
* The byte stream passed in is parsed into a DOM document.
|
||||
*
|
||||
* Not accessible from web content.
|
||||
*
|
||||
* @param stream The byte stream whose contents are parsed
|
||||
* @param charset The character set that was used to encode the byte
|
||||
* stream. NULL if not specified.
|
||||
* @param contentLength The number of bytes in the input stream.
|
||||
* @param contentType The content type of the string - either text/xml,
|
||||
* application/xml, or application/xhtml+xml.
|
||||
* Must not be NULL.
|
||||
* @returns The DOM document created as a result of parsing the
|
||||
* stream
|
||||
*/
|
||||
nsIDOMDocument parseFromStream(in nsIInputStream stream,
|
||||
in string charset,
|
||||
in long contentLength,
|
||||
in string contentType);
|
||||
|
||||
/**
|
||||
* Initialize the principal and document and base URIs that the parser should
|
||||
* use for documents it creates. If this is not called, then a null
|
||||
* principal and its URI will be used. When creating a DOMParser via the JS
|
||||
* constructor, this will be called automatically. This method may only be
|
||||
* called once. If this method fails, all following parse attempts will
|
||||
* fail.
|
||||
*
|
||||
* @param principal The principal to use for documents we create.
|
||||
* If this is null, a codebase principal will be created
|
||||
* based on documentURI; in that case the documentURI must
|
||||
* be non-null.
|
||||
* @param documentURI The documentURI to use for the documents we create.
|
||||
* If null, the principal's URI will be used;
|
||||
* in that case, the principal must be non-null and its
|
||||
* URI must be non-null.
|
||||
* @param baseURI The baseURI to use for the documents we create.
|
||||
* If null, the documentURI will be used.
|
||||
* @param scriptObject The object from which the context for event handling
|
||||
* can be got.
|
||||
*/
|
||||
[noscript] void init(in nsIPrincipal principal,
|
||||
in nsIURI documentURI,
|
||||
in nsIURI baseURI,
|
||||
in nsIGlobalObject scriptObject);
|
||||
};
|
||||
|
||||
%{ C++
|
||||
#define NS_DOMPARSER_CID \
|
||||
{ /* 3a8a3a50-512c-11d4-9a54-000064657374 */ \
|
||||
0x3a8a3a50, 0x512c, 0x11d4, \
|
||||
{0x9a, 0x54, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74} }
|
||||
#define NS_DOMPARSER_CONTRACTID \
|
||||
"@mozilla.org/xmlextras/domparser;1"
|
||||
%}
|
|
@ -2148,4 +2148,41 @@ ToCanonicalSupports(nsINode* aPointer)
|
|||
return aPointer;
|
||||
}
|
||||
|
||||
// Some checks are faster to do on nsIContent or Element than on
|
||||
// nsINode, so spit out FromNode versions taking those types too.
|
||||
#define NS_IMPL_FROMNODE_HELPER(_class, _check) \
|
||||
template<typename ArgType> \
|
||||
static _class* FromNode(ArgType&& aNode) \
|
||||
{ \
|
||||
/* We need the double-cast in case aNode is a smartptr. Those */ \
|
||||
/* can cast to superclasses of the type they're templated on, */ \
|
||||
/* but not directly to subclasses. */ \
|
||||
return aNode->_check ? \
|
||||
static_cast<_class*>(static_cast<nsINode*>(aNode)) : nullptr; \
|
||||
} \
|
||||
template<typename ArgType> \
|
||||
static _class* FromNodeOrNull(ArgType&& aNode) \
|
||||
{ \
|
||||
return aNode ? FromNode(aNode) : nullptr; \
|
||||
} \
|
||||
template<typename ArgType> \
|
||||
static const _class* FromNode(const ArgType* aNode) \
|
||||
{ \
|
||||
return aNode->_check ? static_cast<const _class*>(aNode) : nullptr; \
|
||||
} \
|
||||
template<typename ArgType> \
|
||||
static const _class* FromNodeOrNull(const ArgType* aNode) \
|
||||
{ \
|
||||
return aNode ? FromNode(aNode) : nullptr; \
|
||||
}
|
||||
|
||||
#define NS_IMPL_FROMNODE(_class, _nsid) \
|
||||
NS_IMPL_FROMNODE_HELPER(_class, IsInNamespace(_nsid))
|
||||
|
||||
#define NS_IMPL_FROMNODE_WITH_TAG(_class, _nsid, _tag) \
|
||||
NS_IMPL_FROMNODE_HELPER(_class, NodeInfo()->Equals(nsGkAtoms::_tag, _nsid))
|
||||
|
||||
#define NS_IMPL_FROMNODE_HTML_WITH_TAG(_class, _tag) \
|
||||
NS_IMPL_FROMNODE_WITH_TAG(_class, kNameSpaceID_XHTML, _tag)
|
||||
|
||||
#endif /* nsINode_h___ */
|
||||
|
|
|
@ -16,38 +16,26 @@
|
|||
"use strict";
|
||||
/** Test for Bug 816410 **/
|
||||
|
||||
function throws(a, type, message) {
|
||||
for (let fn of Array.isArray(a) ? a : [a]) {
|
||||
try {
|
||||
fn();
|
||||
ok(false, message);
|
||||
} catch (e) {
|
||||
if (type) {
|
||||
is(e.name, type, message);
|
||||
} else {
|
||||
ok(true, message);
|
||||
}
|
||||
function throws(fn, type, message) {
|
||||
try {
|
||||
fn();
|
||||
ok(false, message);
|
||||
} catch (e) {
|
||||
if (type) {
|
||||
is(e.name, type, message);
|
||||
} else {
|
||||
ok(true, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DOMParser constructor should not throw for null arguments
|
||||
// DOMParser constructor should not throw for extra arguments
|
||||
new DOMParser(undefined);
|
||||
new DOMParser(null);
|
||||
|
||||
throws([
|
||||
function() { new DOMParser(false); },
|
||||
function() { new DOMParser(0); },
|
||||
function() { new DOMParser(""); },
|
||||
function() { new DOMParser({}); },
|
||||
], "TypeError", "DOMParser constructor should throw for extra arguments");
|
||||
|
||||
{
|
||||
let parser = new DOMParser();
|
||||
throws(function() {
|
||||
parser.init();
|
||||
}, "NS_ERROR_UNEXPECTED", "init method should throw when DOMParser is created by constructor");
|
||||
}
|
||||
new DOMParser(false);
|
||||
new DOMParser(0);
|
||||
new DOMParser("");
|
||||
new DOMParser({});
|
||||
|
||||
// XMLSerializer constructor should not throw for extra arguments
|
||||
new XMLSerializer(undefined);
|
||||
|
@ -59,24 +47,10 @@ new XMLSerializer({});
|
|||
|
||||
runTest(new DOMParser(), new XMLSerializer());
|
||||
|
||||
{
|
||||
let parser = Cc["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Ci.nsIDOMParser);
|
||||
parser.init();
|
||||
throws(function() {
|
||||
parser.init();
|
||||
}, "NS_ERROR_UNEXPECTED", "init method should throw when called twice");
|
||||
}
|
||||
|
||||
runTest(Cc["@mozilla.org/xmlextras/domparser;1"]
|
||||
.createInstance(Ci.nsIDOMParser),
|
||||
new XMLSerializer());
|
||||
|
||||
function runTest(parser, serializer) {
|
||||
is(typeof parser.parseFromString, "function", "parseFromString should exist");
|
||||
is(typeof parser.parseFromBuffer, "function", "parseFromBuffer should exist");
|
||||
is(typeof parser.parseFromStream, "function", "parseFromStream should exist");
|
||||
is(typeof parser.init, "function", "init should exist");
|
||||
|
||||
is(typeof serializer.serializeToString, "function", "serializeToString should exist");
|
||||
is(typeof serializer.serializeToStream, "function", "serializeToStream should exist");
|
||||
|
@ -115,13 +89,8 @@ function runTest(parser, serializer) {
|
|||
];
|
||||
for (let input of inputs) {
|
||||
let a = input.array;
|
||||
is(serializer.serializeToString(parser.parseFromBuffer(a, a.length, t.type)), t.expected,
|
||||
is(serializer.serializeToString(parser.parseFromBuffer(a, t.type)), t.expected,
|
||||
input.name + " test for " + t.type);
|
||||
throws(function() {
|
||||
parser.parseFromBuffer(a, a.length + 1, t.type);
|
||||
}, "NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY",
|
||||
input.name + " should throw if bufLen parameter is greater than actual length"
|
||||
);
|
||||
}
|
||||
|
||||
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
|
||||
|
|
|
@ -20,11 +20,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=592829
|
|||
// to create a DOMParser which is not allowed to parse XUL.
|
||||
|
||||
var isXUL = true;
|
||||
var parser = SpecialPowers.getNoXULDOMParser();
|
||||
ok(parser, "Should get a parser!");
|
||||
|
||||
try {
|
||||
var x =
|
||||
SpecialPowers.Cc
|
||||
.getService(Ci.nsIDOMParser)
|
||||
.parseFromString('<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>', "text/xml");
|
||||
var x = parser
|
||||
.parseFromString('<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>', "text/xml");
|
||||
isXUL = x.documentElement.namespaceURI ==
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
}
|
||||
|
|
|
@ -12,17 +12,16 @@ const nsIProperties = I.nsIProperties;
|
|||
const nsIFileInputStream = I.nsIFileInputStream;
|
||||
const nsIInputStream = I.nsIInputStream;
|
||||
|
||||
const nsIDOMParser = I.nsIDOMParser;
|
||||
const nsIDOMDocument = I.nsIDOMDocument;
|
||||
const nsIDOMElement = I.nsIDOMElement;
|
||||
const nsIDOMNode = I.nsIDOMNode;
|
||||
const nsIDOMNodeList = I.nsIDOMNodeList;
|
||||
|
||||
Cu.importGlobalProperties(["XMLSerializer"]);
|
||||
Cu.importGlobalProperties(["DOMParser", "XMLSerializer"]);
|
||||
|
||||
function DOMParser() {
|
||||
var parser = C["@mozilla.org/xmlextras/domparser;1"].createInstance(nsIDOMParser);
|
||||
parser.init();
|
||||
function getParser() {
|
||||
var parser = new DOMParser();
|
||||
parser.forceEnableXULXBL();
|
||||
return parser;
|
||||
}
|
||||
|
||||
|
@ -49,12 +48,12 @@ function ParseFile(file) {
|
|||
|
||||
function ParseXML(data) {
|
||||
if (typeof(data) == "string") {
|
||||
return DOMParser().parseFromString(data, "application/xml");
|
||||
return getParser().parseFromString(data, "application/xml");
|
||||
}
|
||||
|
||||
Assert.equal(data instanceof nsIInputStream, true);
|
||||
|
||||
return DOMParser().parseFromStream(data, "UTF-8", data.available(),
|
||||
return getParser().parseFromStream(data, "UTF-8", data.available(),
|
||||
"application/xml");
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ var ios = Cc["@mozilla.org/network/io-service;1"].
|
|||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
|
||||
var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
|
||||
createInstance(Ci.nsIDOMParser);
|
||||
Cu.importGlobalProperties(["DOMParser"]);
|
||||
var parser = new DOMParser();
|
||||
|
||||
var doc;
|
||||
|
||||
|
@ -21,7 +21,6 @@ var node2;
|
|||
function run_test() {
|
||||
prefs.setBoolPref("network.prefetch-next", true);
|
||||
|
||||
parser.init();
|
||||
doc = parser.parseFromString(docbody, "text/html");
|
||||
|
||||
node1 = doc.getElementById("node1");
|
||||
|
|
|
@ -18,7 +18,7 @@ function test_generate_xpath()
|
|||
</body>
|
||||
</html>
|
||||
`;
|
||||
let doc = DOMParser().parseFromString(docString, "text/html");
|
||||
let doc = getParser().parseFromString(docString, "text/html");
|
||||
|
||||
// Test generate xpath for body.
|
||||
info("Test generate xpath for body node");
|
||||
|
|
|
@ -35,7 +35,7 @@ function getFragment(aNode) {
|
|||
|
||||
// Goodies from head_content.js
|
||||
const serializer = new DOMSerializer();
|
||||
const parser = new DOMParser();
|
||||
const parser = getParser();
|
||||
|
||||
/**
|
||||
* Dump the contents of a document fragment to the console.
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
ChromeUtils.import("resource://testing-common/httpd.js");
|
||||
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.importGlobalProperties(["DOMParser"]);
|
||||
|
||||
var server = new HttpServer();
|
||||
server.start(-1);
|
||||
|
@ -21,8 +22,7 @@ function run_test() {
|
|||
do_test_pending();
|
||||
server.registerPathHandler("/foo", handler);
|
||||
|
||||
var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser);
|
||||
parser.init();
|
||||
var parser = new DOMParser();
|
||||
let doc = parser.parseFromString(docbody, "text/html");
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.onload = function() {
|
||||
|
|
|
@ -3,6 +3,5 @@
|
|||
|
||||
conformance/00_test_list.txt
|
||||
conformance/more/00_test_list.txt
|
||||
// Disable deqp tests temporarily
|
||||
// deqp/00_test_list.txt
|
||||
deqp/00_test_list.txt
|
||||
--min-version 2.0.0 conformance2/00_test_list.txt
|
||||
|
|
|
@ -75,5 +75,6 @@ The dates below are when work on the conformance suite version was started.
|
|||
- 2012/02/23: Version 1.0.1
|
||||
- 2012/03/20: Version 1.0.2
|
||||
- 2013/02/14: Version 1.0.3
|
||||
- 2013/10/11: Version 2.0.0 (beta)
|
||||
- 2013/10/11: Version 2.0.0
|
||||
- 2014/11/14: Version 1.0.4
|
||||
- 2016/11/21: Version 2.0.1
|
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/closurebuilder.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/closurebuilder.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depstree.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depstree.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depswriter.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/build/depswriter.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/calcdeps.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/calcdeps.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/scopify.py
Normal file → Executable file
0
dom/canvas/test/webgl-conf/checkout/closure-library/closure/bin/scopify.py
Normal file → Executable file
|
@ -1,13 +0,0 @@
|
|||
This file "00_test_list.txt" lists which files the test harness should run.
|
||||
|
||||
If you add new tests you can update it with
|
||||
|
||||
on windows
|
||||
|
||||
dir /b *.html >00_test_list.txt
|
||||
|
||||
on OSX / Linux
|
||||
|
||||
ls -1 *.html >00_test_list.txt
|
||||
|
||||
|
|
@ -7,6 +7,7 @@ glsl/00_test_list.txt
|
|||
limits/00_test_list.txt
|
||||
misc/00_test_list.txt
|
||||
--min-version 1.0.2 ogles/00_test_list.txt
|
||||
--min-version 1.0.4 offscreencanvas/00_test_list.txt
|
||||
programs/00_test_list.txt
|
||||
reading/00_test_list.txt
|
||||
renderbuffers/00_test_list.txt
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
--min-version 1.0.3 gl-bindAttribLocation-aliasing.html
|
||||
--min-version 1.0.3 gl-bindAttribLocation-matrix.html
|
||||
--min-version 1.0.4 gl-bindAttribLocation-nonexistent-attribute.html
|
||||
--min-version 1.0.4 gl-bindAttribLocation-repeated.html
|
||||
--min-version 1.0.2 gl-disabled-vertex-attrib.html
|
||||
gl-enable-vertex-attrib.html
|
||||
|
@ -9,3 +10,4 @@ gl-vertexattribpointer.html
|
|||
gl-vertexattribpointer-offsets.html
|
||||
--min-version 1.0.2 gl-vertex-attrib-render.html
|
||||
gl-vertex-attrib-zero-issues.html
|
||||
--min-version 1.0.4 gl-vertex-attrib-unconsumed-out-of-bounds.html
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/gl-bindattriblocation-aliasing.js"></script>
|
||||
<title>bindAttribLocation with aliasing</title>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -50,39 +51,9 @@ var wtu = WebGLTestUtils;
|
|||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas, {antialias: false});
|
||||
var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
|
||||
var typeInfo = [
|
||||
{ type: 'float', asVec4: 'vec4(0.0, $(var), 0.0, 1.0)' },
|
||||
{ type: 'vec2', asVec4: 'vec4($(var), 0.0, 1.0)' },
|
||||
{ type: 'vec3', asVec4: 'vec4($(var), 1.0)' },
|
||||
{ type: 'vec4', asVec4: '$(var)' },
|
||||
];
|
||||
var maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
||||
// Test all type combinations of a_1 and a_2.
|
||||
typeInfo.forEach(function(typeInfo1) {
|
||||
typeInfo.forEach(function(typeInfo2) {
|
||||
debug('attribute_1: ' + typeInfo1.type + ' attribute_2: ' + typeInfo2.type);
|
||||
var replaceParams = {
|
||||
type_1: typeInfo1.type,
|
||||
type_2: typeInfo2.type,
|
||||
gl_Position_1: wtu.replaceParams(typeInfo1.asVec4, {var: 'a_1'}),
|
||||
gl_Position_2: wtu.replaceParams(typeInfo2.asVec4, {var: 'a_2'})
|
||||
};
|
||||
var strVertexShader = wtu.replaceParams(wtu.getScript('vertexShader'), replaceParams);
|
||||
var glVertexShader = wtu.loadShader(gl, strVertexShader, gl.VERTEX_SHADER);
|
||||
assertMsg(glVertexShader != null, "Vertex shader compiled successfully.");
|
||||
// Bind both a_1 and a_2 to the same position and verify the link fails.
|
||||
// Do so for all valid positions available.
|
||||
for (var l = 0; l < maxAttributes; l++) {
|
||||
var glProgram = gl.createProgram();
|
||||
gl.bindAttribLocation(glProgram, l, 'a_1');
|
||||
gl.bindAttribLocation(glProgram, l, 'a_2');
|
||||
gl.attachShader(glProgram, glVertexShader);
|
||||
gl.attachShader(glProgram, glFragmentShader);
|
||||
gl.linkProgram(glProgram);
|
||||
assertMsg(!gl.getProgramParameter(glProgram, gl.LINK_STATUS), "Link should fail when both types are aliased to location " + l);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
runBindAttribLocationAliasingTest(wtu, gl, glFragmentShader, wtu.getScript('vertexShader'));
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<title>bindAttribLocation with nonexistent attribute name</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="8" height="8"></canvas>
|
||||
<script id="vertexShader" type="text/something-not-javascript">
|
||||
precision highp float;
|
||||
attribute vec4 attr;
|
||||
void main() {
|
||||
gl_Position = vec4(attr);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies that calling bindAttribLocation with a non-existent attribute location is fine.");
|
||||
|
||||
// OpenGL ES 2.0.25 section 2.10 page 34.
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var fragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
|
||||
var vertexShader = wtu.loadShaderFromScript(gl, 'vertexShader', gl.VERTEX_SHADER);
|
||||
assertMsg(vertexShader != null, "Vertex shader compiled successfully.");
|
||||
|
||||
var checkAttribLocation = function(program, expectedLocation) {
|
||||
var location = gl.getAttribLocation(program, 'attr');
|
||||
if (location != expectedLocation) {
|
||||
testFailed('Unexpected location for attr: ' + location);
|
||||
} else {
|
||||
testPassed('Location of attr is: ' + location);
|
||||
}
|
||||
}
|
||||
|
||||
var testProgramNonExistentAttributeBound = function() {
|
||||
var program = gl.createProgram();
|
||||
gl.bindAttribLocation(program, 0, 'attr');
|
||||
gl.bindAttribLocation(program, 1, 'bogus_attr');
|
||||
gl.attachShader(program, vertexShader);
|
||||
gl.attachShader(program, fragmentShader);
|
||||
gl.linkProgram(program);
|
||||
var linkStatus = gl.getProgramParameter(program, gl.LINK_STATUS);
|
||||
expectTrue(linkStatus, "Link should succeed even if a non-existent attribute is bound.");
|
||||
if (linkStatus) {
|
||||
checkAttribLocation(program, 0);
|
||||
}
|
||||
};
|
||||
var testProgramNonExistentAttributeOverlap = function() {
|
||||
var program = gl.createProgram();
|
||||
gl.bindAttribLocation(program, 1, 'attr');
|
||||
gl.bindAttribLocation(program, 1, 'bogus_attr');
|
||||
gl.attachShader(program, vertexShader);
|
||||
gl.attachShader(program, fragmentShader);
|
||||
gl.linkProgram(program);
|
||||
var linkStatus = gl.getProgramParameter(program, gl.LINK_STATUS);
|
||||
expectTrue(linkStatus, "Link should succeed even if a non-existent attribute is bound to the same location as an attribute that's present in the shader text.");
|
||||
if (linkStatus) {
|
||||
checkAttribLocation(program, 1);
|
||||
}
|
||||
};
|
||||
|
||||
testProgramNonExistentAttributeBound();
|
||||
testProgramNonExistentAttributeOverlap();
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,210 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Unconsumed Vertex Attributes Out of Bounds Test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="50" height="50">
|
||||
</canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
void main() { }
|
||||
</script>
|
||||
|
||||
<script id="vshader_attrib" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
void main() {
|
||||
gl_Position = vPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
void main() { }
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Test that unconsumed vertex attributes are not read out of bounds");
|
||||
// Tests for http://crbug.com/756293 (driver crash on macOS)
|
||||
// and a class of similar bugs that could exist on other systems.
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var contextVersion = wtu.getDefault3DContextVersion();
|
||||
var gl = wtu.create3DContext("example");
|
||||
var g_program;
|
||||
var g_attribLocation;
|
||||
|
||||
var numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
||||
var allocatedBuffer;
|
||||
var indexBuffer;
|
||||
|
||||
function setupBuffers(numVerts) {
|
||||
var vertices = new Float32Array(numVerts * 3);
|
||||
allocatedBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, allocatedBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
|
||||
|
||||
var indices = new Uint16Array(numVerts);
|
||||
for (var ii = 0; ii < numVerts; ++ii) {
|
||||
indices[ii] = ii;
|
||||
}
|
||||
|
||||
indexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
|
||||
}
|
||||
|
||||
var progNoAttribs = wtu.setupProgram(gl, ['vshader', 'fshader'], [], []);
|
||||
var progAttrib1 = wtu.setupProgram(gl, ['vshader_attrib', 'fshader'], ['vPosition'], [1]);
|
||||
var progAttrib2 = wtu.setupProgram(gl, ['vshader_attrib', 'fshader'], ['vPosition'], [2]);
|
||||
setupBuffers(60000);
|
||||
|
||||
var unallocatedBuffer = gl.createBuffer();
|
||||
var tests = [];
|
||||
|
||||
debug("");
|
||||
debug("<u>Tests with one unconsumed attribute<u>");
|
||||
|
||||
tests.push({
|
||||
name: "drawArrays",
|
||||
errors: gl.NO_ERROR,
|
||||
draw: function() { gl.drawArrays(gl.TRIANGLES, 0, 3); }
|
||||
});
|
||||
tests.push({
|
||||
name: "drawElements",
|
||||
errors: gl.NO_ERROR,
|
||||
draw: function() { gl.drawElements(gl.TRIANGLES, 60000, gl.UNSIGNED_SHORT, 0); }
|
||||
});
|
||||
|
||||
if (contextVersion >= 2) {
|
||||
tests.push({
|
||||
name: "drawArraysInstanced",
|
||||
errors: gl.NO_ERROR,
|
||||
draw: function() { gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 1); }
|
||||
});
|
||||
tests.push({
|
||||
name: "drawElementsInstanced",
|
||||
errors: gl.NO_ERROR,
|
||||
draw: function() { gl.drawElementsInstanced(gl.TRIANGLES, 60000, gl.UNSIGNED_SHORT, 0, 1); }
|
||||
});
|
||||
tests.push({
|
||||
name: "drawRangeElements",
|
||||
errors: gl.NO_ERROR,
|
||||
draw: function() { gl.drawRangeElements(gl.TRIANGLES, 0, 60000, 60000, gl.UNSIGNED_SHORT, 0, 1); }
|
||||
});
|
||||
}
|
||||
|
||||
// Run tests
|
||||
|
||||
// Bound forever
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
|
||||
for (var attrib = 0; attrib < numAttribs; ++attrib) {
|
||||
debug("Attrib " + attrib + " unconsumed");
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
var test = tests[i];
|
||||
gl.useProgram(progNoAttribs);
|
||||
|
||||
gl.enableVertexAttribArray(attrib);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, unallocatedBuffer);
|
||||
gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
test.draw();
|
||||
|
||||
gl.disableVertexAttribArray(attrib);
|
||||
wtu.glErrorShouldBe(gl, test.errors, test.name);
|
||||
}
|
||||
}
|
||||
|
||||
debug("");
|
||||
debug("<u>Tests with one consumed attribute and one unconsumed attribute<u>");
|
||||
|
||||
var ext = gl.getExtension("ANGLE_instanced_arrays");
|
||||
if (!ext) {
|
||||
debug("ANGLE_instanced_arrays not available - skipped");
|
||||
} else {
|
||||
tests.push({
|
||||
name: "drawArraysInstancedANGLE",
|
||||
errors: gl.NO_ERROR,
|
||||
draw: function() {
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, 0, 3, 1);
|
||||
}
|
||||
});
|
||||
tests.push({
|
||||
name: "drawElementsInstancedANGLE",
|
||||
errors: gl.NO_ERROR,
|
||||
draw: function() {
|
||||
ext.drawElementsInstancedANGLE(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Note these don't trigger the macOS driver crash (http://crbug.com/756293)
|
||||
// but they still add potentially useful coverage.
|
||||
for (var attrib = 0; attrib < numAttribs; ++attrib) {
|
||||
var consumedAttrib = attrib == 1 ? 2 : 1;
|
||||
var prog = consumedAttrib == 1 ? progAttrib1 : progAttrib2;
|
||||
debug("Attrib " + attrib +
|
||||
" unconsumed (attrib " + consumedAttrib + " consumed)");
|
||||
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
var test = tests[i];
|
||||
gl.useProgram(prog);
|
||||
|
||||
gl.enableVertexAttribArray(attrib);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, unallocatedBuffer);
|
||||
gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Needed because ANGLE_instanced_arrays requires at least one consumed
|
||||
// attribute to have divisor=0 (which is the default, so we don't need to
|
||||
// call vertexAttribDivisorANGLE here).
|
||||
gl.enableVertexAttribArray(consumedAttrib);
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, allocatedBuffer);
|
||||
gl.vertexAttribPointer(consumedAttrib, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
test.draw();
|
||||
|
||||
gl.disableVertexAttribArray(attrib);
|
||||
gl.disableVertexAttribArray(consumedAttrib);
|
||||
wtu.glErrorShouldBe(gl, test.errors, test.name);
|
||||
}
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -128,7 +128,7 @@ for (var ii = 0; ii < 5; ++ii) {
|
|||
wtu.checkCanvas(gl, [0, 255, 0, 255], "canvas should be green");
|
||||
gl.disableVertexAttribArray(3);
|
||||
|
||||
// This second test of drawing without attrib0 unconvered a bug in chrome
|
||||
// This second test of drawing without attrib0 uncovered a bug in chrome
|
||||
// where after the draw without attrib0 the attrib 0 emulation code disabled
|
||||
// attrib 0 and it was never re-enabled so this next draw failed.
|
||||
gl.useProgram(p3);
|
||||
|
|
|
@ -59,14 +59,28 @@ if (!gl) {
|
|||
gl.FIXED = 0x140C;
|
||||
}
|
||||
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, 0, 0, 12);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||
"vertexAttribPointer should fail if no buffer is bound");
|
||||
|
||||
var vertexObject = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(0), gl.STATIC_DRAW);
|
||||
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 4);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION,
|
||||
"vertexAttribPointer should fail if no buffer is bound and `offset` is non-zero.");
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR,
|
||||
"vertexAttribPointer should succeed if no buffer is bound and `offset` is zero.");
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
|
||||
|
||||
|
||||
if (wtu.getDefault3DContextVersion() < 2) {
|
||||
gl.vertexAttribPointer(0, 1, gl.INT, 0, 0, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
buffer-bind-test.html
|
||||
buffer-data-and-buffer-sub-data.html
|
||||
--min-version 1.0.3 buffer-data-array-buffer-delete.html
|
||||
--min-version 1.0.4 buffer-data-dynamic-delay.html
|
||||
--min-version 1.0.4 buffer-uninitialized.html
|
||||
--min-version 1.0.2 element-array-buffer-delete-recreate.html
|
||||
index-validation-copies-indices.html
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>bufferData with DYNAMIC_DRAW and delay between updating data</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="50" height="50"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec2 a_position;
|
||||
attribute vec2 a_color;
|
||||
varying vec2 v_color;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(a_position, 0.0, 1.0);
|
||||
v_color = a_color;
|
||||
}
|
||||
</script>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying vec2 v_color;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(v_color, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
description("Verifies that bufferData with DYNAMIC_DRAW updates the vertex attribute when there is a significant delay between updating the buffer.");
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("canvas");
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["a_position", "a_color"]);
|
||||
|
||||
// Initialize position vertex attribute to draw a square covering the entire canvas.
|
||||
var positionBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
-1.0, 1.0,
|
||||
1.0, 1.0,
|
||||
-1.0, -1.0,
|
||||
1.0, -1.0
|
||||
]), gl.DYNAMIC_DRAW);
|
||||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
// Initialize color vertex attribute to red.
|
||||
var colorBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
1.0, 0.0,
|
||||
1.0, 0.0,
|
||||
1.0, 0.0,
|
||||
1.0, 0.0,
|
||||
]), gl.DYNAMIC_DRAW);
|
||||
gl.enableVertexAttribArray(1);
|
||||
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No error after setup");
|
||||
|
||||
// Fill the canvas with red
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No error after first drawArrays");
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 0, 50, 50, [255, 0, 0, 255], "Canvas should be red after the first drawArrays");
|
||||
|
||||
// With the buffer set to DYNAMIC_DRAW, Angle internally changes the storage type of the vertex attribute from DYNAMIC to DIRECT
|
||||
// if the buffer has not been updated after ~4-5 draw calls. When the buffer is eventually updated, the vertex attribute
|
||||
// is updated back to DYNAMIC, but there was a bug in Angle where the data is not marked as dirty. The result is that the
|
||||
// vertex data is not updated with the new buffer data. This test verifies that the vertex data is updated.
|
||||
var iteration = 0;
|
||||
function draw() {
|
||||
// Draw 10 times to ensure that the vertex attribute storage type is changed.
|
||||
if (iteration < 10) {
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 2);
|
||||
requestAnimationFrame(draw);
|
||||
}
|
||||
else {
|
||||
// Update the buffer bound to the color vertex attribute to green and draw.
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
0.0, 1.0,
|
||||
0.0, 1.0,
|
||||
0.0, 1.0,
|
||||
0.0, 1.0,
|
||||
]), gl.DYNAMIC_DRAW);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "No error after last drawArrays");
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 0, 50, 50, [0, 255, 0, 255], "Canvas should be green after 10 frames");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
iteration++;
|
||||
}
|
||||
|
||||
requestAnimationFrame(draw);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -56,13 +56,15 @@ context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexObject);
|
|||
var indices = new Uint16Array([ 10000, 0, 1, 2, 3, 10000 ]);
|
||||
context.bufferData(context.ELEMENT_ARRAY_BUFFER, indices, context.STATIC_DRAW);
|
||||
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 2)");
|
||||
wtu.shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
var indexValidationError = wtu.shouldGenerateGLError(context,
|
||||
[context.INVALID_OPERATION, context.NO_ERROR],
|
||||
"context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
indices[0] = 2;
|
||||
indices[5] = 1;
|
||||
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 2)");
|
||||
wtu.shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
wtu.shouldGenerateGLError(context, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
|
|
|
@ -58,9 +58,9 @@ var indexObject = context.createBuffer();
|
|||
debug("Test out of range indices")
|
||||
context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
context.bufferData(context.ELEMENT_ARRAY_BUFFER, new Uint16Array([ 10000, 0, 1, 2, 3, 10000 ]), context.STATIC_DRAW);
|
||||
var indexValidationError = wtu.shouldGenerateGLError(context, [context.INVALID_OPERATION, context.NO_ERROR], "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 2)");
|
||||
wtu.shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 0)");
|
||||
wtu.shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
wtu.shouldGenerateGLError(context, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
|
||||
|
||||
debug("")
|
||||
var successfullyParsed = true;
|
||||
|
|
|
@ -110,7 +110,7 @@ gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT),
|
|||
gl.enableVertexAttribArray(normalLoc);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)');
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
|
||||
wtu.glErrorShouldBe(gl, [gl.INVALID_OPERATION, gl.NO_ERROR]);
|
||||
|
||||
debug("Test with enabled attribute that does not belong to current program");
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ drawingbuffer-test.html
|
|||
--min-version 1.0.2 framebuffer-bindings-unaffected-on-resize.html
|
||||
--min-version 1.0.4 framebuffer-bindings-affected-by-to-data-url.html
|
||||
--min-version 1.0.3 rapid-resizing.html
|
||||
--min-version 1.0.4 render-after-resize-test.html
|
||||
--min-version 1.0.2 texture-bindings-unaffected-on-resize.html
|
||||
--min-version 1.0.2 to-data-url-test.html
|
||||
viewport-unchanged-upon-resize.html
|
||||
|
|
|
@ -104,11 +104,14 @@ if (!gl) {
|
|||
g2d = imgData.data[offset + 1];
|
||||
b2d = imgData.data[offset + 2];
|
||||
a2d = imgData.data[offset + 3];
|
||||
//debug('' + x + ', ' + y + "(" + offset + ") = " + r2d + ", " + g2d + ", " + b2d + ", " + a2d);
|
||||
return isAboutEqualInt(r2d, r3d) &&
|
||||
isAboutEqualInt(g2d, g3d) &&
|
||||
isAboutEqualInt(b2d, b3d) &&
|
||||
isAboutEqualInt(a2d, a3d);
|
||||
var res = isAboutEqualInt(r2d, r3d) &&
|
||||
isAboutEqualInt(g2d, g3d) &&
|
||||
isAboutEqualInt(b2d, b3d) &&
|
||||
isAboutEqualInt(a2d, a3d);
|
||||
if (!res) {
|
||||
bufferedLogToConsole('at ' + x + ', ' + y + " (offset " + offset + ") = " + r2d + ", " + g2d + ", " + b2d + ", " + a2d);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
var checkPixels = function(r3d,g3d,b3d,a3d) {
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL render after resize test</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"> </script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas style="width: 100px, height: 100px; border: 1px solid blue;" id="c"></canvas>
|
||||
<div id="console"></div>
|
||||
<script>
|
||||
description("This test ensures WebGL implementations can render correctly after resizing the canvas.");
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("c");
|
||||
shouldBeTrue("gl != null");
|
||||
|
||||
var positionLocation = 0;
|
||||
var texcoordLocation = 1;
|
||||
var program = wtu.setupColorQuad(gl, positionLocation);
|
||||
var colorLocation = gl.getUniformLocation(program, 'u_color');
|
||||
gl.uniform4fv(colorLocation, [0.0, 1.0, 0.0, 1.0]);
|
||||
|
||||
const smallWidth = 300;
|
||||
const smallHeight = 150;
|
||||
// Changing this size to something smaller produces
|
||||
// different results. Sometimes wrong, sometimes correct.
|
||||
const largeWidth = 1200;
|
||||
const largeHeight = 672;
|
||||
|
||||
function render() {
|
||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.clearColor(1,0,0,1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
gl.useProgram(program);
|
||||
wtu.drawUnitQuad(gl);
|
||||
}
|
||||
|
||||
function checkForQuad(ctx) {
|
||||
let w = ctx.drawingBufferWidth;
|
||||
let h = ctx.drawingBufferHeight;
|
||||
|
||||
wtu.checkCanvasRect(gl, 0, 0, w, h, [ 0, 255, 0, 255 ]);
|
||||
}
|
||||
|
||||
gl.canvas.width = smallWidth;
|
||||
gl.canvas.height = smallHeight;
|
||||
render();
|
||||
checkForQuad(gl); // passes
|
||||
|
||||
gl.canvas.width = largeWidth;
|
||||
gl.canvas.height = largeHeight;
|
||||
gl.canvas.width = smallWidth;
|
||||
gl.canvas.height = smallHeight;
|
||||
render();
|
||||
checkForQuad(gl); // fails (almost all the time)
|
||||
|
||||
finishTest();
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
|
|
|
@ -472,7 +472,6 @@ canvas : "implementation-dependent"
|
|||
// added in versions of the spec that are backward-compatible with
|
||||
// this version
|
||||
var ignoredProperties = [
|
||||
'STENCIL_INDEX'
|
||||
];
|
||||
|
||||
// Constants removed from the WebGL spec compared to ES 2.0
|
||||
|
|
|
@ -156,6 +156,8 @@ function testLosingAndRestoringContext()
|
|||
testLostContext(e);
|
||||
// restore the context after this event has exited.
|
||||
setTimeout(function() {
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()");
|
||||
// Calling restoreContext() twice should not cause error or crash
|
||||
shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()");
|
||||
// The context should still be lost. It will not get restored until the
|
||||
// webglrestorecontext event is fired.
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
--min-version 1.0.2 --max-version 1.9.9 oes-element-index-uint.html
|
||||
webgl-debug-renderer-info.html
|
||||
webgl-debug-shaders.html
|
||||
--min-version 1.0.4 webgl-compressed-texture-astc.html
|
||||
--min-version 1.0.3 webgl-compressed-texture-atc.html
|
||||
--min-version 1.0.4 webgl-compressed-texture-etc.html
|
||||
--min-version 1.0.3 webgl-compressed-texture-pvrtc.html
|
||||
|
@ -33,6 +34,8 @@ webgl-debug-shaders.html
|
|||
--min-version 1.0.3 webgl-compressed-texture-size-limit.html
|
||||
--min-version 1.0.2 --max-version 1.9.9 webgl-depth-texture.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 webgl-draw-buffers.html
|
||||
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-broadcast-return.html
|
||||
--min-version 1.0.3 --max-version 1.9.9 webgl-draw-buffers-feedback-loop.html
|
||||
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-framebuffer-unsupported.html
|
||||
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-max-draw-buffers.html
|
||||
--min-version 1.0.3 webgl-shared-resources.html
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
|
@ -119,6 +119,8 @@ if (!gl) {
|
|||
runDrawArraysWithOffsetTest();
|
||||
runVAOInstancingInteractionTest();
|
||||
runANGLECorruptionTest();
|
||||
// Note that the ANGLE corruption test leaves vertex attrib divisors dirty at the moment.
|
||||
// This should be cleaned up if more subtests are added after it.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,6 +180,9 @@ function runDivisorTestEnabled() {
|
|||
else{
|
||||
testFailed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE should be: 2, returned value was: " + queried_value);
|
||||
}
|
||||
|
||||
// Reset vertex attrib divisors so they cannot affect following subtests.
|
||||
ext.vertexAttribDivisorANGLE(max_vertex_attribs-1, 0);
|
||||
}
|
||||
|
||||
function setupCanvas() {
|
||||
|
@ -351,6 +356,10 @@ function runOutputTests() {
|
|||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with QUADS should return INVALID_ENUM");
|
||||
ext.drawElementsInstancedANGLE(desktopGL['POLYGON'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with POLYGON should return INVALID_ENUM");
|
||||
|
||||
// Reset vertex attrib divisors so they cannot affect following subtests.
|
||||
ext.vertexAttribDivisorANGLE(colorLoc, 0);
|
||||
ext.vertexAttribDivisorANGLE(offsetLoc, 0);
|
||||
}
|
||||
|
||||
function runDrawArraysTest(program, first, count, instanceCount, offset)
|
||||
|
@ -404,6 +413,9 @@ function runDrawArraysTest(program, first, count, instanceCount, offset)
|
|||
// Do the instanced draw
|
||||
ext.drawArraysInstancedANGLE(gl.TRIANGLES, first, count, instanceCount);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE should succeed");
|
||||
|
||||
// Reset vertex attrib divisors so they cannot affect following subtests.
|
||||
ext.vertexAttribDivisorANGLE(instancePosLoc, 0);
|
||||
}
|
||||
|
||||
function runDrawArraysWithOffsetTest()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
|
|
|
@ -65,19 +65,24 @@ if (!gl) {
|
|||
testPassed("No EXT_disjoint_timer_query support -- this is legal");
|
||||
finishTest();
|
||||
} else {
|
||||
runSanityTests();
|
||||
if (wtu.getDefault3DContextVersion() > 1) {
|
||||
testFailed("EXT_disjoint_timer_query must not be advertised on WebGL 2.0 contexts");
|
||||
finishTest();
|
||||
} else {
|
||||
runSanityTests();
|
||||
|
||||
// Clear disjoint value.
|
||||
gl.getParameter(ext.GPU_DISJOINT_EXT);
|
||||
// Clear disjoint value.
|
||||
gl.getParameter(ext.GPU_DISJOINT_EXT);
|
||||
|
||||
runElapsedTimeTest();
|
||||
timestamp_counter_bits = ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT);
|
||||
if (timestamp_counter_bits > 0) {
|
||||
runTimeStampTest();
|
||||
runElapsedTimeTest();
|
||||
timestamp_counter_bits = ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT);
|
||||
if (timestamp_counter_bits > 0) {
|
||||
runTimeStampTest();
|
||||
}
|
||||
verifyQueryResultsNotAvailable();
|
||||
|
||||
window.requestAnimationFrame(checkQueryResults);
|
||||
}
|
||||
verifyQueryResultsNotAvailable();
|
||||
|
||||
window.requestAnimationFrame(checkQueryResults);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
<meta charset="utf-8"/>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -28,6 +27,27 @@ void main() {
|
|||
}
|
||||
</script>
|
||||
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 vPosition;
|
||||
attribute vec2 texCoord0;
|
||||
varying vec2 texCoord;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vPosition;
|
||||
texCoord = texCoord0;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform sampler2D tex;
|
||||
varying vec2 texCoord;
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(tex, texCoord);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
|
@ -227,6 +247,7 @@ if (!gl) {
|
|||
runFramebufferTextureConversionTest(ext.SRGB_EXT);
|
||||
runFramebufferTextureConversionTest(ext.SRGB_ALPHA_EXT);
|
||||
runFramebufferRenderbufferConversionTest();
|
||||
runGenerateMipmapTest();
|
||||
runLoadFromImageTest(function() {
|
||||
finishTest();
|
||||
});
|
||||
|
@ -424,6 +445,23 @@ function runLoadFromImageTest(callback) {
|
|||
});
|
||||
}
|
||||
|
||||
function runGenerateMipmapTest()
|
||||
{
|
||||
debug("");
|
||||
debug("GenerateMipmaps for sRGB textures is forbidden");
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, ext.SRGB_ALPHA_EXT, 2, 2, 0, ext.SRGB_ALPHA_EXT,
|
||||
gl.UNSIGNED_BYTE, null);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
gl.generateMipmap(gl.TEXTURE_2D);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
|
||||
|
||||
gl.deleteTexture(tex);
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
|
|
|
@ -289,8 +289,8 @@ function runIndexValidationTests(drawType) {
|
|||
gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
|
||||
gl.enableVertexAttribArray(normalLoc);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION);
|
||||
wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
|
||||
'gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
|
||||
|
||||
debug("Test with enabled attribute that does not belong to current program");
|
||||
|
||||
|
@ -330,13 +330,14 @@ function runCopiesIndicesTests(drawType) {
|
|||
var indices = new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType);
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
|
||||
"gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
indices[0] = 2;
|
||||
indices[5] = 1;
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
}
|
||||
|
||||
function runResizedBufferTests(drawType) {
|
||||
|
@ -422,8 +423,9 @@ function runVerifiesTooManyIndicesTests(drawType) {
|
|||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
|
||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]), drawType);
|
||||
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)");
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
|
||||
"gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 0)");
|
||||
wtu.shouldGenerateGLError(gl, indexValidationError, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)");
|
||||
}
|
||||
|
||||
function runCrashWithBufferSubDataTests(drawType) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
|
|
|
@ -82,41 +82,72 @@ var canvas = document.getElementById("canvas");
|
|||
var gl = wtu.create3DContext(canvas);
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
var texturedShaders = [
|
||||
wtu.simpleTextureVertexShader,
|
||||
"testFragmentShader"
|
||||
];
|
||||
var testProgram =
|
||||
wtu.setupProgram(gl,
|
||||
texturedShaders,
|
||||
['vPosition', 'texCoord0'],
|
||||
[0, 1]);
|
||||
var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
|
||||
var texturedShaders = [
|
||||
wtu.simpleTextureVertexShader,
|
||||
"testFragmentShader"
|
||||
];
|
||||
var testProgram =
|
||||
wtu.setupProgram(gl,
|
||||
texturedShaders,
|
||||
['vPosition', 'texCoord0'],
|
||||
[0, 1]);
|
||||
var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
|
||||
|
||||
// First verify that allocation of floating-point textures fails if
|
||||
// the extension has not been enabled yet.
|
||||
runTextureCreationTest(testProgram, false);
|
||||
// First verify that allocation of floating-point textures fails if
|
||||
// the extension has not been enabled yet.
|
||||
runTextureCreationTest(testProgram, false);
|
||||
|
||||
if (!gl.getExtension("OES_texture_float")) {
|
||||
testPassed("No OES_texture_float support -- this is legal");
|
||||
} else {
|
||||
testPassed("Successfully enabled OES_texture_float extension");
|
||||
// If alpha value is missing from a texture it gets filled to 1 when sampling according to GLES2.0 table 3.12
|
||||
runTextureCreationTest(testProgram, true, gl.RGBA, 4, [10000, 10000, 10000, 10000]);
|
||||
runTextureCreationTest(testProgram, true, gl.RGB, 3, [10000, 10000, 10000, 1]);
|
||||
runTextureCreationTest(testProgram, true, gl.LUMINANCE, 1, [10000, 10000, 10000, 1]);
|
||||
runTextureCreationTest(testProgram, true, gl.ALPHA, 1, [0, 0, 0, 10000]);
|
||||
runTextureCreationTest(testProgram, true, gl.LUMINANCE_ALPHA, 2, [10000, 10000, 10000, 10000]);
|
||||
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0);
|
||||
runRenderTargetAndReadbackTest(testProgram, gl.RGB, 3, [10000, 10000, 10000, 1], 0);
|
||||
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 1);
|
||||
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0.5);
|
||||
runUniqueObjectTest();
|
||||
}
|
||||
if (!gl.getExtension("OES_texture_float")) {
|
||||
testPassed("No OES_texture_float support -- this is legal");
|
||||
} else {
|
||||
testPassed("Successfully enabled OES_texture_float extension");
|
||||
// If alpha value is missing from a texture it gets filled to 1 when sampling according to GLES2.0 table 3.12
|
||||
runTextureCreationTest(testProgram, true, gl.RGBA, 4, [10000, 10000, 10000, 10000]);
|
||||
runTextureCreationTest(testProgram, true, gl.RGB, 3, [10000, 10000, 10000, 1]);
|
||||
runTextureCreationTest(testProgram, true, gl.LUMINANCE, 1, [10000, 10000, 10000, 1]);
|
||||
runTextureCreationTest(testProgram, true, gl.ALPHA, 1, [0, 0, 0, 10000]);
|
||||
runTextureCreationTest(testProgram, true, gl.LUMINANCE_ALPHA, 2, [10000, 10000, 10000, 10000]);
|
||||
|
||||
(function() {
|
||||
debug("");
|
||||
var renderable = isRenderable(gl);
|
||||
var renderableExtName = "WEBGL_color_buffer_float";
|
||||
var supported = gl.getSupportedExtensions().includes(renderableExtName);
|
||||
if (renderable && !supported) {
|
||||
testFailed("RGBA/FLOAT is color renderable but " + renderableExtName + " not exposed");
|
||||
} else if (supported && !renderable) {
|
||||
testFailed(renderableExtName + " is exposed but RGBA/FLOAT is not color renderable");
|
||||
}
|
||||
if (supported) {
|
||||
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0, true);
|
||||
runRenderTargetAndReadbackTest(testProgram, gl.RGB, 3, [10000, 10000, 10000, 1], 0, false);
|
||||
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 1, true);
|
||||
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0.5, true);
|
||||
}
|
||||
})();
|
||||
|
||||
runUniqueObjectTest();
|
||||
}
|
||||
}
|
||||
|
||||
function isRenderable(gl) {
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.FLOAT, null);
|
||||
|
||||
var fb = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
||||
|
||||
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||
gl.deleteFramebuffer(fb);
|
||||
gl.deleteTexture(tex);
|
||||
|
||||
return status == gl.FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
function allocateTexture()
|
||||
|
@ -189,7 +220,7 @@ function arrayToString(arr, size) {
|
|||
return out + "]";
|
||||
}
|
||||
|
||||
function runRenderTargetAndReadbackTest(testProgram, format, numberOfChannels, subtractor, texSubImageCover)
|
||||
function runRenderTargetAndReadbackTest(testProgram, format, numberOfChannels, subtractor, texSubImageCover, requireRenderable)
|
||||
{
|
||||
var formatString = wtu.glEnumToString(gl, format);
|
||||
debug("");
|
||||
|
@ -209,7 +240,10 @@ function runRenderTargetAndReadbackTest(testProgram, format, numberOfChannels, s
|
|||
// It is legal for a WebGL implementation exposing the OES_texture_float extension to
|
||||
// support floating-point textures but not as attachments to framebuffer objects.
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
||||
debug("floating-point " + formatString + " render target not supported -- this is legal");
|
||||
if (requireRenderable)
|
||||
testFailed("floating-point " + formatString + " render target not supported");
|
||||
else
|
||||
debug("floating-point " + formatString + " render target not supported -- this is legal");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ var gl = wtu.create3DContext(canvas);
|
|||
var halfFloatOESEnum = 0x8D61;
|
||||
var ext = null;
|
||||
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exists");
|
||||
} else {
|
||||
|
@ -157,8 +158,8 @@ if (!gl) {
|
|||
// Next check that values outside the 0-1 range can be written.
|
||||
var halfFloatTenK = 0x70E2; // Half float 10000
|
||||
var uint16Formats2 = [
|
||||
{ format: gl.RGBA, subtractor: [10000, 10000, 10000, 10000], },
|
||||
{ format: gl.RGB, subtractor: [10000, 10000, 10000, 1], },
|
||||
{ format: gl.RGBA, subtractor: [10000, 10000, 10000, 10000], requireRenderable: true},
|
||||
{ format: gl.RGB, subtractor: [10000, 10000, 10000, 1], requireRenderable: false},
|
||||
];
|
||||
|
||||
uint16Formats2.forEach(function(f) {
|
||||
|
@ -170,20 +171,47 @@ if (!gl) {
|
|||
for (var ii = 0; ii < uint16Data.length; ii++) {
|
||||
uint16Data[ii] = halfFloatTenK;
|
||||
}
|
||||
runRenderTest(format, f.subtractor, uint16Data);
|
||||
runRenderTest(format, f.subtractor, uint16Data, f.requireRenderable);
|
||||
});
|
||||
|
||||
// Check if attaching texture as FBO target succeeds (Not mandatory)
|
||||
runRenderTest(gl.RGBA, [10000, 10000, 10000, 10000], null);
|
||||
runRenderTest(gl.RGB, [10000, 10000, 10000, 1], null);
|
||||
|
||||
runFramebufferTest();
|
||||
(function() {
|
||||
debug("");
|
||||
var renderable = isRenderable(gl, ext);
|
||||
var renderableExtName = "EXT_color_buffer_half_float";
|
||||
var supported = gl.getSupportedExtensions().includes(renderableExtName);
|
||||
if (renderable && !supported) {
|
||||
testFailed("RGBA/HALF_FLOAT_OES is color renderable but " + renderableExtName + " not exposed");
|
||||
} else if (supported && !renderable) {
|
||||
testFailed(renderableExtName + " is exposed but RGBA/HALF_FLOAT_OES is not color renderable");
|
||||
}
|
||||
if (supported) {
|
||||
runRenderTest(gl.RGBA, [10000, 10000, 10000, 10000], null, true);
|
||||
runRenderTest(gl.RGB, [10000, 10000, 10000, 1], null, false);
|
||||
runFramebufferTest();
|
||||
}
|
||||
})();
|
||||
|
||||
// Check of getExtension() returns same object
|
||||
runUniqueObjectTest();
|
||||
}
|
||||
}
|
||||
|
||||
function isRenderable(gl, ext) {
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, ext.HALF_FLOAT_OES, null);
|
||||
|
||||
var fb = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
||||
|
||||
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
||||
gl.deleteFramebuffer(fb);
|
||||
gl.deleteTexture(tex);
|
||||
|
||||
return status == gl.FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
function getNumberOfChannels(format)
|
||||
{
|
||||
if (format == gl.RGBA)
|
||||
|
@ -278,7 +306,7 @@ function checkRenderingResults()
|
|||
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
|
||||
}
|
||||
|
||||
function runRenderTest(format, subtractor, data)
|
||||
function runRenderTest(format, subtractor, data, requireRenderable)
|
||||
{
|
||||
var formatString = wtu.glEnumToString(gl, format);
|
||||
|
||||
|
@ -307,7 +335,11 @@ function runRenderTest(format, subtractor, data)
|
|||
// It is legal for a WebGL implementation exposing the OES_texture_half_float extension to
|
||||
// support half floating point textures but not as attachments to framebuffer objects.
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
||||
debug("Half floating point render targets not supported -- this is legal");
|
||||
if (requireRenderable) {
|
||||
testFailed(formatString + " render targets not supported.");
|
||||
} else {
|
||||
debug(formatString + " render targets not supported -- this is legal");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -397,16 +429,12 @@ function runFramebufferTest() {
|
|||
|
||||
var texture = allocateTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, ext.HALF_FLOAT_OES, null);
|
||||
|
||||
var fbo = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
||||
debug("Half floating point render targets not supported -- this is legal");
|
||||
return;
|
||||
}
|
||||
debug("Ensure non-color-renderable formats [LUMINANCE, LUMINANCE_ALPHA, ALPHA] fail");
|
||||
|
||||
debug("Ensure non-color-renderable formats [LUMINANCE, LUMINANCE_ALPHA, ALPHA] fail.");
|
||||
var arrayBufferFloatOutput = new Float32Array(4); // 4 color channels
|
||||
[gl.LUMINANCE, gl.LUMINANCE_ALPHA, gl.ALPHA].forEach(function(badFormat) {
|
||||
debug(getFormatName(badFormat) + " framebuffer");
|
||||
|
@ -437,51 +465,49 @@ function runFramebufferTest() {
|
|||
debug("");
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, goodFormat, 1, 1, 0, goodFormat, ext.HALF_FLOAT_OES, arrayBufferHalfFloatInput);
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
|
||||
// To avoid GPU idiosyncrasies, dispense with clearing or rendering to the texture. Go straight to readPixels.
|
||||
|
||||
// Per the OES_color_buffer_half_float, RGBA/FLOAT should always succeed for readPixels
|
||||
verifyReadPixelsColors(
|
||||
0.00, // red
|
||||
0.25, // green
|
||||
0.50, // blue
|
||||
0.75, // alpha
|
||||
1.0, // alphaRGB
|
||||
goodFormat,
|
||||
gl.FLOAT,
|
||||
Float32Array);
|
||||
|
||||
var implementationColorReadFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
|
||||
assertMsg(implementationColorReadFormat === gl.RGBA || implementationColorReadFormat === gl.RGB,
|
||||
"IMPLEMENTATION_COLOR_READ_FORMAT should be color renderable: RGBA or RGB. Received: " + getFormatName(implementationColorReadFormat));
|
||||
|
||||
var implementationColorReadType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
|
||||
|
||||
// There is nothing in the specifications that keeps the
|
||||
// implementation color read format and type from being the
|
||||
// same as the implicitly supported one. For this reason, keep
|
||||
// gl.FLOAT as one of the valid options.
|
||||
assertMsg(implementationColorReadType === gl.UNSIGNED_BYTE ||
|
||||
implementationColorReadType === gl.FLOAT ||
|
||||
implementationColorReadType === ext.HALF_FLOAT_OES ||
|
||||
implementationColorReadType === gl.UNSIGNED_SHORT_4_4_4_4 ||
|
||||
implementationColorReadType === gl.UNSIGNED_SHORT_5_5_5_1 ||
|
||||
implementationColorReadType === gl.UNSIGNED_SHORT_5_6_5,
|
||||
"IMPLEMENTATION_COLOR_READ_TYPE must be one of UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_5_6_5, FLOAT, or HALF_FLOAT_OES. " +
|
||||
"Received: " + getTypeName(implementationColorReadType));
|
||||
|
||||
// Test the RGBA/HALF_FLOAT_OES combination
|
||||
if (implementationColorReadFormat === gl.RGBA && implementationColorReadType === ext.HALF_FLOAT_OES) {
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
|
||||
// Per the OES_color_buffer_half_float, RGBA/FLOAT should always succeed for readPixels
|
||||
verifyReadPixelsColors(
|
||||
0, // red
|
||||
0x3400, // green
|
||||
0x3800, // blue
|
||||
0x3A00, // alpha
|
||||
0x3C00, // alphaRGB
|
||||
0.00, // red
|
||||
0.25, // green
|
||||
0.50, // blue
|
||||
0.75, // alpha
|
||||
1.0, // alphaRGB
|
||||
goodFormat,
|
||||
ext.HALF_FLOAT_OES,
|
||||
Uint16Array);
|
||||
gl.FLOAT,
|
||||
Float32Array);
|
||||
|
||||
var implementationColorReadFormat = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT);
|
||||
assertMsg(implementationColorReadFormat === gl.RGBA || implementationColorReadFormat === gl.RGB,
|
||||
"IMPLEMENTATION_COLOR_READ_FORMAT should be color renderable: RGBA or RGB. Received: " + getFormatName(implementationColorReadFormat));
|
||||
|
||||
var implementationColorReadType = gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE);
|
||||
|
||||
// There is nothing in the specifications that keeps the
|
||||
// implementation color read format and type from being the
|
||||
// same as the implicitly supported one. For this reason, keep
|
||||
// gl.FLOAT as one of the valid options.
|
||||
assertMsg(implementationColorReadType === gl.UNSIGNED_BYTE ||
|
||||
implementationColorReadType === gl.FLOAT ||
|
||||
implementationColorReadType === ext.HALF_FLOAT_OES ||
|
||||
implementationColorReadType === gl.UNSIGNED_SHORT_4_4_4_4 ||
|
||||
implementationColorReadType === gl.UNSIGNED_SHORT_5_5_5_1 ||
|
||||
implementationColorReadType === gl.UNSIGNED_SHORT_5_6_5,
|
||||
"IMPLEMENTATION_COLOR_READ_TYPE must be one of UNSIGNED_BYTE, UNSIGNED_SHORT_4_4_4_4, UNSIGNED_SHORT_5_5_5_1, UNSIGNED_SHORT_5_6_5, FLOAT, or HALF_FLOAT_OES. " +
|
||||
"Received: " + getTypeName(implementationColorReadType));
|
||||
|
||||
// Test the RGBA/HALF_FLOAT_OES combination
|
||||
if (implementationColorReadFormat === gl.RGBA && implementationColorReadType === ext.HALF_FLOAT_OES) {
|
||||
verifyReadPixelsColors(
|
||||
0, // red
|
||||
0x3400, // green
|
||||
0x3800, // blue
|
||||
0x3A00, // alpha
|
||||
0x3C00, // alphaRGB
|
||||
goodFormat,
|
||||
ext.HALF_FLOAT_OES,
|
||||
Uint16Array);
|
||||
}
|
||||
}
|
||||
debug("");
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
|
@ -624,25 +624,33 @@ function runBoundDeleteTests() {
|
|||
gl.deleteBuffer(colorBuffer);
|
||||
gl.deleteBuffer(positionBuffer);
|
||||
|
||||
// The buffers should not be accessible at this point. Deleted objects that are bound
|
||||
// in the current context undergo an automatic unbinding
|
||||
// After the first iteration, deleteBuffer will be a no-op, and will not unbind its matching
|
||||
// bind points on the now-bound VAO like it did on the first iteration.
|
||||
var expectRetained = (ii != 0);
|
||||
var shouldBeStr = (expectRetained ? "retained" : "cleared");
|
||||
|
||||
var boundPositionBuffer = gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
|
||||
if(boundPositionBuffer == positionBuffer) {
|
||||
testFailed("Position buffer should be automatically unbound when deleted");
|
||||
if (expectRetained != (boundPositionBuffer == positionBuffer)) {
|
||||
testFailed("Position attrib stored buffer should be " + shouldBeStr + ".");
|
||||
}
|
||||
|
||||
var boundColorBuffer = gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
|
||||
if(boundColorBuffer == colorBuffer) {
|
||||
testFailed("Color buffer should be automatically unbound when deleted");
|
||||
if (expectRetained != (boundColorBuffer == colorBuffer)) {
|
||||
testFailed("Color attrib stored buffer should be " + shouldBeStr + ".");
|
||||
}
|
||||
|
||||
// If retained, everything should still work. If cleared, drawing should now fail.
|
||||
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "Draw call should fail with unbound position and color buffers");
|
||||
var expectedError = (expectRetained ? gl.NO_ERROR : gl.INVALID_OPERATION);
|
||||
wtu.glErrorShouldBe(gl, expectedError,
|
||||
"Draw call should " + (expectRetained ? "not " : "") + "fail.");
|
||||
|
||||
var isPositionBuffer = gl.isBuffer(positionBuffer);
|
||||
var isColorBuffer = gl.isBuffer(colorBuffer);
|
||||
|
||||
if(isPositionBuffer) testFailed("Position buffer should no longer exist after last ref removed");
|
||||
if(isColorBuffer) testFailed("Color buffer should no longer exist after last ref removed");
|
||||
if (!gl.isBuffer(positionBuffer)) {
|
||||
testFailed("References from unbound VAOs keep Position buffer alive.");
|
||||
}
|
||||
if (!gl.isBuffer(colorBuffer)) {
|
||||
testFailed("References from unbound VAOs keep Color buffer alive");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
|
@ -204,12 +204,8 @@ function runTestExtension() {
|
|||
}
|
||||
|
||||
supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
|
||||
// There should be exactly 3 formats for WebGL 1.0 and 13 formats for WebGL 2.0.
|
||||
if (contextVersion < 2) {
|
||||
shouldBe("supportedFormats.length", "3");
|
||||
} else {
|
||||
shouldBe("supportedFormats.length", "13");
|
||||
}
|
||||
// There should be exactly 3 formats for both WebGL 1.0 and WebGL 2.0.
|
||||
shouldBe("supportedFormats.length", "3");
|
||||
|
||||
// check that all 3 formats exist
|
||||
for (var name in validFormats.length) {
|
||||
|
|
|
@ -61,7 +61,8 @@ var COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
|
|||
var COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext(undefined, undefined);
|
||||
var contextVersion = wtu.getDefault3DContextVersion();
|
||||
var gl = wtu.create3DContext();
|
||||
var WEBGL_compressed_texture_etc;
|
||||
|
||||
var formats = null;
|
||||
|
@ -89,7 +90,7 @@ function runTest() {
|
|||
}
|
||||
} else {
|
||||
if (WEBGL_compressed_texture_etc !== null) {
|
||||
testFailed("WEBGL_compressed_texture_etc listed as supported but getExtension failed");
|
||||
testFailed("WEBGL_compressed_texture_etc listed as unsupported but getExtension succeeded");
|
||||
return;
|
||||
} else {
|
||||
testPassed("No WEBGL_compressed_texture_etc support -- this is legal");
|
||||
|
@ -138,10 +139,19 @@ function runTest() {
|
|||
shouldBe("formats.length", isPositive ? "10" : "0");
|
||||
|
||||
debug("");
|
||||
shouldThrow("gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_R11_EAC, 4, 4, 0, null)");
|
||||
shouldThrow("gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, COMPRESSED_R11_EAC, null)");
|
||||
shouldThrow("gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, COMPRESSED_R11_EAC, 4, 4, 4, 0, null)");
|
||||
shouldThrow("gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 0, COMPRESSED_R11_EAC, null)");
|
||||
if (contextVersion >= 2) {
|
||||
var expectedError = isPositive ? gl.INVALID_OPERATION: [gl.INVALID_ENUM, gl.INVALID_OPERATION];
|
||||
// `null` coerces into `0` for the PBO entrypoint, yielding INVALID_OP due to no PBO bound.
|
||||
wtu.shouldGenerateGLError(gl, expectedError, "gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_R11_EAC, 4, 4, 0, 0, null)");
|
||||
wtu.shouldGenerateGLError(gl, expectedError, "gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, COMPRESSED_R11_EAC, 0, null)");
|
||||
wtu.shouldGenerateGLError(gl, expectedError, "gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, COMPRESSED_R11_EAC, 4, 4, 4, 0, 0, null)");
|
||||
wtu.shouldGenerateGLError(gl, expectedError, "gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 0, COMPRESSED_R11_EAC, 0, null)");
|
||||
} else {
|
||||
shouldThrow("gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_R11_EAC, 4, 4, 0, null)");
|
||||
shouldThrow("gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, COMPRESSED_R11_EAC, null)");
|
||||
shouldThrow("gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, COMPRESSED_R11_EAC, 4, 4, 4, 0, null)");
|
||||
shouldThrow("gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 0, COMPRESSED_R11_EAC, null)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012-2016 The Khronos Group Inc.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/webgl-compressed-texture-size-limit.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="32" height="32" style="width: 40px; height: 40px;"></canvas>
|
||||
|
@ -42,202 +43,11 @@
|
|||
"use strict";
|
||||
enableJSTestPreVerboseLogging();
|
||||
description("Checks size limit of the webgl compressed textures")
|
||||
var canvas;
|
||||
|
||||
function numLevelsFromSize(size) {
|
||||
var levels = 0;
|
||||
while ((size >> levels) > 0) {
|
||||
++levels;
|
||||
}
|
||||
return levels;
|
||||
}
|
||||
|
||||
// More formats can be added here when more texture compression extensions are enabled in WebGL.
|
||||
var validFormats = {
|
||||
COMPRESSED_RGB_S3TC_DXT1_EXT : 0x83F0,
|
||||
COMPRESSED_RGBA_S3TC_DXT1_EXT : 0x83F1,
|
||||
COMPRESSED_RGBA_S3TC_DXT3_EXT : 0x83F2,
|
||||
COMPRESSED_RGBA_S3TC_DXT5_EXT : 0x83F3,
|
||||
};
|
||||
|
||||
// format specific restrictions for COMPRESSED_RGB_S3TC_DXT1_EXT and COMPRESSED_RGBA_S3TC_DXT1_EXT
|
||||
// on the byteLength of the ArrayBufferView, pixels
|
||||
function func1 (width, height)
|
||||
{
|
||||
return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8;
|
||||
}
|
||||
|
||||
// format specific restrictions for COMPRESSED_RGBA_S3TC_DXT3_EXT and COMPRESSED_RGBA_S3TC_DXT5_EXT
|
||||
// on the byteLength of the ArrayBufferView, pixels
|
||||
function func2 (width, height)
|
||||
{
|
||||
return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16;
|
||||
}
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("example");
|
||||
var tests = [
|
||||
// More tests can be added here when more texture compression extensions are enabled in WebGL.
|
||||
// Level 0 image width and height must be a multiple of the sizeStep.
|
||||
{ extension: "WEBGL_compressed_texture_s3tc", format: validFormats.COMPRESSED_RGB_S3TC_DXT1_EXT, dataType: Uint8Array, func: func1, sizeStep: 4},
|
||||
{ extension: "WEBGL_compressed_texture_s3tc", format: validFormats.COMPRESSED_RGBA_S3TC_DXT1_EXT, dataType: Uint8Array, func: func1, sizeStep: 4},
|
||||
{ extension: "WEBGL_compressed_texture_s3tc", format: validFormats.COMPRESSED_RGBA_S3TC_DXT3_EXT, dataType: Uint8Array, func: func2, sizeStep: 4},
|
||||
{ extension: "WEBGL_compressed_texture_s3tc", format: validFormats.COMPRESSED_RGBA_S3TC_DXT5_EXT, dataType: Uint8Array, func: func2, sizeStep: 4},
|
||||
];
|
||||
|
||||
// Note: We expressly only use 2 textures because first a texture will be defined
|
||||
// using all mip levels of 1 format, then for a moment it will have mixed formats which
|
||||
// may uncover bugs.
|
||||
var targets = [
|
||||
{ target: gl.TEXTURE_2D,
|
||||
maxSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
|
||||
tex: gl.createTexture(),
|
||||
targets: [gl.TEXTURE_2D]
|
||||
},
|
||||
{ target: gl.TEXTURE_CUBE_MAP,
|
||||
maxSize: gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE),
|
||||
tex: gl.createTexture(),
|
||||
targets: [
|
||||
gl.TEXTURE_CUBE_MAP_POSITIVE_X,
|
||||
gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
|
||||
gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
|
||||
gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
|
||||
gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
|
||||
gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
function getSharedArrayBufferSize() {
|
||||
var sharedArrayBufferSize = 0;
|
||||
for (var tt = 0; tt < tests.length; ++tt) {
|
||||
var test = tests[tt];
|
||||
for (var trg = 0; trg < targets.length; ++trg) {
|
||||
var t = targets[trg];
|
||||
var bufferSizeNeeded;
|
||||
if (t.target === gl.TEXTURE_CUBE_MAP) {
|
||||
var positiveTestSize = Math.min(2048, t.maxSize);
|
||||
bufferSizeNeeded = test.func(positiveTestSize, positiveTestSize);
|
||||
} else {
|
||||
bufferSizeNeeded = test.func(t.maxSize, test.sizeStep);
|
||||
}
|
||||
if (bufferSizeNeeded > sharedArrayBufferSize) {
|
||||
sharedArrayBufferSize = bufferSizeNeeded;
|
||||
}
|
||||
bufferSizeNeeded = test.func(t.maxSize + test.sizeStep, t.maxSize + test.sizeStep);
|
||||
// ArrayBuffers can be at most 4GB (minus 1 byte)
|
||||
if (bufferSizeNeeded > sharedArrayBufferSize && bufferSizeNeeded <= 4294967295) {
|
||||
sharedArrayBufferSize = bufferSizeNeeded;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sharedArrayBufferSize;
|
||||
}
|
||||
|
||||
// Share an ArrayBuffer among tests to avoid too many large allocations
|
||||
var sharedArrayBuffer = new ArrayBuffer(getSharedArrayBufferSize());
|
||||
|
||||
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
||||
|
||||
var trg = 0;
|
||||
var tt = 0;
|
||||
runNextTest();
|
||||
|
||||
function runNextTest() {
|
||||
var t = targets[trg];
|
||||
|
||||
if (tt == 0) {
|
||||
var tex = t.tex;
|
||||
gl.bindTexture(t.target, tex);
|
||||
|
||||
debug("");
|
||||
debug("max size for " + wtu.glEnumToString(gl, t.target) + ": " + t.maxSize);
|
||||
}
|
||||
|
||||
var test = tests[tt];
|
||||
testFormatType(t, test);
|
||||
++tt;
|
||||
if (tt == tests.length) {
|
||||
tt = 0;
|
||||
++trg;
|
||||
if (trg == targets.length) {
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
}
|
||||
wtu.waitForComposite(runNextTest);
|
||||
}
|
||||
|
||||
function testFormatType(t, test) {
|
||||
var positiveTestSize = t.maxSize;
|
||||
var positiveTestOtherDimension = test.sizeStep;
|
||||
if (t.target === gl.TEXTURE_CUBE_MAP) {
|
||||
// Can't always test the maximum size since that can cause OOM:
|
||||
positiveTestSize = Math.min(2048, t.maxSize);
|
||||
// Cube map textures need to be square:
|
||||
positiveTestOtherDimension = positiveTestSize;
|
||||
}
|
||||
var positiveTestLevels = numLevelsFromSize(positiveTestSize);
|
||||
var numLevels = numLevelsFromSize(t.maxSize);
|
||||
debug("");
|
||||
debug("num levels: " + numLevels + ", levels used in positive test: " + positiveTestLevels);
|
||||
|
||||
debug("");
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
var ext = wtu.getExtensionWithKnownPrefixes(gl, test.extension);
|
||||
if (ext) {
|
||||
|
||||
testPassed("Successfully enabled " + test.extension + " extension");
|
||||
|
||||
for (var j = 0; j < t.targets.length; ++j) {
|
||||
var target = t.targets[j];
|
||||
debug("");
|
||||
debug(wtu.glEnumToString(gl, target));
|
||||
|
||||
// positive test
|
||||
var size = positiveTestSize;
|
||||
var otherDimension = positiveTestOtherDimension;
|
||||
for (var i = 0; i < positiveTestLevels; i++) {
|
||||
var pixels = new test.dataType(sharedArrayBuffer, 0, test.func(size, otherDimension));
|
||||
gl.compressedTexImage2D(target, i, test.format, size, otherDimension, 0, pixels);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "uploading compressed texture should generate NO_ERROR."
|
||||
+ "level is " + i + ", size is " + size + "x" + otherDimension);
|
||||
size /= 2;
|
||||
otherDimension /= 2;
|
||||
if (otherDimension < 1) {
|
||||
otherDimension = 1;
|
||||
}
|
||||
}
|
||||
|
||||
var numLevels = numLevelsFromSize(t.maxSize);
|
||||
|
||||
// out of bounds tests
|
||||
// width and height out of bounds
|
||||
var dataSize = test.func(t.maxSize + test.sizeStep, t.maxSize + test.sizeStep);
|
||||
// this check assumes that each element is 1 byte
|
||||
if (dataSize > sharedArrayBuffer.byteLength) {
|
||||
testPassed("Unable to test texture larger than maximum size due to ArrayBuffer size limitations -- this is legal");
|
||||
} else {
|
||||
var pixelsNegativeTest1 = new test.dataType(sharedArrayBuffer, 0, dataSize);
|
||||
gl.compressedTexImage2D(target, 0, test.format, t.maxSize + test.sizeStep, t.maxSize + test.sizeStep, 0, pixelsNegativeTest1);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "width or height out of bounds: should generate INVALID_VALUE."
|
||||
+ " level is 0, size is " + (t.maxSize + test.sizeStep) + "x" + (t.maxSize + test.sizeStep));
|
||||
}
|
||||
// level out of bounds
|
||||
var pixelsNegativeTest2 = new test.dataType(sharedArrayBuffer, 0, test.func(256, 256));
|
||||
gl.compressedTexImage2D(target, numLevels, test.format, 256, 256, 0, pixelsNegativeTest2);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "level out of bounds: should generate INVALID_VALUE."
|
||||
+ " level is " + numLevels + ", size is 256x256");
|
||||
//width and height out of bounds for specified level
|
||||
gl.compressedTexImage2D(target, numLevels - 1, test.format, 256, 256, 0, pixelsNegativeTest2);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, "width or height out of bounds for specified level: should generate INVALID_VALUE."
|
||||
+ " level is " + (numLevels - 1) + ", size is 256x256");
|
||||
}
|
||||
}
|
||||
else
|
||||
testPassed("No " + test.extension + " extension support -- this is legal");
|
||||
}
|
||||
// ArrayBuffers can be at most 4GB (minus 1 byte), but any allocations larger than 1 GB are unreliable in practice. So limit allocations to 1 GB.
|
||||
// Textures that are wide in just one dimension can still be used to test max TEXTURE_2D size limit even if we can't allocate space for huge square textures.
|
||||
// Use a fairly conservative limit for positive test cube map size so OOM is avoided.
|
||||
runCompressedTextureSizeLimitTest(Math.pow(2, 30), 2048);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2012 The Khronos Group Inc.
|
||||
|
|
|
@ -89,7 +89,8 @@ if (!gl) {
|
|||
testPassed("Successfully enabled WEBGL_depth_texture extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
runTestExtension();
|
||||
runTestExtension(true);
|
||||
runTestExtension(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,8 +139,8 @@ function dumpIt(gl, res, msg) {
|
|||
debug(strs.join(" "));
|
||||
}
|
||||
}
|
||||
function runTestExtension() {
|
||||
debug("Testing WEBGL_depth_texture");
|
||||
function runTestExtension(unpackFlipY) {
|
||||
debug("Testing WEBGL_depth_texture. UNPACK_FLIP_Y_WEBGL: " + unpackFlipY);
|
||||
|
||||
var res = 8;
|
||||
|
||||
|
@ -171,6 +172,8 @@ function runTestExtension() {
|
|||
gl.enableVertexAttribArray(0);
|
||||
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
||||
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, unpackFlipY);
|
||||
|
||||
var types = [
|
||||
{obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMPONENT', type: 'UNSIGNED_SHORT', data: 'new Uint16Array(1)', depthBits: "16"},
|
||||
{obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMPONENT', type: 'UNSIGNED_INT', data: 'new Uint32Array(1)', depthBits: "16"},
|
||||
|
@ -197,7 +200,7 @@ function runTestExtension() {
|
|||
'TEXTURE_CUBE_MAP_NEGATIVE_Z'
|
||||
];
|
||||
for (var tt = 0; tt < targets.length; ++tt) {
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.' + targets[ii] + ', 1, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + typeStr + ', null)');
|
||||
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, 'gl.texImage2D(gl.' + targets[ii] + ', 0, gl.' + typeInfo.format + ', 1, 1, 0, gl.' + typeInfo.format + ', ' + typeStr + ', null)');
|
||||
}
|
||||
|
||||
// The WebGL_depth_texture extension supports both NEAREST and
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL WEBGL_draw_buffers Conformance Tests</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/webgl-draw-buffers-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" width="64" height="64"> </canvas>
|
||||
<div id="console"></div>
|
||||
<script id="fshaderRedWithReturn" type="x-shader/x-fragment">
|
||||
#extension GL_EXT_draw_buffers : require
|
||||
precision mediump float;
|
||||
uniform float u_zero;
|
||||
void main() {
|
||||
gl_FragColor = vec4(1,0,0,1);
|
||||
if (u_zero < 1.0) {
|
||||
return;
|
||||
}
|
||||
gl_FragColor = vec4(0,0,1,1);
|
||||
}
|
||||
</script>
|
||||
<script id="fshaderWithDiscard" type="x-shader/x-fragment">
|
||||
#extension GL_EXT_draw_buffers : require
|
||||
precision mediump float;
|
||||
uniform float u_zero;
|
||||
void main() {
|
||||
gl_FragColor = vec4(1,0,0,1);
|
||||
if (u_zero < 1.0) {
|
||||
discard;
|
||||
}
|
||||
gl_FragColor = vec4(0,0,1,1);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
description("This test verifies gl_FragColor being broadcasted when using WEBGL_draw_buffers extension, if it is available.");
|
||||
|
||||
debug("");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
var drawBuffersUtils;
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = gl.getExtension("WEBGL_draw_buffers");
|
||||
if (!ext) {
|
||||
testPassed("No WEBGL_draw_buffers support -- this is legal");
|
||||
} else {
|
||||
testPassed("Successfully enabled WEBGL_draw_buffers extension");
|
||||
drawBuffersUtils = WebGLDrawBuffersUtils(gl, ext);
|
||||
runDrawTests();
|
||||
}
|
||||
}
|
||||
|
||||
function runDrawTests() {
|
||||
debug("");
|
||||
var fb = gl.createFramebuffer();
|
||||
|
||||
var maxUsable = drawBuffersUtils.getMaxUsableColorAttachments();
|
||||
var bufs = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
|
||||
|
||||
var width = 64;
|
||||
var height = 64;
|
||||
var attachments = [];
|
||||
for (var ii = 0; ii < maxUsable; ++ii) {
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + ii, gl.TEXTURE_2D, tex, 0);
|
||||
attachments.push({
|
||||
texture: tex
|
||||
});
|
||||
}
|
||||
|
||||
debug("test that gl_FragColor broadcasts if extension is enabled in fragment shader and fragment shader main returns in the middle");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
ext.drawBuffersWEBGL(bufs);
|
||||
var redProgramWithReturn = wtu.setupProgram(gl, [wtu.simpleVertexShader, "fshaderRedWithReturn"], ["vPosition"], undefined, true);
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.useProgram(redProgramWithReturn);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after draw");
|
||||
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
|
||||
|
||||
debug("test that none of the attachments are written in case the fragment shader discards");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
ext.drawBuffersWEBGL(bufs);
|
||||
var programWithDiscard = wtu.setupProgram(gl, [wtu.simpleVertexShader, "fshaderWithDiscard"], ["vPosition"], undefined, true);
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.useProgram(programWithDiscard);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after draw");
|
||||
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 0, 0, 0]);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
gl.deleteFramebuffer(fb);
|
||||
attachments.forEach(function(attachment) {
|
||||
gl.deleteTexture(attachment.texture);
|
||||
});
|
||||
gl.deleteProgram(redProgramWithReturn);
|
||||
gl.deleteProgram(programWithDiscard);
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,161 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2016 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>WebGL Rendering and Sampling Feedback Loop Tests For WEBGL_draw_buffers Extension</title>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="example" width="8" height="8"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 aPosition;
|
||||
attribute vec2 aTexCoord;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
gl_Position = aPosition;
|
||||
texCoord = aTexCoord;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
#extension GL_EXT_draw_buffers : require
|
||||
precision mediump float;
|
||||
uniform sampler2D tex;
|
||||
varying vec2 texCoord;
|
||||
void main() {
|
||||
gl_FragData[0] = texture2D(tex, texCoord);
|
||||
gl_FragData[1] = texture2D(tex, texCoord);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("example");
|
||||
description("This test verifies the functionality of rendering to the same texture where it samples from.");
|
||||
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
|
||||
var width = 8;
|
||||
var height = 8;
|
||||
var tex0;
|
||||
var tex1;
|
||||
var fbo;
|
||||
var ext;
|
||||
var program;
|
||||
var positionLoc;
|
||||
var texCoordLoc;
|
||||
|
||||
if (!gl) {
|
||||
testFailed("WebGL context does not exist");
|
||||
} else {
|
||||
testPassed("WebGL context exists");
|
||||
|
||||
ext = gl.getExtension("WEBGL_draw_buffers");
|
||||
if (!ext) {
|
||||
testPassed("No WEBGL_draw_buffers support -- this is legal");
|
||||
|
||||
finishTest();
|
||||
} else {
|
||||
testPassed("Successfully enabled WEBGL_draw_buffers extension");
|
||||
|
||||
init();
|
||||
|
||||
// The sampling texture is bound to COLOR_ATTACHMENT1 during resource allocation
|
||||
allocate_resource();
|
||||
|
||||
rendering_sampling_feedback_loop([gl.NONE, ext.COLOR_ATTACHMENT1_WEBGL], gl.INVALID_OPERATION);
|
||||
rendering_sampling_feedback_loop([gl.COLOR_ATTACHMENT0, ext.COLOR_ATTACHMENT1_WEBGL], gl.INVALID_OPERATION);
|
||||
rendering_sampling_feedback_loop([gl.COLOR_ATTACHMENT0, gl.NONE], gl.NO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['aPosition', 'aTexCoord'], [0, 1]);
|
||||
positionLoc = gl.getAttribLocation(program, "aPosition");
|
||||
texCoordLoc = gl.getAttribLocation(program, "aTexCoord");
|
||||
if (!program || positionLoc < 0 || texCoordLoc < 0) {
|
||||
testFailed("Set up program failed");
|
||||
return;
|
||||
}
|
||||
testPassed("Set up program succeeded");
|
||||
|
||||
wtu.setupUnitQuad(gl, 0, 1);
|
||||
gl.viewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
function allocate_resource() {
|
||||
tex0 = gl.createTexture();
|
||||
tex1 = gl.createTexture();
|
||||
fbo = gl.createFramebuffer();
|
||||
wtu.fillTexture(gl, tex0, width, height, [0xff, 0x0, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
|
||||
wtu.fillTexture(gl, tex1, width, height, [0x0, 0xff, 0x0, 0xff], 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.RGBA);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex1);
|
||||
var texLoc = gl.getUniformLocation(program, "tex");
|
||||
gl.uniform1i(texLoc, 0);
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex0, 0);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, ext.COLOR_ATTACHMENT1_WEBGL, gl.TEXTURE_2D, tex1, 0);
|
||||
}
|
||||
|
||||
function rendering_sampling_feedback_loop(draw_buffers, error) {
|
||||
// gl.drawBuffers(draw_buffers);
|
||||
ext.drawBuffersWEBGL(draw_buffers);
|
||||
|
||||
// Make sure framebuffer is complete before feedback loop detection
|
||||
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
||||
testFailed("Framebuffer incomplete.");
|
||||
return;
|
||||
}
|
||||
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.glErrorShouldBe(gl, error, "Rendering to a texture where it samples from should geneates INVALID_OPERATION. Otherwise, it should be NO_ERROR");
|
||||
}
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
gl.deleteTexture(tex0);
|
||||
gl.deleteTexture(tex1);
|
||||
gl.deleteFramebuffer(fbo);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../js/js-test-post.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2015 The Khronos Group Inc.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013 The Khronos Group Inc.
|
||||
|
@ -33,17 +33,12 @@
|
|||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../js/js-test-pre.js"></script>
|
||||
<script src="../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../js/tests/webgl-draw-buffers-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<canvas id="canvas" width="64" height="64"> </canvas>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 a_position;
|
||||
void main() {
|
||||
gl_Position = a_position;
|
||||
}
|
||||
</script>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
#extension GL_EXT_draw_buffers : require
|
||||
precision mediump float;
|
||||
|
@ -111,10 +106,10 @@ debug("");
|
|||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("canvas");
|
||||
var output = document.getElementById("console");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
var ext = null;
|
||||
var programWithMaxDrawBuffersEqualOne = null;
|
||||
var drawBuffersUtils;
|
||||
|
||||
var extensionConstants = [
|
||||
{ name: "MAX_COLOR_ATTACHMENTS_WEBGL", enum: 0x8CDF, expectedFn: function(v) { return v >= 4; }, passMsg: " should be >= 4"},
|
||||
|
@ -177,6 +172,7 @@ if (!gl) {
|
|||
} else {
|
||||
testPassed("Successfully enabled WEBGL_draw_buffers extension");
|
||||
|
||||
drawBuffersUtils = WebGLDrawBuffersUtils(gl, ext);
|
||||
runSupportedTest(true);
|
||||
runEnumTestEnabled();
|
||||
runShadersTestEnabled();
|
||||
|
@ -189,7 +185,7 @@ if (!gl) {
|
|||
function createExtDrawBuffersProgram(scriptId, sub) {
|
||||
var fsource = wtu.getScript(scriptId);
|
||||
fsource = wtu.replaceParams(fsource, sub);
|
||||
return wtu.setupProgram(gl, ["vshader", fsource], ["a_position"], undefined, true);
|
||||
return wtu.setupProgram(gl, [wtu.simpleVertexShader, fsource], ["vPosition"], undefined, true);
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
|
@ -254,8 +250,8 @@ function runEnumTestEnabled() {
|
|||
|
||||
function testShaders(tests, sub) {
|
||||
tests.forEach(function(test) {
|
||||
var shaders = [wtu.getScript(test.shaders[0]), wtu.replaceParams(wtu.getScript(test.shaders[1]), sub)];
|
||||
var program = wtu.setupProgram(gl, shaders, ["a_position"], undefined, true);
|
||||
var shaders = [wtu.simpleVertexShader, wtu.replaceParams(wtu.getScript(test.fragmentShaderTemplate), sub)];
|
||||
var program = wtu.setupProgram(gl, shaders, ["vPosition"], undefined, true);
|
||||
var programLinkedSuccessfully = (program != null);
|
||||
var expectedProgramToLinkSuccessfully = (test.expectFailure == true);
|
||||
expectTrue(programLinkedSuccessfully != expectedProgramToLinkSuccessfully, test.msg);
|
||||
|
@ -269,10 +265,10 @@ function runShadersTestDisabled() {
|
|||
|
||||
var sub = {numDrawingBuffers: 1};
|
||||
testShaders([
|
||||
{ shaders: ["vshader", "fshaderMacroDisabled"],
|
||||
{ fragmentShaderTemplate: "fshaderMacroDisabled",
|
||||
msg: "GL_EXT_draw_buffers should not be defined in GLSL",
|
||||
},
|
||||
{ shaders: ["vshader", "fshader"],
|
||||
{ fragmentShaderTemplate: "fshader",
|
||||
msg: "#extension GL_EXT_draw_buffers should not be allowed in GLSL",
|
||||
expectFailure: true,
|
||||
},
|
||||
|
@ -291,11 +287,11 @@ function runShadersTestEnabled() {
|
|||
|
||||
var sub = {numDrawingBuffers: gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL)};
|
||||
testShaders([
|
||||
{ shaders: ["vshader", "fshaderMacroEnabled"],
|
||||
msg: "GL_EXT_draw_buffers should be defined as 1 in GLSL",
|
||||
{ fragmentShaderTemplate: "fshaderMacroEnabled",
|
||||
msg: "GL_EXT_draw_buffers should be defined as 1 in GLSL",
|
||||
},
|
||||
{ shaders: ["vshader", "fshader"],
|
||||
msg: "fragment shader containing the #extension directive should compile",
|
||||
{ fragmentShaderTemplate: "fshader",
|
||||
msg: "fragment shader containing the #extension directive should compile",
|
||||
},
|
||||
], sub);
|
||||
|
||||
|
@ -337,14 +333,6 @@ function makeArray(size, value) {
|
|||
return array;
|
||||
}
|
||||
|
||||
function makeColorAttachmentArray(size) {
|
||||
var array = []
|
||||
for (var ii = 0; ii < size; ++ii) {
|
||||
array.push(gl.COLOR_ATTACHMENT0 + ii);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
function runAttachmentTestEnabled() {
|
||||
debug("");
|
||||
debug("test attachment enabled");
|
||||
|
@ -362,7 +350,7 @@ function runAttachmentTestEnabled() {
|
|||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to attach to the max attachment point: gl.COLOR_ATTACHMENT0 + " + (maxColorAttachments - 1));
|
||||
ext.drawBuffersWEBGL(makeArray(maxDrawingBuffers, gl.NONE));
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffersWEBGL with array NONE of size " + maxColorAttachments);
|
||||
var bufs = makeColorAttachmentArray(maxDrawingBuffers);
|
||||
var bufs = drawBuffersUtils.makeColorAttachmentArray(maxDrawingBuffers);
|
||||
ext.drawBuffersWEBGL(bufs);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffersWEBGL with array attachments of size " + maxColorAttachments);
|
||||
bufs[0] = gl.NONE;
|
||||
|
@ -373,7 +361,7 @@ function runAttachmentTestEnabled() {
|
|||
bufs[1] = ext.COLOR_ATTACHMENT0_WEBGL;
|
||||
ext.drawBuffersWEBGL(bufs);
|
||||
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be able to call drawBuffersWEBGL with out of order attachments of size " + maxColorAttachments);
|
||||
var bufs = makeColorAttachmentArray(Math.floor(maxDrawingBuffers / 2));
|
||||
var bufs = drawBuffersUtils.makeColorAttachmentArray(Math.floor(maxDrawingBuffers / 2));
|
||||
ext.drawBuffersWEBGL(bufs);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffersWEBGL with short array of attachments of size " + bufs.length);
|
||||
}
|
||||
|
@ -417,11 +405,9 @@ function runDrawTests() {
|
|||
var middleFB = gl.createFramebuffer();
|
||||
|
||||
var maxDrawingBuffers = gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL);
|
||||
var maxColorAttachments = gl.getParameter(ext.MAX_COLOR_ATTACHMENTS_WEBGL);
|
||||
var maxUniformVectors = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);
|
||||
var maxUsable = Math.min(maxDrawingBuffers, maxColorAttachments, maxUniformVectors);
|
||||
var maxUsable = drawBuffersUtils.getMaxUsableColorAttachments();
|
||||
var half = Math.floor(maxUsable / 2);
|
||||
var bufs = makeColorAttachmentArray(maxUsable);
|
||||
var bufs = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
|
||||
var nones = makeArray(maxUsable, gl.NONE);
|
||||
|
||||
[fb, fb2, halfFB1, halfFB2, endsFB, middleFB].forEach(function(fbo) {
|
||||
|
@ -430,8 +416,8 @@ function runDrawTests() {
|
|||
});
|
||||
|
||||
var checkProgram = wtu.setupTexturedQuad(gl);
|
||||
var redProgram = wtu.setupProgram(gl, ["vshader", "fshaderRed"], ["a_position"]);
|
||||
var redProgramWithExtension = wtu.setupProgram(gl, ["vshader", "fshaderRedWithExtension"], ["a_position"]);
|
||||
var redProgram = wtu.setupProgram(gl, [wtu.simpleVertexShader, "fshaderRed"], ["vPosition"]);
|
||||
var redProgramWithExtension = wtu.setupProgram(gl, [wtu.simpleVertexShader, "fshaderRedWithExtension"], ["vPosition"]);
|
||||
var drawProgram = createExtDrawBuffersProgram("fshader", {numDrawingBuffers: maxDrawingBuffers});
|
||||
var width = 64;
|
||||
var height = 64;
|
||||
|
@ -464,7 +450,6 @@ function runDrawTests() {
|
|||
gl.uniform4fv(location, floatColor);
|
||||
attachments.push({
|
||||
texture: tex,
|
||||
location: location,
|
||||
color: color
|
||||
});
|
||||
}
|
||||
|
@ -473,30 +458,6 @@ function runDrawTests() {
|
|||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
|
||||
var checkAttachmentsForColorFn = function(attachments, colorFn) {
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
gl.useProgram(checkProgram);
|
||||
attachments.forEach(function(attachment, index) {
|
||||
gl.bindTexture(gl.TEXTURE_2D, attachment.texture);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
var expectedColor = colorFn(attachment, index);
|
||||
var tolerance = 0;
|
||||
expectedColor.forEach(function(v) {
|
||||
if (v != 0 && v != 255) {
|
||||
tolerance = 8;
|
||||
}
|
||||
});
|
||||
wtu.checkCanvas(gl, expectedColor, "attachment " + index + " should be " + expectedColor.toString(), tolerance);
|
||||
});
|
||||
debug("");
|
||||
};
|
||||
|
||||
var checkAttachmentsForColor = function(attachments, color) {
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return color || attachment.color;
|
||||
});
|
||||
};
|
||||
|
||||
var drawAndCheckAttachments = function(testFB, msg, testFn) {
|
||||
debug("test clearing " + msg);
|
||||
|
||||
|
@ -517,7 +478,7 @@ function runDrawTests() {
|
|||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
//checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
//drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
// return [0, 0, 0, 0];
|
||||
//});
|
||||
//debug("--");
|
||||
|
@ -527,7 +488,7 @@ function runDrawTests() {
|
|||
|
||||
gl.clearColor(0, 1, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return testFn(attachment, index) ? [0, 255, 0, 255] : [0, 0, 0, 0];
|
||||
});
|
||||
|
||||
|
@ -538,7 +499,7 @@ function runDrawTests() {
|
|||
gl.bindFramebuffer(gl.FRAMEBUFFER, testFB);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return testFn(attachment, index) ? attachment.color : [0, 0, 0, 0];
|
||||
});
|
||||
};
|
||||
|
@ -553,17 +514,17 @@ function runDrawTests() {
|
|||
|
||||
debug("test that each texture got the correct color.");
|
||||
|
||||
checkAttachmentsForColor(attachments);
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments);
|
||||
|
||||
debug("test clearing clears all the textures");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
gl.clearColor(0, 1, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
|
||||
|
||||
debug("test a fragment shader writing to neither gl_FragColor nor gl_FragData does not touch attachments");
|
||||
var noWriteProgram = wtu.setupProgram(gl, ["vshader", "fshaderNoWrite"], ["a_position"]);
|
||||
var noWriteProgram = wtu.setupProgram(gl, [wtu.simpleVertexShader, "fshaderNoWrite"], ["vPosition"]);
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no GL error setting up the program");
|
||||
if (!noWriteProgram) {
|
||||
testFailed("Setup a program where fragment shader writes nothing failed");
|
||||
|
@ -571,7 +532,7 @@ function runDrawTests() {
|
|||
gl.useProgram(noWriteProgram);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
|
||||
gl.deleteProgram(noWriteProgram);
|
||||
}
|
||||
|
||||
|
@ -581,7 +542,7 @@ function runDrawTests() {
|
|||
gl.useProgram(redProgram);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
|
||||
checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
|
||||
|
||||
debug("test that gl_FragColor does not broadcast unless extension is enabled in fragment shader");
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
|
@ -589,7 +550,7 @@ function runDrawTests() {
|
|||
gl.useProgram(redProgram);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return (index == 0) ? [255, 0, 0, 255] : [0, 255, 0, 255];
|
||||
});
|
||||
|
||||
|
@ -600,17 +561,17 @@ function runDrawTests() {
|
|||
gl.useProgram(redProgramWithExtension);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
|
||||
|
||||
if (maxUsable > 1) {
|
||||
// First half of color buffers disable.
|
||||
var bufs1 = makeColorAttachmentArray(maxUsable);
|
||||
var bufs1 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
|
||||
// Second half of color buffers disable.
|
||||
var bufs2 = makeColorAttachmentArray(maxUsable);
|
||||
var bufs2 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
|
||||
// Color buffers with even indices disabled.
|
||||
var bufs3 = makeColorAttachmentArray(maxUsable);
|
||||
var bufs3 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
|
||||
// Color buffers with odd indices disabled.
|
||||
var bufs4 = makeColorAttachmentArray(maxUsable);
|
||||
var bufs4 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
|
||||
for (var ii = 0; ii < maxUsable; ++ii) {
|
||||
if (ii < half) {
|
||||
bufs1[ii] = gl.NONE;
|
||||
|
@ -637,7 +598,7 @@ function runDrawTests() {
|
|||
gl.clearColor(0, 1, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return index < half ? [255, 0, 0, 255] : [0, 255, 0, 255];
|
||||
});
|
||||
|
||||
|
@ -647,7 +608,7 @@ function runDrawTests() {
|
|||
gl.useProgram(drawProgram);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return index < half ? [255, 0, 0, 255] : attachment.color;
|
||||
});
|
||||
|
||||
|
@ -661,7 +622,7 @@ function runDrawTests() {
|
|||
ext.drawBuffersWEBGL(bufs2);
|
||||
gl.clearColor(0, 0, 1, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return index < half ? [0, 0, 255, 255] : [255, 0, 0, 255];
|
||||
});
|
||||
|
||||
|
@ -671,7 +632,7 @@ function runDrawTests() {
|
|||
gl.useProgram(drawProgram);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return index < half ? attachment.color : [255, 0, 0, 255];
|
||||
});
|
||||
|
||||
|
@ -685,7 +646,7 @@ function runDrawTests() {
|
|||
gl.clearColor(1, 0, 1, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return (index % 2) ? [255, 0, 0, 255] : [255, 0, 255, 255];
|
||||
});
|
||||
|
||||
|
@ -699,7 +660,7 @@ function runDrawTests() {
|
|||
ext.drawBuffersWEBGL(bufs4);
|
||||
wtu.drawUnitQuad(gl);
|
||||
|
||||
checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
|
||||
return (index % 2 == 0) ? [0, 0, 0, 255] : attachment.color;
|
||||
});
|
||||
|
||||
|
@ -747,18 +708,18 @@ function runDrawTests() {
|
|||
ext.drawBuffersWEBGL(bufs);
|
||||
gl.clearColor(1, 0, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
|
||||
|
||||
// fb2 still has the NONE draw buffers from before, so this draw should be a no-op.
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
|
||||
gl.useProgram(drawProgram);
|
||||
wtu.drawUnitQuad(gl);
|
||||
checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
||||
gl.useProgram(drawProgram);
|
||||
wtu.drawUnitQuad(gl);
|
||||
checkAttachmentsForColor(attachments);
|
||||
drawBuffersUtils.checkAttachmentsForColor(attachments);
|
||||
|
||||
debug("test queries");
|
||||
debug("check framebuffer with all attachments on");
|
||||
|
|
|
@ -5,6 +5,7 @@ implicit/00_test_list.txt
|
|||
--min-version 1.0.2 literals/00_test_list.txt
|
||||
--min-version 1.0.2 matrices/00_test_list.txt
|
||||
misc/00_test_list.txt
|
||||
--min-version 1.0.4 preprocessor/00_test_list.txt
|
||||
reserved/00_test_list.txt
|
||||
--min-version 1.0.2 samplers/00_test_list.txt
|
||||
variables/00_test_list.txt
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
--min-version 1.0.3 angle-d3d11-compiler-error.html
|
||||
--min-version 1.0.3 angle-dx-variable-bug.html
|
||||
--min-version 1.0.3 array-of-struct-with-int-first-position.html
|
||||
--min-version 1.0.4 assign-to-swizzled-twice-in-function.html
|
||||
--min-version 1.0.4 bool-type-cast-bug-int-float.html
|
||||
--min-version 1.0.3 compare-loop-index-to-uniform.html
|
||||
--min-version 1.0.3 complex-glsl-does-not-crash.html
|
||||
--min-version 1.0.4 compound-assignment-type-combination.html
|
||||
--min-version 1.0.3 conditional-discard-in-loop.html
|
||||
--min-version 1.0.3 conditional-discard-optimization.html
|
||||
--min-version 1.0.4 conditional-texture-fetch.html
|
||||
--min-version 1.0.3 constant-precision-qualifier.html
|
||||
--min-version 1.0.3 --max-version 1.99 essl3-shaders-with-webgl1.html
|
||||
--min-version 1.0.4 floor-div-cos-should-not-truncate.html
|
||||
|
@ -16,7 +18,10 @@
|
|||
--min-version 1.0.3 fragcoord-linking-bug.html
|
||||
--min-version 1.0.4 gl-fragcoord-multisampling-bug.html
|
||||
--min-version 1.0.4 global-invariant-does-not-leak-across-shaders.html
|
||||
--min-version 1.0.4 if-return-and-elseif.html
|
||||
--min-version 1.0.4 init-array-with-loop.html
|
||||
--min-version 1.0.4 invariant-does-not-leak-across-shaders.html
|
||||
--min-version 1.0.4 in-parameter-passed-as-inout-argument-and-global.html
|
||||
--min-version 1.0.4 logic-inside-block-without-braces.html
|
||||
--min-version 1.0.3 long-expressions-should-not-crash.html
|
||||
--min-version 1.0.4 loop-if-loop-gradient.html
|
||||
|
@ -29,11 +34,16 @@
|
|||
--min-version 1.0.4 pow-with-constant-exponent-should-not-crash.html
|
||||
--min-version 1.0.4 qualcomm-crash.html
|
||||
--min-version 1.0.4 qualcomm-loop-with-continue-crash.html
|
||||
--min-version 1.0.4 sampler-array-struct-function-arg.html
|
||||
--min-version 1.0.3 sampler-array-using-loop-index.html
|
||||
--min-version 1.0.4 sampler-struct-function-arg.html
|
||||
--min-version 1.0.4 sequence-operator-evaluation-order.html
|
||||
--min-version 1.0.4 sketchfab-lighting-shader-crash.html
|
||||
--min-version 1.0.4 struct-constructor-highp-bug.html
|
||||
--min-version 1.0.3 temp-expressions-should-not-crash.html
|
||||
--min-version 1.0.4 unary-minus-operator-float-bug.html
|
||||
--min-version 1.0.4 undefined-index-should-not-crash.html
|
||||
--min-version 1.0.3 uniforms-should-not-lose-values.html
|
||||
--min-version 1.0.4 varying-arrays-should-not-be-reversed.html
|
||||
--min-version 1.0.4 vector-scalar-arithmetic-inside-loop.html
|
||||
--min-version 1.0.4 vector-scalar-arithmetic-inside-loop-complex.html
|
|
@ -53,6 +53,22 @@ void main()
|
|||
gl_FragColor = foo(uv) + foo(um);
|
||||
}
|
||||
</script>
|
||||
<script id="fshaderAmbiguousHLSLStructFunctionCall" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform float u_zero;
|
||||
struct S { float foo; };
|
||||
struct S2 { float foo; };
|
||||
float get(S s) { return s.foo + u_zero; }
|
||||
float get(S2 s2) { return 0.25 + s2.foo + u_zero; }
|
||||
void main()
|
||||
{
|
||||
S s;
|
||||
s.foo = 0.5;
|
||||
S2 s2;
|
||||
s2.foo = 0.25;
|
||||
gl_FragColor = vec4(0.0, get(s) + get(s2), 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
description("Test overloaded functions with vec4 and mat2 parameters that have had issues in ANGLE. Issues were due to HLSL compiler treating float4 and float2x2 as the same type when resolving which overloaded function to call.");
|
||||
|
@ -62,7 +78,14 @@ GLSLConformanceTester.runTests([
|
|||
fShaderId: 'fshaderAmbiguousHLSLFunctionCall',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Disambiguate correctly between overloaded function calls"
|
||||
passMsg: "Disambiguate correctly between overloaded function calls with 4-component float parameters"
|
||||
},
|
||||
{
|
||||
fShaderId: 'fshaderAmbiguousHLSLStructFunctionCall',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Disambiguate correctly between overloaded function calls with struct parameters",
|
||||
render: true
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Assigning an assignment to a swizzled value inside function</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
vec2 f()
|
||||
{
|
||||
vec2 r = vec2(0);
|
||||
r.x = r.y = 1.0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor.ga = f();
|
||||
}
|
||||
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
description();
|
||||
|
||||
// Minimal test case based on report at http://crbug.com/798117
|
||||
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fshader',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Assigning an assignment to a swizzled value inside a user-defined function"
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -33,18 +33,11 @@
|
|||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="256" height="256"> </canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec3 aPosition;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aPosition, 1);
|
||||
}
|
||||
</script>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform int uCount;
|
||||
|
@ -62,25 +55,16 @@ void main() {
|
|||
<script type="application/javascript">
|
||||
"use strict";
|
||||
description("Comparing loop index to an uniform in a fragment shader should work.");
|
||||
debug("");
|
||||
var wtu = WebGLTestUtils;
|
||||
function test() {
|
||||
var gl = wtu.create3DContext("canvas");
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
return;
|
||||
}
|
||||
wtu.setupUnitQuad(gl);
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"], undefined, true);
|
||||
var uniformLoc = gl.getUniformLocation(program, 'uCount');
|
||||
gl.uniform1i(uniformLoc, 5);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255]);
|
||||
};
|
||||
|
||||
test();
|
||||
var successfullyParsed = true;
|
||||
finishTest();
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fshader',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: 'Compare a loop index to an uniform',
|
||||
uniforms: [{name: "uCount", functionName: "uniform1i", value: 5}]
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Conditional texture fetch test</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="output" style="border: none;" width="64" height="64"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshaderConditionalTextureFetch" type="x-shader/x-vertex">
|
||||
attribute vec2 a_position;
|
||||
attribute vec4 a_canvasTileColor;
|
||||
attribute vec2 a_texCoord;
|
||||
varying vec2 texCoord;
|
||||
varying vec4 canvasTileColor;
|
||||
void main()
|
||||
{
|
||||
canvasTileColor = a_canvasTileColor;
|
||||
texCoord = a_texCoord;
|
||||
gl_Position = vec4(a_position, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script id="fshaderConditionalTextureFetch" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying vec4 canvasTileColor;
|
||||
uniform bool hasTexture;
|
||||
uniform sampler2D canvasTileTexture;
|
||||
varying vec2 texCoord;
|
||||
uniform vec4 uvRect;
|
||||
void main()
|
||||
{
|
||||
vec4 finalColor = canvasTileColor;
|
||||
if (hasTexture) {
|
||||
vec2 clampedUV = clamp(texCoord.xy, uvRect.xy, uvRect.zw);
|
||||
finalColor = texture2D(canvasTileTexture, clampedUV);
|
||||
}
|
||||
gl_FragColor = finalColor;
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
description();
|
||||
debug("If the test passes correctly the viewport will be green.");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("output");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
|
||||
var createGreenTexture = function() {
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
wtu.fillTexture(gl, texture, 1, 1, [0, 255, 0, 255]);
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
return texture;
|
||||
};
|
||||
|
||||
var test = function(greenTexture) {
|
||||
// This is a reduced test case for a problem reported by Figma.
|
||||
// Program compilation produces the following warning/error on ANGLE's
|
||||
// D3D9 backend:
|
||||
// [WARNING:angle_platform_impl.cc(51)] : rx::HLSLCompiler::compileToBinary(228): C:\fakepath(26,12): error X6077: texld/texldb/texldp/dsx/dsy instructions with r# as source cannot be used inside dynamic conditional 'if' blocks, dynamic conditional subroutine calls, or loop/rep with break*.
|
||||
//
|
||||
// All of the operations in the shader -- including the clamping of the
|
||||
// texture coordinates -- seem to be needed in order to provoke this
|
||||
// error.
|
||||
//
|
||||
// However, this doesn't seem to produce incorrect rendering results.
|
||||
var program = wtu.setupProgram(
|
||||
gl,
|
||||
["vshaderConditionalTextureFetch",
|
||||
"fshaderConditionalTextureFetch"],
|
||||
["a_position", "a_canvasTileColor", "a_texCoord"],
|
||||
[0, 1, 2],
|
||||
true);
|
||||
if (!program) {
|
||||
testFailed("Shader compilation/link failed");
|
||||
} else {
|
||||
// Set up buffers
|
||||
wtu.setupUnitQuad(gl, 0, 2);
|
||||
|
||||
// Set up constant color (red)
|
||||
gl.vertexAttrib4f(1, 1, 0, 0, 1);
|
||||
|
||||
var uniformMap = wtu.getUniformMap(gl, program);
|
||||
|
||||
// Use texturing
|
||||
gl.uniform1i(uniformMap["hasTexture"].location, 1);
|
||||
|
||||
// Bind texture
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, greenTexture);
|
||||
gl.uniform1i(uniformMap["canvasTileTexture"].location, 0);
|
||||
|
||||
// Set up (essentially no-op) clamp rectangle
|
||||
gl.uniform4f(uniformMap["uvRect"].location, 0, 0, 0.25, 0.25);
|
||||
|
||||
// Draw
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
|
||||
// Verify output
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green", 1);
|
||||
}
|
||||
};
|
||||
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
var tex = createGreenTexture();
|
||||
test(tex);
|
||||
}
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -33,18 +33,11 @@
|
|||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="256" height="256"> </canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec3 aPosition;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aPosition, 1);
|
||||
}
|
||||
</script>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
// It is assumed that uTest is set to 0. It's here to make the expression not constant.
|
||||
uniform mediump float uTest;
|
||||
|
@ -96,49 +89,48 @@ void main() {
|
|||
<script type="application/javascript">
|
||||
"use strict";
|
||||
description();
|
||||
var wtu = WebGLTestUtils;
|
||||
|
||||
function test() {
|
||||
var gl = wtu.create3DContext("canvas");
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext();
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision == 0) {
|
||||
testPassed("highp precision not supported");
|
||||
finishTest();
|
||||
} else {
|
||||
wtu.setupUnitQuad(gl);
|
||||
|
||||
debug("Testing shader where the precision qualifier of a constant affects built-in function results");
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"], undefined, true);
|
||||
var uniformLoc = gl.getUniformLocation(program, 'uTest');
|
||||
gl.uniform1f(uniformLoc, 0);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 256, 256, [0, 255, 0, 255]);
|
||||
|
||||
debug("");
|
||||
debug("Testing shader where the precision qualifier of a variable affects built-in function results");
|
||||
program = wtu.setupProgram(gl, ["vshader", "fshaderNoConstants"], ["aPosition"], undefined, true);
|
||||
uniformLoc = gl.getUniformLocation(program, 'uTest');
|
||||
gl.uniform1f(uniformLoc, 0);
|
||||
uniformLoc = gl.getUniformLocation(program, 'uTestHigh');
|
||||
gl.uniform1f(uniformLoc, 0);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 256, 256, [0, 255, 0, 255]);
|
||||
|
||||
debug("");
|
||||
debug("Testing shader where all variables are qualified as highp");
|
||||
program = wtu.setupProgram(gl, ["vshader", "fshaderAllHighp"], ["aPosition"], undefined, true);
|
||||
uniformLoc = gl.getUniformLocation(program, 'uTest');
|
||||
gl.uniform1f(uniformLoc, 0);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvasRect(gl, 0, 0, 256, 256, [0, 255, 0, 255]);
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fshader',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: 'The precision qualifier of a constant affects built-in function results',
|
||||
uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}]
|
||||
},
|
||||
{
|
||||
fShaderId: 'fshaderNoConstants',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: 'The precision qualifier of a variable affects built-in function results',
|
||||
uniforms: [{name: "uTest", functionName: "uniform1f", value: 0},
|
||||
{name: "uTestHigh", functionName: "uniform1f", value: 0}]
|
||||
},
|
||||
{
|
||||
fShaderId: 'fshaderAllHighp',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: 'All variables are qualified as highp',
|
||||
uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}]
|
||||
},
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
test();
|
||||
var successfullyParsed = true;
|
||||
finishTest();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -35,19 +35,19 @@
|
|||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="repro" style="border: none;" width="256" height="256"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script id="shader-vs" type="x-shader/x-vertex">
|
||||
attribute vec2 pos;
|
||||
attribute vec4 vPosition;
|
||||
uniform float divisor;
|
||||
varying vec4 vColor;
|
||||
void main(void) {
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
gl_Position = vPosition;
|
||||
float index = 9.0;
|
||||
// Floating point operations don't have any guaranteed precision, but they
|
||||
// should at least be accurate to 1 part in 10^5.
|
||||
|
@ -65,31 +65,26 @@ void main(void) {
|
|||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
description();
|
||||
|
||||
debug("");
|
||||
// Reproduces bug seen on Mac OS X with AMD Radeon HD 6490 GPU
|
||||
debug("If things are working correctly, then the square will be green.");
|
||||
debug("If your card thinks floor(9. / 3.) is not 3 to within 1 part in 10^5, ");
|
||||
debug("then the square will be red.");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("repro");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
wtu.setupUnitQuad(gl);
|
||||
var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"], ["pos"], undefined, true);
|
||||
gl.uniform1f(gl.getUniformLocation(program, "divisor"), 3);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvasRect(gl, 128, 128, 128, 128, [ 0, 255, 0, 255 ], "should be green", 1);
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
vShaderId: 'shader-vs',
|
||||
vShaderSuccess: true,
|
||||
fShaderId: 'shader-fs',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: 'Test that floor(9. / 3.) is 3 to within 1 part in 10^5',
|
||||
uniforms: [{name: "divisor", functionName: "uniform1f", value: 3}]
|
||||
}
|
||||
]);
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2018 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>If with return and else if in fragment shader</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 pos;
|
||||
varying vec2 vPos;
|
||||
void main()
|
||||
{
|
||||
gl_Position = pos;
|
||||
vPos = pos.xy;
|
||||
}
|
||||
</script>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
varying vec2 vPos;
|
||||
void main()
|
||||
{
|
||||
if(vPos.x < 1.0) // This colors the whole canvas green
|
||||
{
|
||||
gl_FragColor = vec4(0, 1, 0, 1);
|
||||
return;
|
||||
}
|
||||
else if(vPos.x < 1.1) // This should have no effect
|
||||
{
|
||||
gl_FragColor = vec4(1, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
description();
|
||||
|
||||
// Minimal test case based on report at http://anglebug.com/2325
|
||||
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
vShaderId: 'vshader',
|
||||
vShaderSuccess: true,
|
||||
fShaderId: 'fshader',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "If and else if in fragment shader"
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,73 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Function in parameter passed as an inout argument and a global variable with the same name</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="fshaderParameters" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform vec3 u_zero;
|
||||
vec3 p;
|
||||
void G(inout vec3 q) {
|
||||
p += q;
|
||||
}
|
||||
void F(in vec3 p) {
|
||||
G(p);
|
||||
}
|
||||
void main(){
|
||||
F(u_zero + vec3(0.0, 1.0, 0.0));
|
||||
gl_FragColor = vec4(p, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
description();
|
||||
|
||||
// This is intended to test an issue seen on NVIDIA OpenGL drivers (at least up to version 388.59).
|
||||
// http://crbug.com/792210
|
||||
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fshaderParameters',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Function in parameter passed as an inout argument and a global variable with the same name"
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,105 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Initializing an array with a loop test</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="fshaderInitLoop" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
void initGlobals();
|
||||
|
||||
uniform vec4 in0;
|
||||
vec4 out0;
|
||||
|
||||
float func(float a[4]) {
|
||||
a[0] = -1.0;
|
||||
return a[0];
|
||||
}
|
||||
|
||||
float arr[4];
|
||||
|
||||
bool isOk(vec4 a) {
|
||||
vec4 ref = -(in0 + 1.0);
|
||||
if (abs(a.x - ref.x) < 0.05 && abs(a.y - ref.y) < 0.05 && abs(a.z - ref.z) < 0.05 && abs(a.w - ref.w) < 0.05)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void main() {
|
||||
initGlobals();
|
||||
arr[0] = in0.x + 1.0;
|
||||
arr[1] = in0.y + 1.0;
|
||||
arr[2] = in0.z + 1.0;
|
||||
arr[3] = in0.w + 1.0;
|
||||
mediump float f = func(arr);
|
||||
out0 = f * vec4(arr[0], arr[1], arr[2], arr[3]);
|
||||
if (isOk(out0))
|
||||
{
|
||||
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
void initGlobals() {
|
||||
out0 = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
arr[i] = 0.0;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
description();
|
||||
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fshaderInitLoop',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Initialize a global array using a for loop"
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -33,18 +33,11 @@
|
|||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="256" height="256"> </canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec3 aPosition;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(aPosition, 1);
|
||||
}
|
||||
</script>
|
||||
<script id="fshaderIf" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform bool uFalse;
|
||||
|
@ -92,33 +85,22 @@ void main() {
|
|||
"use strict";
|
||||
description("Short-circuiting logic operator with side effects inside if/for statement without braces should work.");
|
||||
debug("");
|
||||
var wtu = WebGLTestUtils;
|
||||
function test() {
|
||||
var gl = wtu.create3DContext("canvas");
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
return;
|
||||
}
|
||||
wtu.setupUnitQuad(gl);
|
||||
|
||||
debug("");
|
||||
debug("Testing if");
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshaderIf"], ["aPosition"], undefined, true);
|
||||
var uniformLoc = gl.getUniformLocation(program, 'uFalse');
|
||||
gl.uniform1i(uniformLoc, 0);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255]);
|
||||
|
||||
debug("");
|
||||
debug("Testing for");
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshaderFor"], ["aPosition"], undefined, true);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255]);
|
||||
};
|
||||
|
||||
test();
|
||||
var successfullyParsed = true;
|
||||
finishTest();
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fshaderIf',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: 'Short-circuiting operator inside if statement without braces',
|
||||
uniforms: [{name: "uFalse", functionName: "uniform1i", value: 0}]
|
||||
},
|
||||
{
|
||||
fShaderId: 'fshaderFor',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: 'Short-circuiting operator inside for statement without braces'
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -35,19 +35,19 @@
|
|||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="repro" style="border: none;" width="256" height="256"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script id="shader-vs" type="x-shader/x-vertex">
|
||||
attribute vec2 pos;
|
||||
attribute vec4 vPosition;
|
||||
uniform float divisor;
|
||||
varying vec4 vColor;
|
||||
void main(void) {
|
||||
gl_Position = vec4(pos, 0.0, 1.0);
|
||||
gl_Position = vPosition;
|
||||
float index = 9.0;
|
||||
// mod(x, y) is computed as x-y*floor(x/y). There are no guarantees on
|
||||
// the precision of floating point operations in WebGL shaders, but division
|
||||
|
@ -73,23 +73,17 @@ debug("");
|
|||
debug("If things are working correctly, then the square will be green.");
|
||||
debug("If your card thinks mod(9,3) is not 0, then the square will be red.");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("repro");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
wtu.setupUnitQuad(gl);
|
||||
var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"], ["pos"], undefined, true);
|
||||
gl.uniform1f(gl.getUniformLocation(program, "divisor"), 3);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvasRect(gl, 128, 128, 128, 128, [ 0, 255, 0, 255 ], "should be green", 1);
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
vShaderId: 'shader-vs',
|
||||
vShaderSuccess: true,
|
||||
fShaderId: 'shader-fs',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: 'Test that mod(9/3) is 0',
|
||||
uniforms: [{name: "divisor", functionName: "uniform1f", value: 3}]
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
]);
|
||||
</script>
|
||||
<script src="../../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -33,14 +33,10 @@
|
|||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script id="shader-vs" type="x-shader/x-vertex">
|
||||
void main(){
|
||||
gl_Position = vec4(0);
|
||||
}
|
||||
</script>
|
||||
<script id="shader-fs" type="x-shader/x-fragment">
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform mat3 rot;
|
||||
float foo(vec3 bar) {
|
||||
|
@ -60,21 +56,16 @@ void main(void){
|
|||
description();
|
||||
debug("");
|
||||
debug('Verify multiplication assignment operator compiles correctly - regression test for <a href="https://code.google.com/p/chromium/issues/detail?id=384847">Chromium bug 384847</a>');
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext();
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"], null, null, true);
|
||||
if (program) {
|
||||
testPassed("Program compiled and linked successfully");
|
||||
} else {
|
||||
testFailed("Program failed to compile and link");
|
||||
}
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
GLSLConformanceTester.runTests([
|
||||
{
|
||||
fShaderId: 'fshader',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "vec3 *= mat3 multiplication assignment operator",
|
||||
}
|
||||
]);
|
||||
|
||||
</script>
|
||||
<script src="../../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!--
|
||||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2014 The Khronos Group Inc.
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>GLSL struct containing an array of samplers passed into a user-defined function</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<canvas id="output" style="border: none;" width="64" height="64"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="fshaderSampler" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
struct S {
|
||||
sampler2D sam[2];
|
||||
};
|
||||
|
||||
uniform S uni;
|
||||
|
||||
vec4 useSampler(S arg)
|
||||
{
|
||||
return texture2D(arg.sam[0], vec2(0.0, 0.0));
|
||||
}
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vec4(useSampler(uni));
|
||||
}
|
||||
</script>
|
||||
<script type="application/javascript">
|
||||
"use strict";
|
||||
description();
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("output");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
|
||||
if (!gl) {
|
||||
testFailed("Could not create a GL context.");
|
||||
} else {
|
||||
debug("Drawing with a shader that uses a sampler array in a struct passed into a function.");
|
||||
var program = wtu.setupProgram(
|
||||
gl, [wtu.simpleVertexShader, 'fshaderSampler'], ['a_position'], [0], true);
|
||||
wtu.setupUnitQuad(gl);
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
wtu.fillTexture(gl, tex, 1, 1, [0, 255, 0, 255]);
|
||||
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
|
||||
}
|
||||
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -35,17 +35,10 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<canvas id="output" style="border: none;" width="256" height="256"></canvas>
|
||||
<canvas id="output" style="border: none;" width="64" height="64"></canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script id="shader-vs" type="x-shader/x-vertex">
|
||||
attribute vec4 a_position;
|
||||
void main(){
|
||||
gl_Position = a_position;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="shader-fs" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
|
@ -63,35 +56,49 @@
|
|||
}
|
||||
</script>
|
||||
|
||||
<script id="shader-fs-array" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
struct SomeStruct{
|
||||
sampler2D source;
|
||||
};
|
||||
|
||||
vec4 fun(SomeStruct s[2]){
|
||||
return texture2D(s[0].source, vec2(0.5));
|
||||
}
|
||||
|
||||
uniform SomeStruct green[2];
|
||||
void main(){
|
||||
gl_FragColor = fun(green);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
description();
|
||||
debug("");
|
||||
debug("If the test passes correctly the viewport will be green.");
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas = document.getElementById("output");
|
||||
var gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
var textureGreen = gl.createTexture()
|
||||
gl.bindTexture(gl.TEXTURE_2D, textureGreen);
|
||||
|
||||
var textureGreen;
|
||||
|
||||
var createGreenTexture = function() {
|
||||
var texture = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
wtu.fillTexture(gl, textureGreen, 1, 1, [0, 255, 0, 255]);
|
||||
wtu.fillTexture(gl, texture, 1, 1, [0, 255, 0, 255]);
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
return texture;
|
||||
};
|
||||
|
||||
// Clear complete viewport to red
|
||||
gl.clearColor(1.0, 0.0, 0.0, 1.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
var attribBuffers = wtu.setupUnitQuad(gl, 0, 1);
|
||||
var program = wtu.setupProgram(gl, ["shader-vs", "shader-fs"], ["a_position"], [0], true);
|
||||
var test = function(fragShaderId, texUniformName) {
|
||||
var program = wtu.setupProgram(gl, [wtu.simpleVertexShader, fragShaderId], ["a_position"], [0], true);
|
||||
|
||||
if (!program) {
|
||||
testFailed("Shader compilation/link failed");
|
||||
|
@ -100,14 +107,23 @@ if (!gl) {
|
|||
var uniformMap = wtu.getUniformMap(gl, program);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, textureGreen);
|
||||
gl.uniform1i(uniformMap['green.source'].location, 0);
|
||||
gl.uniform1i(uniformMap[texUniformName].location, 0);
|
||||
|
||||
// Draw
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.clearAndDrawUnitQuad(gl);
|
||||
|
||||
// Verify output
|
||||
wtu.checkCanvasRect(gl, 0, 128, 256, 128, [0, 255,0, 255], "should be green", 1);
|
||||
}
|
||||
};
|
||||
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
wtu.setupUnitQuad(gl, 0, 1);
|
||||
textureGreen = createGreenTexture();
|
||||
test("shader-fs", "green.source");
|
||||
test("shader-fs-array", "green[0].source");
|
||||
}
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
|
|
|
@ -6,19 +6,11 @@
|
|||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="256" height="256"> </canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
attribute vec4 a_position;
|
||||
void main() {
|
||||
gl_Position = a_position;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
|
@ -42,22 +34,17 @@ void main() {
|
|||
description("Struct constructors should evaluate properly.");
|
||||
debug("Regression test for Three.js bug worked around in <a href='https://github.com/mrdoob/three.js/pull/7556'>https://github.com/mrdoob/three.js/pull/7556</a> that reproduced on Nexus 4 and 5 (Adreno 320 and 330).");
|
||||
debug("When high precision is used in the fragment shader on these devices, bugs occur in evaluation of structs' constructors. Thanks to Mr. doob for the reduced test case.");
|
||||
var wtu = WebGLTestUtils;
|
||||
var gl = wtu.create3DContext("canvas");
|
||||
|
||||
gl.clearColor(1, 0, 0, 1);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
var attribBuffers = wtu.setupUnitQuad(gl, 0, 1);
|
||||
var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_position'], [0], true);
|
||||
if (!program) {
|
||||
testFailed("Shader compilation/link failed");
|
||||
} else {
|
||||
// Draw
|
||||
wtu.drawUnitQuad(gl);
|
||||
// Verify output
|
||||
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fshader',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Struct contstructor evaluation"
|
||||
}
|
||||
]);
|
||||
|
||||
finishTest();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2016 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>GLSL unary minus operator with float bug Tests</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
void main () {
|
||||
float f = -1.0;
|
||||
// atan(tan(0.5), -f) is in range [1.5707, 1.5708) on Mac OSX 10.11 with Intel GPU.
|
||||
// But it should be 0.5.
|
||||
gl_FragColor = vec4(atan(tan(0.5), -f), 0.0, 0.0, 1.0);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
description("Test for unary minus operator with float bug on MacOSX 10.11 with Intel GPU");
|
||||
debug("This is a regression test for <a href='https://bugs.chromium.org/p/chromium/issues/detail?id=308366'>Chromium Issue 308366</a>");
|
||||
debug("");
|
||||
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fshader',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Evaluate unary minus operator and atan(x, y)",
|
||||
renderTolerance: 3,
|
||||
renderColor: [127, 0, 0, 255]
|
||||
}
|
||||
]);
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,101 @@
|
|||
<!--
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Varying arrays should not be reversed</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="canvas" width="512" height="256"> </canvas>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="vshader" type="x-shader/x-vertex">
|
||||
varying float colors[3];
|
||||
uniform vec3 testData;
|
||||
attribute vec3 position;
|
||||
void main(){
|
||||
gl_Position = vec4(position, 1.0);
|
||||
colors[0] = testData.x;
|
||||
colors[1] = testData.y;
|
||||
colors[2] = testData.z;
|
||||
}
|
||||
</script>
|
||||
<script id="fshader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
varying float colors[3];
|
||||
void main() {
|
||||
gl_FragColor = vec4(colors[0], colors[1], colors[2], 1.0);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
"use strict";
|
||||
description("Varying arrays should not be reversed.");
|
||||
debug("This issue has been seen in Chrome on Nexus 7 2013 (Adreno 320) and Moto G3 (Adreno 306).");
|
||||
debug("");
|
||||
debug("If things are working correctly, the vertical stripes should be: red, green, blue, light blue, orange");
|
||||
debug("");
|
||||
debug("If they are not, the red and blue channels will appear to be swapped and you will see: blue, green, red, orange, light blue");
|
||||
var wtu = WebGLTestUtils;
|
||||
function test() {
|
||||
var gl = wtu.create3DContext("canvas");
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
wtu.setupUnitQuad(gl);
|
||||
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["position"], undefined, true);
|
||||
var loc = gl.getUniformLocation(program, 'testData');
|
||||
|
||||
var triples = [
|
||||
[255, 0, 0],
|
||||
[0, 255, 0],
|
||||
[0, 0, 255],
|
||||
[0, 128, 255],
|
||||
[255, 128, 0]
|
||||
];
|
||||
|
||||
for (var i = 0; i < triples.length; i++) {
|
||||
var triple = triples[i];
|
||||
var x = i * 64;
|
||||
gl.viewport(x, 0, 64, 256);
|
||||
gl.uniform3f(loc, triple[0] / 255, triple[1] / 255, triple[2] / 255);
|
||||
wtu.drawUnitQuad(gl);
|
||||
wtu.checkCanvasRect(gl, x, 0, 64, 256, [triple[0], triple[1], triple[2], 255]);
|
||||
}
|
||||
|
||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "there should be no errors");
|
||||
}
|
||||
test();
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script src="../../../js/js-test-post.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<!--
|
||||
|
||||
/*
|
||||
** Copyright (c) 2017 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
|
||||
-->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>GLSL vector/scalar arithmetic inside a for loop (complex cases)</title>
|
||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||
<script src="../../../js/js-test-pre.js"></script>
|
||||
<script src="../../../js/webgl-test-utils.js"></script>
|
||||
<script src="../../../js/glsl-conformance-test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<script id="fShaderVectorCompoundMulAndAddInSeparateStatementsInsideForLoop" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
float x = gl_FragCoord.x;
|
||||
float y = (x *= 2.0);
|
||||
gl_FragColor = gl_FragColor + vec4(y, y, y, y);
|
||||
}
|
||||
if (gl_FragColor.g == gl_FragColor.r &&
|
||||
gl_FragColor.b == gl_FragColor.r &&
|
||||
gl_FragColor.a == gl_FragColor.r)
|
||||
{
|
||||
gl_FragColor = vec4(0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script id="fShaderVectorCompoundMulAndAddInSeparateStatementsInsideForLoop2" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
float x = gl_FragCoord.x;
|
||||
float y = (x *= 2.0);
|
||||
gl_FragColor = gl_FragColor + vec4(x, y, x, y);
|
||||
}
|
||||
if (gl_FragColor.g == gl_FragColor.r &&
|
||||
gl_FragColor.b == gl_FragColor.r &&
|
||||
gl_FragColor.a == gl_FragColor.r)
|
||||
{
|
||||
gl_FragColor = vec4(0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
"use strict";
|
||||
description();
|
||||
|
||||
// See http://crbug.com/772651
|
||||
|
||||
GLSLConformanceTester.runRenderTests([
|
||||
{
|
||||
fShaderId: 'fShaderVectorCompoundMulAndAddInSeparateStatementsInsideForLoop',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Adding a vector that's just 4 copies of a scalar to another vector inside for loop should work."
|
||||
},
|
||||
{
|
||||
fShaderId: 'fShaderVectorCompoundMulAndAddInSeparateStatementsInsideForLoop2',
|
||||
fShaderSuccess: true,
|
||||
linkSuccess: true,
|
||||
passMsg: "Adding a vector that's just 4 copies of a scalar stored in two different variables to another vector inside for loop should work."
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче