Merge mozilla-central to autoland. a=merge on a CLOSED TREE

This commit is contained in:
Andreea Pavel 2018-04-21 12:34:21 +03:00
Родитель 6e2b2b6f35 5743b5b700
Коммит 5bb0fde6e9
2981 изменённых файлов: 66869 добавлений и 10547 удалений

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

@ -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.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';"); pref("extensions.webextensions.default-content-security-policy", "script-src 'self'; object-src 'self';");
#if defined(XP_WIN) #if defined(XP_WIN) || defined(XP_MACOSX)
pref("extensions.webextensions.remote", true);
#elif defined(XP_MACOSX) && !defined(RELEASE_OR_BETA)
pref("extensions.webextensions.remote", true); pref("extensions.webextensions.remote", true);
#endif #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"); 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 // Require signed add-ons by default
pref("extensions.langpacks.signatures.required", true);
pref("xpinstall.signatures.required", true); pref("xpinstall.signatures.required", true);
pref("xpinstall.signatures.devInfoURL", "https://wiki.mozilla.org/Addons/Extension_Signing"); pref("xpinstall.signatures.devInfoURL", "https://wiki.mozilla.org/Addons/Extension_Signing");

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

@ -441,7 +441,7 @@
<hbox align="center"> <hbox align="center">
<vbox flex="1"> <vbox flex="1">
<description id="updateAppInfo"> <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>
<description id="distribution" class="text-blurb" hidden="true"/> <description id="distribution" class="text-blurb" hidden="true"/>
<description id="distributionId" 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; const TEXT_NODE = Ci.nsIDOMNode.TEXT_NODE;
ChromeUtils.import("resource://services-common/async.js"); ChromeUtils.import("resource://services-common/async.js");
Cu.importGlobalProperties(["DOMParser"]);
/** /**
* This class represents a document that is being translated, * This class represents a document that is being translated,
@ -301,8 +302,7 @@ TranslationItem.prototype = {
return; return;
} }
let domParser = Cc["@mozilla.org/xmlextras/domparser;1"] let domParser = new DOMParser();
.createInstance(Ci.nsIDOMParser);
let doc = domParser.parseFromString(result, "text/html"); let doc = domParser.parseFromString(result, "text/html");
parseResultNode(this, doc.body.firstChild); parseResultNode(this, doc.body.firstChild);

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

@ -8,6 +8,7 @@ const CC = Components.Constructor;
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream", "nsIBinaryInputStream",
"setInputStream"); "setInputStream");
Cu.importGlobalProperties(["DOMParser"]);
function handleRequest(req, res) { function handleRequest(req, res) {
try { try {
@ -98,9 +99,8 @@ function sha1(str) {
} }
function parseXml(body) { function parseXml(body) {
let DOMParser = Cc["@mozilla.org/xmlextras/domparser;1"] let parser = new DOMParser();
.createInstance(Ci.nsIDOMParser); let xml = parser.parseFromString(body, "text/xml");
let xml = DOMParser.parseFromString(body, "text/xml");
if (xml.documentElement.localName == "parsererror") if (xml.documentElement.localName == "parsererror")
throw new Error("Invalid XML"); throw new Error("Invalid XML");
return xml; return xml;

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

@ -31,6 +31,7 @@ var { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {}
var { gDevTools } = require("devtools/client/framework/devtools"); var { gDevTools } = require("devtools/client/framework/devtools");
var Services = require("Services"); var Services = require("Services");
var { globals } = require("devtools/shared/builtin-modules");
this.EXPORTED_SYMBOLS = ["AppCacheUtils"]; this.EXPORTED_SYMBOLS = ["AppCacheUtils"];
@ -617,5 +618,5 @@ XPCOMUtils.defineLazyGetter(this, "appcacheservice", function() {
}); });
XPCOMUtils.defineLazyGetter(this, "_DOMParser", 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 // Test that VariablesView._doSearch() works even without an attached
// VariablesViewController (bug 1196341). // VariablesViewController (bug 1196341).
const DOMParser = Cc["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Ci.nsIDOMParser);
const { VariablesView } = const { VariablesView } =
ChromeUtils.import("resource://devtools/client/shared/widgets/VariablesView.jsm", {}); 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() { function run_test() {
let doc = DOMParser.parseFromString("<div>", "text/html"); let doc = DOMParser.parseFromString("<div>", "text/html");

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

@ -34,9 +34,6 @@ loader.lazyRequireGetter(this, "WalkerSearch", "devtools/server/actors/utils/wal
loader.lazyServiceGetter(this, "eventListenerService", loader.lazyServiceGetter(this, "eventListenerService",
"@mozilla.org/eventlistenerservice;1", "nsIEventListenerService"); "@mozilla.org/eventlistenerservice;1", "nsIEventListenerService");
loader.lazyServiceGetter(this, "DOMParser",
"@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
// Minimum delay between two "new-mutations" events. // Minimum delay between two "new-mutations" events.
const MUTATIONS_THROTTLING_DELAY = 100; const MUTATIONS_THROTTLING_DELAY = 100;
// List of mutation types that should -not- be throttled. // List of mutation types that should -not- be throttled.
@ -1259,7 +1256,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
return; return;
} }
let parsedDOM = DOMParser.parseFromString(value, "text/html"); let parsedDOM = new DOMParser().parseFromString(value, "text/html");
let rawNode = node.rawNode; let rawNode = node.rawNode;
let parentNode = rawNode.parentNode; let parentNode = rawNode.parentNode;

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

@ -20,12 +20,14 @@ function run_test() {
let g2 = testGlobal("test2"); let g2 = testGlobal("test2");
g2.g = g; g2.g = g;
g2.eval("(" + function createBadEvent() { // Not using the "stringify a function" trick because that runs afoul of the
let parser = Cc["@mozilla.org/xmlextras/domparser;1"] // Cu.importGlobalProperties lint and we don't need it here anyway.
.createInstance(Ci.nsIDOMParser); g2.eval(`(function createBadEvent() {
Cu.importGlobalProperties(["DOMParser"]);
let parser = new DOMParser();
let doc = parser.parseFromString("<foo></foo>", "text/xml"); let doc = parser.parseFromString("<foo></foo>", "text/xml");
g.stopMe(doc.createEvent("MouseEvent")); g.stopMe(doc.createEvent("MouseEvent"));
} + ")()"); } )()`);
dbg.enabled = false; dbg.enabled = false;
} }

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

@ -32,6 +32,7 @@ const {
ChromeUtils, ChromeUtils,
CSS, CSS,
CSSRule, CSSRule,
DOMParser,
Event, Event,
FileReader, FileReader,
FormData, FormData,
@ -48,6 +49,7 @@ const {
"ChromeUtils", "ChromeUtils",
"CSS", "CSS",
"CSSRule", "CSSRule",
"DOMParser",
"Event", "Event",
"FileReader", "FileReader",
"FormData", "FormData",
@ -264,6 +266,7 @@ exports.globals = {
define(factory) { define(factory) {
factory(this.require, this.exports, this.module); factory(this.require, this.exports, this.module);
}, },
DOMParser,
Element: Ci.nsIDOMElement, Element: Ci.nsIDOMElement,
Event, Event,
FormData, FormData,
@ -315,9 +318,6 @@ lazyGlobal("clearInterval", () => {
lazyGlobal("setInterval", () => { lazyGlobal("setInterval", () => {
return require("resource://gre/modules/Timer.jsm").setInterval; return require("resource://gre/modules/Timer.jsm").setInterval;
}); });
lazyGlobal("DOMParser", () => {
return CC("@mozilla.org/xmlextras/domparser;1", "nsIDOMParser");
});
lazyGlobal("WebSocket", () => { lazyGlobal("WebSocket", () => {
return Services.appShell.hiddenDOMWindow.WebSocket; return Services.appShell.hiddenDOMWindow.WebSocket;
}); });

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

@ -13,8 +13,6 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "nsIAttribute.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 "nsIDOMNode.h"
#include "nsIDOMNodeList.h" #include "nsIDOMNodeList.h"
#include "nsString.h" #include "nsString.h"

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

@ -8,6 +8,8 @@
#include "nsIDOMDocument.h" #include "nsIDOMDocument.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsDOMString.h"
#include "MainThreadUtils.h"
#include "nsIStreamListener.h" #include "nsIStreamListener.h"
#include "nsStringStream.h" #include "nsStringStream.h"
#include "nsIScriptError.h" #include "nsIScriptError.h"
@ -26,10 +28,16 @@
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
DOMParser::DOMParser() DOMParser::DOMParser(nsIGlobalObject* aOwner, nsIPrincipal* aDocPrincipal,
: mAttemptedInit(false) nsIURI* aDocumentURI, nsIURI* aBaseURI)
, mOriginalPrincipalWasSystem(false) : mOwner(aOwner)
, mPrincipal(aDocPrincipal)
, mDocumentURI(aDocumentURI)
, mBaseURI(aBaseURI)
, mForceEnableXULXBL(false)
{ {
MOZ_ASSERT(aDocPrincipal);
MOZ_ASSERT(aDocumentURI);
} }
DOMParser::~DOMParser() DOMParser::~DOMParser()
@ -39,9 +47,7 @@ DOMParser::~DOMParser()
// QueryInterface implementation for DOMParser // QueryInterface implementation for DOMParser
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMParser) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMParser)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMParser) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIDOMParser)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMParser, mOwner) NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(DOMParser, mOwner)
@ -57,124 +63,72 @@ StringFromSupportedType(SupportedType aType)
already_AddRefed<nsIDocument> already_AddRefed<nsIDocument>
DOMParser::ParseFromString(const nsAString& aStr, SupportedType aType, DOMParser::ParseFromString(const nsAString& aStr, SupportedType aType,
ErrorResult& rv) ErrorResult& aRv)
{ {
nsCOMPtr<nsIDOMDocument> domDocument; if (aType == SupportedType::Text_html) {
rv = ParseFromString(aStr, nsCOMPtr<nsIDocument> document = SetUpDocument(DocumentFlavorHTML, aRv);
StringFromSupportedType(aType), if (NS_WARN_IF(aRv.Failed())) {
getter_AddRefs(domDocument)); return nullptr;
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);
// Keep the XULXBL state in sync with the XML case. // Keep the XULXBL state in sync with the XML case.
if (mForceEnableXULXBL) {
if (mOriginalPrincipalWasSystem) {
document->ForceEnableXULXBL(); document->ForceEnableXULXBL();
} }
rv = nsContentUtils::ParseDocumentHTML(str, document, false); nsresult rv = nsContentUtils::ParseDocumentHTML(aStr, document, false);
NS_ENSURE_SUCCESS(rv, rv); if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return nullptr;
}
domDocument.forget(aResult); return document.forget();
return rv;
} }
nsAutoCString utf8str; nsAutoCString utf8str;
// Convert from UTF16 to UTF8 using fallible allocations // Convert from UTF16 to UTF8 using fallible allocations
if (!AppendUTF16toUTF8(str, utf8str, mozilla::fallible)) { if (!AppendUTF16toUTF8(aStr, utf8str, mozilla::fallible)) {
return NS_ERROR_OUT_OF_MEMORY; aRv.Throw(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);
return nullptr; 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 // The new stream holds a reference to the buffer
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
reinterpret_cast<const char *>(buf), utf8str.get(), utf8str.Length(),
bufLen, NS_ASSIGNMENT_DEPEND); NS_ASSIGNMENT_DEPEND);
if (NS_FAILED(rv)) if (NS_WARN_IF(NS_FAILED(rv))) {
return 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, const nsAString& aCharset,
int32_t aContentLength, int32_t aContentLength,
SupportedType aType, SupportedType aType,
ErrorResult& rv) ErrorResult& aRv)
{ {
nsCOMPtr<nsIDOMDocument> domDocument; bool svg = (aType == SupportedType::Image_svg_xml);
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;
// For now, we can only create XML documents. // For now, we can only create XML documents.
//XXXsmaug Should we create an HTMLDocument (in XHTML mode) //XXXsmaug Should we create an HTMLDocument (in XHTML mode)
// for "application/xhtml+xml"? // for "application/xhtml+xml"?
if ((nsCRT::strcmp(aContentType, "text/xml") != 0) && if (aType != SupportedType::Text_xml &&
(nsCRT::strcmp(aContentType, "application/xml") != 0) && aType != SupportedType::Application_xml &&
(nsCRT::strcmp(aContentType, "application/xhtml+xml") != 0) && aType != SupportedType::Application_xhtml_xml &&
!svg) !svg) {
return NS_ERROR_NOT_IMPLEMENTED; aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return nullptr;
nsresult rv; }
// Put the nsCOMPtr out here so we hold a ref to the stream as needed // Put the nsCOMPtr out here so we hold a ref to the stream as needed
nsCOMPtr<nsIInputStream> stream = aStream; nsCOMPtr<nsIInputStream> stream = aStream;
if (!NS_InputStreamIsBuffered(stream)) { if (!NS_InputStreamIsBuffered(stream)) {
nsCOMPtr<nsIInputStream> bufferedStream; nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream), nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
stream.forget(), 4096); stream.forget(), 4096);
NS_ENSURE_SUCCESS(rv, rv); if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return nullptr;
}
stream = bufferedStream; stream = bufferedStream;
} }
nsCOMPtr<nsIDOMDocument> domDocument; nsCOMPtr<nsIDocument> document =
rv = SetUpDocument(svg ? DocumentFlavorSVG : DocumentFlavorLegacyGuess, SetUpDocument(svg ? DocumentFlavorSVG : DocumentFlavorLegacyGuess, aRv);
getter_AddRefs(domDocument)); if (NS_WARN_IF(aRv.Failed())) {
NS_ENSURE_SUCCESS(rv, rv); return nullptr;
}
// Create a fake channel // Create a fake channel
nsCOMPtr<nsIChannel> parserChannel; nsCOMPtr<nsIChannel> parserChannel;
@ -244,35 +180,35 @@ DOMParser::ParseFromStream(nsIInputStream* aStream,
mPrincipal, mPrincipal,
nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL, nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
nsIContentPolicy::TYPE_OTHER, nsIContentPolicy::TYPE_OTHER,
nsDependentCString(aContentType)); nsDependentCString(StringFromSupportedType(aType)));
NS_ENSURE_STATE(parserChannel); if (NS_WARN_IF(!parserChannel)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
if (aCharset) { if (!DOMStringIsNull(aCharset)) {
parserChannel->SetContentCharset(nsDependentCString(aCharset)); parserChannel->SetContentCharset(NS_ConvertUTF16toUTF8(aCharset));
} }
// Tell the document to start loading // Tell the document to start loading
nsCOMPtr<nsIStreamListener> listener; 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 // Keep the XULXBL state in sync with the HTML case
if (mForceEnableXULXBL) {
if (mOriginalPrincipalWasSystem) {
document->ForceEnableXULXBL(); document->ForceEnableXULXBL();
} }
rv = document->StartDocumentLoad(kLoadAsData, parserChannel, // Have to pass false for reset here, else the reset will remove
nullptr, nullptr, // our event listener. Should that listener addition move to later
getter_AddRefs(listener), // than this call?
false); nsresult rv = document->StartDocumentLoad(kLoadAsData, parserChannel,
nullptr, nullptr,
getter_AddRefs(listener),
false);
if (NS_FAILED(rv) || !listener) { if (NS_FAILED(rv) || !listener) {
return NS_ERROR_FAILURE; aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
} }
// Now start pumping data to the listener // 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. // the channel, so we do not need to call Cancel(rv) as we do above.
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE; aRv.Throw(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);
return nullptr; return nullptr;
} }
RefPtr<DOMParser> domParser = new DOMParser(aOwner.GetAsSupports());
rv = domParser->InitInternal(aOwner.GetAsSupports(), aPrincipal, aDocumentURI, return document.forget();
aBaseURI);
if (rv.Failed()) {
return nullptr;
}
return domParser.forget();
} }
/*static */already_AddRefed<DOMParser> /*static */already_AddRefed<DOMParser>
DOMParser::Constructor(const GlobalObject& aOwner, DOMParser::Constructor(const GlobalObject& aOwner,
ErrorResult& rv) ErrorResult& rv)
{ {
RefPtr<DOMParser> domParser = new DOMParser(aOwner.GetAsSupports()); MOZ_ASSERT(NS_IsMainThread());
rv = domParser->InitInternal(aOwner.GetAsSupports(), nsCOMPtr<nsIPrincipal> docPrincipal = aOwner.GetSubjectPrincipal();
nsContentUtils::SubjectPrincipal(), nsCOMPtr<nsIURI> documentURI;
nullptr, nullptr); nsIURI* baseURI = nullptr;
if (rv.Failed()) { if (nsContentUtils::IsSystemPrincipal(docPrincipal)) {
return nullptr; docPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
} docPrincipal->GetURI(getter_AddRefs(documentURI));
return domParser.forget(); } else {
} // Grab document and base URIs off the window our constructor was
// called on. Error out if anything untoward happens.
nsresult nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aOwner.GetAsSupports());
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);
if (!window) { if (!window) {
return NS_ERROR_UNEXPECTED; rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
} }
baseURI = window->GetDocBaseURI(); baseURI = window->GetDocBaseURI();
documentURI = window->GetDocumentURI(); documentURI = window->GetDocumentURI();
if (!documentURI) {
return NS_ERROR_UNEXPECTED;
}
} }
nsCOMPtr<nsIGlobalObject> scriptglobal = do_QueryInterface(aOwner); if (!documentURI) {
return Init(prin, documentURI, baseURI, scriptglobal); rv.Throw(NS_ERROR_UNEXPECTED);
} return nullptr;
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();
} }
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 // static
DOMParser::SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult) 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 // if we pass it a scriptHandlingObject that doesn't QI to
// nsIScriptGlobalObject, and test_isequalnode.js (an xpcshell test without // nsIScriptGlobalObject, and test_isequalnode.js (an xpcshell test without
// a window global) breaks. The correct solution is just to wean nsDocument // a window global) breaks. The correct solution is just to wean nsDocument
// off of nsIScriptGlobalObject, but that's a yak to shave another day. // off of nsIScriptGlobalObject, but that's a yak to shave another day.
nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject = nsCOMPtr<nsIScriptGlobalObject> scriptHandlingObject =
do_QueryReferent(mScriptHandlingObject); do_QueryInterface(mOwner);
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);
}
// Try to inherit a style backend. // Try to inherit a style backend.
NS_ASSERTION(mPrincipal, "Must have principal by now"); NS_ASSERTION(mPrincipal, "Must have principal by now");
NS_ASSERTION(mDocumentURI, "Must have document URI by now"); NS_ASSERTION(mDocumentURI, "Must have document URI by now");
return NS_NewDOMDocument(aResult, EmptyString(), EmptyString(), nullptr, nsCOMPtr<nsIDOMDocument> domDoc;
mDocumentURI, mBaseURI, nsresult rv = NS_NewDOMDocument(getter_AddRefs(domDoc), EmptyString(), EmptyString(),
mPrincipal, nullptr, mDocumentURI, mBaseURI, mPrincipal,
true, true, scriptHandlingObject, aFlavor);
scriptHandlingObject, if (NS_WARN_IF(NS_FAILED(rv))) {
aFlavor); aRv.Throw(rv);
return nullptr;
}
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
return doc.forget();
} }

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

@ -9,20 +9,19 @@
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIDOMParser.h"
#include "nsWeakReference.h"
#include "nsWrapperCache.h" #include "nsWrapperCache.h"
#include "mozilla/ErrorResult.h" #include "mozilla/ErrorResult.h"
#include "mozilla/Span.h"
#include "mozilla/dom/DOMParserBinding.h" #include "mozilla/dom/DOMParserBinding.h"
#include "mozilla/dom/TypedArray.h" #include "mozilla/dom/TypedArray.h"
class nsIDocument; class nsIDocument;
class nsIGlobalObject;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class DOMParser final : public nsIDOMParser, class DOMParser final : public nsISupports,
public nsSupportsWeakReference,
public nsWrapperCache public nsWrapperCache
{ {
typedef mozilla::dom::GlobalObject GlobalObject; typedef mozilla::dom::GlobalObject GlobalObject;
@ -30,48 +29,39 @@ class DOMParser final : public nsIDOMParser,
virtual ~DOMParser(); virtual ~DOMParser();
public: public:
DOMParser();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(DOMParser, NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMParser)
nsIDOMParser)
// nsIDOMParser
NS_DECL_NSIDOMPARSER
// WebIDL API // WebIDL API
static already_AddRefed<DOMParser> static already_AddRefed<DOMParser>
Constructor(const GlobalObject& aOwner, Constructor(const GlobalObject& aOwner,
mozilla::ErrorResult& rv); mozilla::ErrorResult& rv);
static already_AddRefed<DOMParser> already_AddRefed<nsIDocument>
Constructor(const GlobalObject& aOwner, ParseFromString(const nsAString& aStr, SupportedType aType, ErrorResult& aRv);
nsIPrincipal* aPrincipal, nsIURI* aDocumentURI, nsIURI* aBaseURI,
mozilla::ErrorResult& rv); // 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> already_AddRefed<nsIDocument>
ParseFromString(const nsAString& aStr, mozilla::dom::SupportedType aType, ParseFromBuffer(const Uint8Array& aBuf, SupportedType aType,
mozilla::ErrorResult& rv); ErrorResult& aRv);
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);
already_AddRefed<nsIDocument> already_AddRefed<nsIDocument>
ParseFromStream(nsIInputStream* aStream, const nsAString& aCharset, ParseFromStream(nsIInputStream* aStream, const nsAString& aCharset,
int32_t aContentLength, mozilla::dom::SupportedType aType, int32_t aContentLength, SupportedType aType,
mozilla::ErrorResult& rv); ErrorResult& aRv);
void Init(nsIPrincipal* aPrincipal, nsIURI* aDocumentURI, void
nsIURI* aBaseURI, mozilla::ErrorResult& rv); ForceEnableXULXBL()
{
mForceEnableXULXBL = true;
}
nsISupports* GetParentObject() const nsIGlobalObject* GetParentObject() const
{ {
return mOwner; return mOwner;
} }
@ -81,46 +71,22 @@ public:
return mozilla::dom::DOMParserBinding::Wrap(aCx, this, aGivenProto); 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: private:
explicit DOMParser(nsISupports* aOwner) DOMParser(nsIGlobalObject* aOwner, nsIPrincipal* aDocPrincipal,
: mOwner(aOwner) nsIURI* aDocumentURI, nsIURI* aBaseURI);
, mAttemptedInit(false)
, mOriginalPrincipalWasSystem(false)
{
MOZ_ASSERT(aOwner);
}
nsresult InitInternal(nsISupports* aOwner, nsIPrincipal* prin, already_AddRefed<nsIDocument> SetUpDocument(DocumentFlavor aFlavor,
nsIURI* documentURI, nsIURI* baseURI); ErrorResult& aRv);
nsresult SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult); nsCOMPtr<nsIGlobalObject> mOwner;
// 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<nsIPrincipal> mPrincipal; nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIURI> mDocumentURI; nsCOMPtr<nsIURI> mDocumentURI;
nsCOMPtr<nsIURI> mBaseURI; nsCOMPtr<nsIURI> mBaseURI;
nsWeakPtr mScriptHandlingObject;
bool mAttemptedInit; bool mForceEnableXULXBL;
bool mOriginalPrincipalWasSystem;
}; };
} // namespace dom } // namespace dom

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

@ -16,7 +16,6 @@ XPIDL_SOURCES += [
'mozIDOMWindow.idl', 'mozIDOMWindow.idl',
'nsIContentPolicy.idl', 'nsIContentPolicy.idl',
'nsIDocumentEncoder.idl', 'nsIDocumentEncoder.idl',
'nsIDOMParser.idl',
'nsIDOMRequestService.idl', 'nsIDOMRequestService.idl',
'nsIDroppedLinkHandler.idl', 'nsIDroppedLinkHandler.idl',
'nsIFrameLoaderOwner.idl', 'nsIFrameLoaderOwner.idl',

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

@ -945,41 +945,4 @@ inline const nsIContent* nsINode::AsContent() const
return const_cast<nsINode*>(this)->AsContent(); 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___ */ #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; 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___ */ #endif /* nsINode_h___ */

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

@ -16,38 +16,26 @@
"use strict"; "use strict";
/** Test for Bug 816410 **/ /** Test for Bug 816410 **/
function throws(a, type, message) { function throws(fn, type, message) {
for (let fn of Array.isArray(a) ? a : [a]) { try {
try { fn();
fn(); ok(false, message);
ok(false, message); } catch (e) {
} catch (e) { if (type) {
if (type) { is(e.name, type, message);
is(e.name, type, message); } else {
} else { ok(true, message);
ok(true, message);
}
} }
} }
} }
// DOMParser constructor should not throw for null arguments // DOMParser constructor should not throw for extra arguments
new DOMParser(undefined); new DOMParser(undefined);
new DOMParser(null); new DOMParser(null);
new DOMParser(false);
throws([ new DOMParser(0);
function() { new DOMParser(false); }, new DOMParser("");
function() { new DOMParser(0); }, new DOMParser({});
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");
}
// XMLSerializer constructor should not throw for extra arguments // XMLSerializer constructor should not throw for extra arguments
new XMLSerializer(undefined); new XMLSerializer(undefined);
@ -59,24 +47,10 @@ new XMLSerializer({});
runTest(new DOMParser(), 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) { function runTest(parser, serializer) {
is(typeof parser.parseFromString, "function", "parseFromString should exist"); is(typeof parser.parseFromString, "function", "parseFromString should exist");
is(typeof parser.parseFromBuffer, "function", "parseFromBuffer should exist"); is(typeof parser.parseFromBuffer, "function", "parseFromBuffer should exist");
is(typeof parser.parseFromStream, "function", "parseFromStream 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.serializeToString, "function", "serializeToString should exist");
is(typeof serializer.serializeToStream, "function", "serializeToStream should exist"); is(typeof serializer.serializeToStream, "function", "serializeToStream should exist");
@ -115,13 +89,8 @@ function runTest(parser, serializer) {
]; ];
for (let input of inputs) { for (let input of inputs) {
let a = input.array; 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); 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"]. 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. // to create a DOMParser which is not allowed to parse XUL.
var isXUL = true; var isXUL = true;
var parser = SpecialPowers.getNoXULDOMParser();
ok(parser, "Should get a parser!");
try { try {
var x = var x = parser
SpecialPowers.Cc .parseFromString('<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>', "text/xml");
.getService(Ci.nsIDOMParser)
.parseFromString('<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>', "text/xml");
isXUL = x.documentElement.namespaceURI == isXUL = x.documentElement.namespaceURI ==
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
} }

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

@ -12,17 +12,16 @@ const nsIProperties = I.nsIProperties;
const nsIFileInputStream = I.nsIFileInputStream; const nsIFileInputStream = I.nsIFileInputStream;
const nsIInputStream = I.nsIInputStream; const nsIInputStream = I.nsIInputStream;
const nsIDOMParser = I.nsIDOMParser;
const nsIDOMDocument = I.nsIDOMDocument; const nsIDOMDocument = I.nsIDOMDocument;
const nsIDOMElement = I.nsIDOMElement; const nsIDOMElement = I.nsIDOMElement;
const nsIDOMNode = I.nsIDOMNode; const nsIDOMNode = I.nsIDOMNode;
const nsIDOMNodeList = I.nsIDOMNodeList; const nsIDOMNodeList = I.nsIDOMNodeList;
Cu.importGlobalProperties(["XMLSerializer"]); Cu.importGlobalProperties(["DOMParser", "XMLSerializer"]);
function DOMParser() { function getParser() {
var parser = C["@mozilla.org/xmlextras/domparser;1"].createInstance(nsIDOMParser); var parser = new DOMParser();
parser.init(); parser.forceEnableXULXBL();
return parser; return parser;
} }
@ -49,12 +48,12 @@ function ParseFile(file) {
function ParseXML(data) { function ParseXML(data) {
if (typeof(data) == "string") { if (typeof(data) == "string") {
return DOMParser().parseFromString(data, "application/xml"); return getParser().parseFromString(data, "application/xml");
} }
Assert.equal(data instanceof nsIInputStream, true); Assert.equal(data instanceof nsIInputStream, true);
return DOMParser().parseFromStream(data, "UTF-8", data.available(), return getParser().parseFromStream(data, "UTF-8", data.available(),
"application/xml"); "application/xml");
} }

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

@ -6,8 +6,8 @@ var ios = Cc["@mozilla.org/network/io-service;1"].
var prefs = Cc["@mozilla.org/preferences-service;1"]. var prefs = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch); getService(Ci.nsIPrefBranch);
var parser = Cc["@mozilla.org/xmlextras/domparser;1"]. Cu.importGlobalProperties(["DOMParser"]);
createInstance(Ci.nsIDOMParser); var parser = new DOMParser();
var doc; var doc;
@ -21,7 +21,6 @@ var node2;
function run_test() { function run_test() {
prefs.setBoolPref("network.prefetch-next", true); prefs.setBoolPref("network.prefetch-next", true);
parser.init();
doc = parser.parseFromString(docbody, "text/html"); doc = parser.parseFromString(docbody, "text/html");
node1 = doc.getElementById("node1"); node1 = doc.getElementById("node1");

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

@ -18,7 +18,7 @@ function test_generate_xpath()
</body> </body>
</html> </html>
`; `;
let doc = DOMParser().parseFromString(docString, "text/html"); let doc = getParser().parseFromString(docString, "text/html");
// Test generate xpath for body. // Test generate xpath for body.
info("Test generate xpath for body node"); info("Test generate xpath for body node");

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

@ -35,7 +35,7 @@ function getFragment(aNode) {
// Goodies from head_content.js // Goodies from head_content.js
const serializer = new DOMSerializer(); const serializer = new DOMSerializer();
const parser = new DOMParser(); const parser = getParser();
/** /**
* Dump the contents of a document fragment to the console. * Dump the contents of a document fragment to the console.

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

@ -4,6 +4,7 @@
ChromeUtils.import("resource://testing-common/httpd.js"); ChromeUtils.import("resource://testing-common/httpd.js");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
Cu.importGlobalProperties(["DOMParser"]);
var server = new HttpServer(); var server = new HttpServer();
server.start(-1); server.start(-1);
@ -21,8 +22,7 @@ function run_test() {
do_test_pending(); do_test_pending();
server.registerPathHandler("/foo", handler); server.registerPathHandler("/foo", handler);
var parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser); var parser = new DOMParser();
parser.init();
let doc = parser.parseFromString(docbody, "text/html"); let doc = parser.parseFromString(docbody, "text/html");
let xhr = new XMLHttpRequest(); let xhr = new XMLHttpRequest();
xhr.onload = function() { xhr.onload = function() {

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

@ -3,6 +3,5 @@
conformance/00_test_list.txt conformance/00_test_list.txt
conformance/more/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 --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/02/23: Version 1.0.1
- 2012/03/20: Version 1.0.2 - 2012/03/20: Version 1.0.2
- 2013/02/14: Version 1.0.3 - 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 - 2014/11/14: Version 1.0.4
- 2016/11/21: Version 2.0.1

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

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

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

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

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

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

@ -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 limits/00_test_list.txt
misc/00_test_list.txt misc/00_test_list.txt
--min-version 1.0.2 ogles/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 programs/00_test_list.txt
reading/00_test_list.txt reading/00_test_list.txt
renderbuffers/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-aliasing.html
--min-version 1.0.3 gl-bindAttribLocation-matrix.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.4 gl-bindAttribLocation-repeated.html
--min-version 1.0.2 gl-disabled-vertex-attrib.html --min-version 1.0.2 gl-disabled-vertex-attrib.html
gl-enable-vertex-attrib.html gl-enable-vertex-attrib.html
@ -9,3 +10,4 @@ gl-vertexattribpointer.html
gl-vertexattribpointer-offsets.html gl-vertexattribpointer-offsets.html
--min-version 1.0.2 gl-vertex-attrib-render.html --min-version 1.0.2 gl-vertex-attrib-render.html
gl-vertex-attrib-zero-issues.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"/> <link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script> <script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script> <script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/tests/gl-bindattriblocation-aliasing.js"></script>
<title>bindAttribLocation with aliasing</title> <title>bindAttribLocation with aliasing</title>
</head> </head>
<body> <body>
@ -50,39 +51,9 @@ var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas"); var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas, {antialias: false}); var gl = wtu.create3DContext(canvas, {antialias: false});
var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER); var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
var typeInfo = [
{ type: 'float', asVec4: 'vec4(0.0, $(var), 0.0, 1.0)' }, runBindAttribLocationAliasingTest(wtu, gl, glFragmentShader, wtu.getScript('vertexShader'));
{ 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);
}
});
});
var successfullyParsed = true; var successfullyParsed = true;
</script> </script>
<script src="../../js/js-test-post.js"></script> <script src="../../js/js-test-post.js"></script>

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2014 The Khronos Group Inc. ** 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"); wtu.checkCanvas(gl, [0, 255, 0, 255], "canvas should be green");
gl.disableVertexAttribArray(3); 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 // 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. // attrib 0 and it was never re-enabled so this next draw failed.
gl.useProgram(p3); gl.useProgram(p3);

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

@ -59,14 +59,28 @@ if (!gl) {
gl.FIXED = 0x140C; 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(); var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject); gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(0), gl.STATIC_DRAW); 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) { if (wtu.getDefault3DContextVersion() < 2) {
gl.vertexAttribPointer(0, 1, gl.INT, 0, 0, 0); gl.vertexAttribPointer(0, 1, gl.INT, 0, 0, 0);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, wtu.glErrorShouldBe(gl, gl.INVALID_ENUM,

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

@ -1,6 +1,7 @@
buffer-bind-test.html buffer-bind-test.html
buffer-data-and-buffer-sub-data.html buffer-data-and-buffer-sub-data.html
--min-version 1.0.3 buffer-data-array-buffer-delete.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.4 buffer-uninitialized.html
--min-version 1.0.2 element-array-buffer-delete-recreate.html --min-version 1.0.2 element-array-buffer-delete-recreate.html
index-validation-copies-indices.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 ]); var indices = new Uint16Array([ 10000, 0, 1, 2, 3, 10000 ]);
context.bufferData(context.ELEMENT_ARRAY_BUFFER, indices, context.STATIC_DRAW); 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.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)"); var indexValidationError = wtu.shouldGenerateGLError(context,
wtu.shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)"); [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[0] = 2;
indices[5] = 1; indices[5] = 1;
wtu.shouldGenerateGLError(context, context.NO_ERROR, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 2)"); 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, indexValidationError, "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("") debug("")
var successfullyParsed = true; var successfullyParsed = true;

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

@ -58,9 +58,9 @@ var indexObject = context.createBuffer();
debug("Test out of range indices") debug("Test out of range indices")
context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexObject); context.bindBuffer(context.ELEMENT_ARRAY_BUFFER, indexObject);
context.bufferData(context.ELEMENT_ARRAY_BUFFER, new Uint16Array([ 10000, 0, 1, 2, 3, 10000 ]), context.STATIC_DRAW); 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.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, indexValidationError, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
wtu.shouldGenerateGLError(context, context.INVALID_OPERATION, "context.drawElements(context.TRIANGLE_STRIP, 4, context.UNSIGNED_SHORT, 4)");
debug("") debug("")
var successfullyParsed = true; var successfullyParsed = true;

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

@ -110,7 +110,7 @@ gl.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT),
gl.enableVertexAttribArray(normalLoc); gl.enableVertexAttribArray(normalLoc);
wtu.glErrorShouldBe(gl, gl.NO_ERROR); wtu.glErrorShouldBe(gl, gl.NO_ERROR);
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0)'); 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"); 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.2 framebuffer-bindings-unaffected-on-resize.html
--min-version 1.0.4 framebuffer-bindings-affected-by-to-data-url.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.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 texture-bindings-unaffected-on-resize.html
--min-version 1.0.2 to-data-url-test.html --min-version 1.0.2 to-data-url-test.html
viewport-unchanged-upon-resize.html viewport-unchanged-upon-resize.html

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

@ -104,11 +104,14 @@ if (!gl) {
g2d = imgData.data[offset + 1]; g2d = imgData.data[offset + 1];
b2d = imgData.data[offset + 2]; b2d = imgData.data[offset + 2];
a2d = imgData.data[offset + 3]; a2d = imgData.data[offset + 3];
//debug('' + x + ', ' + y + "(" + offset + ") = " + r2d + ", " + g2d + ", " + b2d + ", " + a2d); var res = isAboutEqualInt(r2d, r3d) &&
return isAboutEqualInt(r2d, r3d) && isAboutEqualInt(g2d, g3d) &&
isAboutEqualInt(g2d, g3d) && isAboutEqualInt(b2d, b3d) &&
isAboutEqualInt(b2d, b3d) && isAboutEqualInt(a2d, a3d);
isAboutEqualInt(a2d, a3d); if (!res) {
bufferedLogToConsole('at ' + x + ', ' + y + " (offset " + offset + ") = " + r2d + ", " + g2d + ", " + b2d + ", " + a2d);
}
return res;
} }
var checkPixels = function(r3d,g3d,b3d,a3d) { 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. ** 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 // added in versions of the spec that are backward-compatible with
// this version // this version
var ignoredProperties = [ var ignoredProperties = [
'STENCIL_INDEX'
]; ];
// Constants removed from the WebGL spec compared to ES 2.0 // Constants removed from the WebGL spec compared to ES 2.0

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

@ -156,6 +156,8 @@ function testLosingAndRestoringContext()
testLostContext(e); testLostContext(e);
// restore the context after this event has exited. // restore the context after this event has exited.
setTimeout(function() { 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()"); shouldGenerateGLError(gl, gl.NO_ERROR, "WEBGL_lose_context.restoreContext()");
// The context should still be lost. It will not get restored until the // The context should still be lost. It will not get restored until the
// webglrestorecontext event is fired. // webglrestorecontext event is fired.

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

@ -25,6 +25,7 @@
--min-version 1.0.2 --max-version 1.9.9 oes-element-index-uint.html --min-version 1.0.2 --max-version 1.9.9 oes-element-index-uint.html
webgl-debug-renderer-info.html webgl-debug-renderer-info.html
webgl-debug-shaders.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.3 webgl-compressed-texture-atc.html
--min-version 1.0.4 webgl-compressed-texture-etc.html --min-version 1.0.4 webgl-compressed-texture-etc.html
--min-version 1.0.3 webgl-compressed-texture-pvrtc.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.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.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.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-framebuffer-unsupported.html
--min-version 1.0.4 --max-version 1.9.9 webgl-draw-buffers-max-draw-buffers.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 --min-version 1.0.3 webgl-shared-resources.html

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2013 The Khronos Group Inc. ** Copyright (c) 2013 The Khronos Group Inc.
@ -119,6 +119,8 @@ if (!gl) {
runDrawArraysWithOffsetTest(); runDrawArraysWithOffsetTest();
runVAOInstancingInteractionTest(); runVAOInstancingInteractionTest();
runANGLECorruptionTest(); 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{ else{
testFailed("Set value of VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE should be: 2, returned value was: " + queried_value); 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() { function setupCanvas() {
@ -351,6 +356,10 @@ function runOutputTests() {
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with QUADS should return INVALID_ENUM"); wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with QUADS should return INVALID_ENUM");
ext.drawElementsInstancedANGLE(desktopGL['POLYGON'], 6, gl.UNSIGNED_SHORT, 0, instanceCount); ext.drawElementsInstancedANGLE(desktopGL['POLYGON'], 6, gl.UNSIGNED_SHORT, 0, instanceCount);
wtu.glErrorShouldBe(gl, gl.INVALID_ENUM, "drawElementsInstancedANGLE with POLYGON should return INVALID_ENUM"); 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) function runDrawArraysTest(program, first, count, instanceCount, offset)
@ -404,6 +413,9 @@ function runDrawArraysTest(program, first, count, instanceCount, offset)
// Do the instanced draw // Do the instanced draw
ext.drawArraysInstancedANGLE(gl.TRIANGLES, first, count, instanceCount); ext.drawArraysInstancedANGLE(gl.TRIANGLES, first, count, instanceCount);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "drawArraysInstancedANGLE should succeed"); 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() function runDrawArraysWithOffsetTest()

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2014 The Khronos Group Inc. ** Copyright (c) 2014 The Khronos Group Inc.

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

@ -65,19 +65,24 @@ if (!gl) {
testPassed("No EXT_disjoint_timer_query support -- this is legal"); testPassed("No EXT_disjoint_timer_query support -- this is legal");
finishTest(); finishTest();
} else { } 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. // Clear disjoint value.
gl.getParameter(ext.GPU_DISJOINT_EXT); gl.getParameter(ext.GPU_DISJOINT_EXT);
runElapsedTimeTest(); runElapsedTimeTest();
timestamp_counter_bits = ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT); timestamp_counter_bits = ext.getQueryEXT(ext.TIMESTAMP_EXT, ext.QUERY_COUNTER_BITS_EXT);
if (timestamp_counter_bits > 0) { if (timestamp_counter_bits > 0) {
runTimeStampTest(); runTimeStampTest();
}
verifyQueryResultsNotAvailable();
window.requestAnimationFrame(checkQueryResults);
} }
verifyQueryResultsNotAvailable();
window.requestAnimationFrame(checkQueryResults);
} }
} }

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2013 The Khronos Group Inc. ** Copyright (c) 2013 The Khronos Group Inc.

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

@ -4,7 +4,6 @@
<meta charset="utf-8"/> <meta charset="utf-8"/>
<link rel="stylesheet" href="../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script> <script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test.js"></script>
<script src="../../js/webgl-test-utils.js"></script> <script src="../../js/webgl-test-utils.js"></script>
</head> </head>
<body> <body>
@ -28,6 +27,27 @@ void main() {
} }
</script> </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> <script>
"use strict"; "use strict";
@ -227,6 +247,7 @@ if (!gl) {
runFramebufferTextureConversionTest(ext.SRGB_EXT); runFramebufferTextureConversionTest(ext.SRGB_EXT);
runFramebufferTextureConversionTest(ext.SRGB_ALPHA_EXT); runFramebufferTextureConversionTest(ext.SRGB_ALPHA_EXT);
runFramebufferRenderbufferConversionTest(); runFramebufferRenderbufferConversionTest();
runGenerateMipmapTest();
runLoadFromImageTest(function() { runLoadFromImageTest(function() {
finishTest(); 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; var successfullyParsed = true;
</script> </script>
</body> </body>

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2014 The Khronos Group Inc. ** Copyright (c) 2014 The Khronos Group Inc.

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>. ** Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>.

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2012 The Khronos Group Inc. ** 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.vertexAttribPointer(normalLoc, 3, gl.FLOAT, false, 7 * sizeInBytes(gl.FLOAT), 4 * sizeInBytes(gl.FLOAT));
gl.enableVertexAttribArray(normalLoc); gl.enableVertexAttribArray(normalLoc);
wtu.glErrorShouldBe(gl, gl.NO_ERROR); wtu.glErrorShouldBe(gl, gl.NO_ERROR);
shouldBeUndefined('gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)'); wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION); 'gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, 0)');
debug("Test with enabled attribute that does not belong to current program"); 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 ]); var indices = new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, drawType); 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.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)"); var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)"); "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[0] = 2;
indices[5] = 1; indices[5] = 1;
wtu.shouldGenerateGLError(gl, gl.NO_ERROR, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 4)"); 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, indexValidationError, "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, 8)");
} }
function runResizedBufferTests(drawType) { function runResizedBufferTests(drawType) {
@ -422,8 +423,9 @@ function runVerifiesTooManyIndicesTests(drawType) {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array([ 10000, 0, 1, 2, 3, 10000 ]), drawType); 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.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)"); var indexValidationError = wtu.shouldGenerateGLError(gl, [gl.INVALID_OPERATION, gl.NO_ERROR],
wtu.shouldGenerateGLError(gl, gl.INVALID_OPERATION, "gl.drawElements(gl.TRIANGLE_STRIP, 4, gl.UNSIGNED_INT, 8)"); "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) { function runCrashWithBufferSubDataTests(drawType) {

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2012 The Khronos Group Inc. ** Copyright (c) 2012 The Khronos Group Inc.

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

@ -82,41 +82,72 @@ var canvas = document.getElementById("canvas");
var gl = wtu.create3DContext(canvas); var gl = wtu.create3DContext(canvas);
if (!gl) { if (!gl) {
testFailed("WebGL context does not exist"); testFailed("WebGL context does not exist");
} else { } else {
testPassed("WebGL context exists"); testPassed("WebGL context exists");
var texturedShaders = [ var texturedShaders = [
wtu.simpleTextureVertexShader, wtu.simpleTextureVertexShader,
"testFragmentShader" "testFragmentShader"
]; ];
var testProgram = var testProgram =
wtu.setupProgram(gl, wtu.setupProgram(gl,
texturedShaders, texturedShaders,
['vPosition', 'texCoord0'], ['vPosition', 'texCoord0'],
[0, 1]); [0, 1]);
var quadParameters = wtu.setupUnitQuad(gl, 0, 1); var quadParameters = wtu.setupUnitQuad(gl, 0, 1);
// First verify that allocation of floating-point textures fails if // First verify that allocation of floating-point textures fails if
// the extension has not been enabled yet. // the extension has not been enabled yet.
runTextureCreationTest(testProgram, false); runTextureCreationTest(testProgram, false);
if (!gl.getExtension("OES_texture_float")) { if (!gl.getExtension("OES_texture_float")) {
testPassed("No OES_texture_float support -- this is legal"); testPassed("No OES_texture_float support -- this is legal");
} else { } else {
testPassed("Successfully enabled OES_texture_float extension"); 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 // 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.RGBA, 4, [10000, 10000, 10000, 10000]);
runTextureCreationTest(testProgram, true, gl.RGB, 3, [10000, 10000, 10000, 1]); runTextureCreationTest(testProgram, true, gl.RGB, 3, [10000, 10000, 10000, 1]);
runTextureCreationTest(testProgram, true, gl.LUMINANCE, 1, [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.ALPHA, 1, [0, 0, 0, 10000]);
runTextureCreationTest(testProgram, true, gl.LUMINANCE_ALPHA, 2, [10000, 10000, 10000, 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); (function() {
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 1); debug("");
runRenderTargetAndReadbackTest(testProgram, gl.RGBA, 4, [10000, 10000, 10000, 10000], 0.5); var renderable = isRenderable(gl);
runUniqueObjectTest(); 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() function allocateTexture()
@ -189,7 +220,7 @@ function arrayToString(arr, size) {
return out + "]"; return out + "]";
} }
function runRenderTargetAndReadbackTest(testProgram, format, numberOfChannels, subtractor, texSubImageCover) function runRenderTargetAndReadbackTest(testProgram, format, numberOfChannels, subtractor, texSubImageCover, requireRenderable)
{ {
var formatString = wtu.glEnumToString(gl, format); var formatString = wtu.glEnumToString(gl, format);
debug(""); 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 // 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. // support floating-point textures but not as attachments to framebuffer objects.
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { 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; return;
} }

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

@ -82,6 +82,7 @@ var gl = wtu.create3DContext(canvas);
var halfFloatOESEnum = 0x8D61; var halfFloatOESEnum = 0x8D61;
var ext = null; var ext = null;
if (!gl) { if (!gl) {
testFailed("WebGL context does not exists"); testFailed("WebGL context does not exists");
} else { } else {
@ -157,8 +158,8 @@ if (!gl) {
// Next check that values outside the 0-1 range can be written. // Next check that values outside the 0-1 range can be written.
var halfFloatTenK = 0x70E2; // Half float 10000 var halfFloatTenK = 0x70E2; // Half float 10000
var uint16Formats2 = [ var uint16Formats2 = [
{ format: gl.RGBA, subtractor: [10000, 10000, 10000, 10000], }, { format: gl.RGBA, subtractor: [10000, 10000, 10000, 10000], requireRenderable: true},
{ format: gl.RGB, subtractor: [10000, 10000, 10000, 1], }, { format: gl.RGB, subtractor: [10000, 10000, 10000, 1], requireRenderable: false},
]; ];
uint16Formats2.forEach(function(f) { uint16Formats2.forEach(function(f) {
@ -170,20 +171,47 @@ if (!gl) {
for (var ii = 0; ii < uint16Data.length; ii++) { for (var ii = 0; ii < uint16Data.length; ii++) {
uint16Data[ii] = halfFloatTenK; 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) (function() {
runRenderTest(gl.RGBA, [10000, 10000, 10000, 10000], null); debug("");
runRenderTest(gl.RGB, [10000, 10000, 10000, 1], null); var renderable = isRenderable(gl, ext);
var renderableExtName = "EXT_color_buffer_half_float";
runFramebufferTest(); 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 // Check of getExtension() returns same object
runUniqueObjectTest(); 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) function getNumberOfChannels(format)
{ {
if (format == gl.RGBA) if (format == gl.RGBA)
@ -278,7 +306,7 @@ function checkRenderingResults()
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green"); 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); 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 // 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. // support half floating point textures but not as attachments to framebuffer objects.
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) { 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; return;
} }
@ -397,16 +429,12 @@ function runFramebufferTest() {
var texture = allocateTexture(); var texture = allocateTexture();
gl.bindTexture(gl.TEXTURE_2D, texture); 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(); var fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); 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"); debug("Ensure non-color-renderable formats [LUMINANCE, LUMINANCE_ALPHA, ALPHA] fail.");
return;
}
debug("Ensure non-color-renderable formats [LUMINANCE, LUMINANCE_ALPHA, ALPHA] fail");
var arrayBufferFloatOutput = new Float32Array(4); // 4 color channels var arrayBufferFloatOutput = new Float32Array(4); // 4 color channels
[gl.LUMINANCE, gl.LUMINANCE_ALPHA, gl.ALPHA].forEach(function(badFormat) { [gl.LUMINANCE, gl.LUMINANCE_ALPHA, gl.ALPHA].forEach(function(badFormat) {
debug(getFormatName(badFormat) + " framebuffer"); debug(getFormatName(badFormat) + " framebuffer");
@ -437,51 +465,49 @@ function runFramebufferTest() {
debug(""); debug("");
gl.texImage2D(gl.TEXTURE_2D, 0, goodFormat, 1, 1, 0, goodFormat, ext.HALF_FLOAT_OES, arrayBufferHalfFloatInput); gl.texImage2D(gl.TEXTURE_2D, 0, goodFormat, 1, 1, 0, goodFormat, ext.HALF_FLOAT_OES, arrayBufferHalfFloatInput);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE) {
// Per the OES_color_buffer_half_float, RGBA/FLOAT should always succeed for readPixels
// 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) {
verifyReadPixelsColors( verifyReadPixelsColors(
0, // red 0.00, // red
0x3400, // green 0.25, // green
0x3800, // blue 0.50, // blue
0x3A00, // alpha 0.75, // alpha
0x3C00, // alphaRGB 1.0, // alphaRGB
goodFormat, goodFormat,
ext.HALF_FLOAT_OES, gl.FLOAT,
Uint16Array); 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(""); debug("");
}); });

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2014 The Khronos Group Inc. ** Copyright (c) 2014 The Khronos Group Inc.

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2012 The Khronos Group Inc. ** Copyright (c) 2012 The Khronos Group Inc.
@ -624,25 +624,33 @@ function runBoundDeleteTests() {
gl.deleteBuffer(colorBuffer); gl.deleteBuffer(colorBuffer);
gl.deleteBuffer(positionBuffer); gl.deleteBuffer(positionBuffer);
// The buffers should not be accessible at this point. Deleted objects that are bound // After the first iteration, deleteBuffer will be a no-op, and will not unbind its matching
// in the current context undergo an automatic unbinding // 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); var boundPositionBuffer = gl.getVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
if(boundPositionBuffer == positionBuffer) { if (expectRetained != (boundPositionBuffer == positionBuffer)) {
testFailed("Position buffer should be automatically unbound when deleted"); testFailed("Position attrib stored buffer should be " + shouldBeStr + ".");
} }
var boundColorBuffer = gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING); var boundColorBuffer = gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
if(boundColorBuffer == colorBuffer) { if (expectRetained != (boundColorBuffer == colorBuffer)) {
testFailed("Color buffer should be automatically unbound when deleted"); 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); 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); if (!gl.isBuffer(positionBuffer)) {
var isColorBuffer = gl.isBuffer(colorBuffer); testFailed("References from unbound VAOs keep Position buffer alive.");
}
if(isPositionBuffer) testFailed("Position buffer should no longer exist after last ref removed"); if (!gl.isBuffer(colorBuffer)) {
if(isColorBuffer) testFailed("Color buffer should no longer exist after last ref removed"); testFailed("References from unbound VAOs keep Color buffer alive");
}
} }
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2013 The Khronos Group Inc. ** Copyright (c) 2013 The Khronos Group Inc.
@ -204,12 +204,8 @@ function runTestExtension() {
} }
supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS); supportedFormats = gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS);
// There should be exactly 3 formats for WebGL 1.0 and 13 formats for WebGL 2.0. // There should be exactly 3 formats for both WebGL 1.0 and WebGL 2.0.
if (contextVersion < 2) { shouldBe("supportedFormats.length", "3");
shouldBe("supportedFormats.length", "3");
} else {
shouldBe("supportedFormats.length", "13");
}
// check that all 3 formats exist // check that all 3 formats exist
for (var name in validFormats.length) { for (var name in validFormats.length) {

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

@ -61,7 +61,8 @@ var COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
var COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279; var COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279;
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
var gl = wtu.create3DContext(undefined, undefined); var contextVersion = wtu.getDefault3DContextVersion();
var gl = wtu.create3DContext();
var WEBGL_compressed_texture_etc; var WEBGL_compressed_texture_etc;
var formats = null; var formats = null;
@ -89,7 +90,7 @@ function runTest() {
} }
} else { } else {
if (WEBGL_compressed_texture_etc !== null) { 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; return;
} else { } else {
testPassed("No WEBGL_compressed_texture_etc support -- this is legal"); testPassed("No WEBGL_compressed_texture_etc support -- this is legal");
@ -138,10 +139,19 @@ function runTest() {
shouldBe("formats.length", isPositive ? "10" : "0"); shouldBe("formats.length", isPositive ? "10" : "0");
debug(""); debug("");
shouldThrow("gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_R11_EAC, 4, 4, 0, null)"); if (contextVersion >= 2) {
shouldThrow("gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, COMPRESSED_R11_EAC, null)"); var expectedError = isPositive ? gl.INVALID_OPERATION: [gl.INVALID_ENUM, gl.INVALID_OPERATION];
shouldThrow("gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, COMPRESSED_R11_EAC, 4, 4, 4, 0, null)"); // `null` coerces into `0` for the PBO entrypoint, yielding INVALID_OP due to no PBO bound.
shouldThrow("gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 0, COMPRESSED_R11_EAC, null)"); 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. ** Copyright (c) 2013 The Khronos Group Inc.

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2012-2016 The Khronos Group Inc. ** Copyright (c) 2012-2016 The Khronos Group Inc.

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2012 The Khronos Group Inc. ** Copyright (c) 2012 The Khronos Group Inc.

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

@ -33,6 +33,7 @@
<link rel="stylesheet" href="../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script> <script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script> <script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/tests/webgl-compressed-texture-size-limit.js"></script>
</head> </head>
<body> <body>
<canvas id="example" width="32" height="32" style="width: 40px; height: 40px;"></canvas> <canvas id="example" width="32" height="32" style="width: 40px; height: 40px;"></canvas>
@ -42,202 +43,11 @@
"use strict"; "use strict";
enableJSTestPreVerboseLogging(); enableJSTestPreVerboseLogging();
description("Checks size limit of the webgl compressed textures") description("Checks size limit of the webgl compressed textures")
var canvas;
function numLevelsFromSize(size) { // 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.
var levels = 0; // 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.
while ((size >> levels) > 0) { // Use a fairly conservative limit for positive test cube map size so OOM is avoided.
++levels; runCompressedTextureSizeLimitTest(Math.pow(2, 30), 2048);
}
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");
}
var successfullyParsed = true; var successfullyParsed = true;
</script> </script>

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2012 The Khronos Group Inc. ** Copyright (c) 2012 The Khronos Group Inc.

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2012 The Khronos Group Inc. ** Copyright (c) 2012 The Khronos Group Inc.

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

@ -89,7 +89,8 @@ if (!gl) {
testPassed("Successfully enabled WEBGL_depth_texture extension"); testPassed("Successfully enabled WEBGL_depth_texture extension");
runSupportedTest(true); runSupportedTest(true);
runTestExtension(); runTestExtension(true);
runTestExtension(false);
} }
} }
@ -138,8 +139,8 @@ function dumpIt(gl, res, msg) {
debug(strs.join(" ")); debug(strs.join(" "));
} }
} }
function runTestExtension() { function runTestExtension(unpackFlipY) {
debug("Testing WEBGL_depth_texture"); debug("Testing WEBGL_depth_texture. UNPACK_FLIP_Y_WEBGL: " + unpackFlipY);
var res = 8; var res = 8;
@ -171,6 +172,8 @@ function runTestExtension() {
gl.enableVertexAttribArray(0); gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0); gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, unpackFlipY);
var types = [ 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_SHORT', data: 'new Uint16Array(1)', depthBits: "16"},
{obj: 'gl', attachment: 'DEPTH_ATTACHMENT', format: 'DEPTH_COMPONENT', type: 'UNSIGNED_INT', data: 'new Uint32Array(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' 'TEXTURE_CUBE_MAP_NEGATIVE_Z'
]; ];
for (var tt = 0; tt < targets.length; ++tt) { 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 // 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. ** Copyright (c) 2015 The Khronos Group Inc.

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2013 The Khronos Group Inc. ** Copyright (c) 2013 The Khronos Group Inc.
@ -33,17 +33,12 @@
<link rel="stylesheet" href="../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../js/js-test-pre.js"></script> <script src="../../js/js-test-pre.js"></script>
<script src="../../js/webgl-test-utils.js"></script> <script src="../../js/webgl-test-utils.js"></script>
<script src="../../js/tests/webgl-draw-buffers-utils.js"></script>
</head> </head>
<body> <body>
<div id="description"></div> <div id="description"></div>
<canvas id="canvas" width="64" height="64"> </canvas> <canvas id="canvas" width="64" height="64"> </canvas>
<div id="console"></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"> <script id="fshader" type="x-shader/x-fragment">
#extension GL_EXT_draw_buffers : require #extension GL_EXT_draw_buffers : require
precision mediump float; precision mediump float;
@ -111,10 +106,10 @@ debug("");
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas"); var canvas = document.getElementById("canvas");
var output = document.getElementById("console");
var gl = wtu.create3DContext(canvas); var gl = wtu.create3DContext(canvas);
var ext = null; var ext = null;
var programWithMaxDrawBuffersEqualOne = null; var programWithMaxDrawBuffersEqualOne = null;
var drawBuffersUtils;
var extensionConstants = [ var extensionConstants = [
{ name: "MAX_COLOR_ATTACHMENTS_WEBGL", enum: 0x8CDF, expectedFn: function(v) { return v >= 4; }, passMsg: " should be >= 4"}, { name: "MAX_COLOR_ATTACHMENTS_WEBGL", enum: 0x8CDF, expectedFn: function(v) { return v >= 4; }, passMsg: " should be >= 4"},
@ -177,6 +172,7 @@ if (!gl) {
} else { } else {
testPassed("Successfully enabled WEBGL_draw_buffers extension"); testPassed("Successfully enabled WEBGL_draw_buffers extension");
drawBuffersUtils = WebGLDrawBuffersUtils(gl, ext);
runSupportedTest(true); runSupportedTest(true);
runEnumTestEnabled(); runEnumTestEnabled();
runShadersTestEnabled(); runShadersTestEnabled();
@ -189,7 +185,7 @@ if (!gl) {
function createExtDrawBuffersProgram(scriptId, sub) { function createExtDrawBuffersProgram(scriptId, sub) {
var fsource = wtu.getScript(scriptId); var fsource = wtu.getScript(scriptId);
fsource = wtu.replaceParams(fsource, sub); 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) { function runSupportedTest(extensionEnabled) {
@ -254,8 +250,8 @@ function runEnumTestEnabled() {
function testShaders(tests, sub) { function testShaders(tests, sub) {
tests.forEach(function(test) { tests.forEach(function(test) {
var shaders = [wtu.getScript(test.shaders[0]), wtu.replaceParams(wtu.getScript(test.shaders[1]), sub)]; var shaders = [wtu.simpleVertexShader, wtu.replaceParams(wtu.getScript(test.fragmentShaderTemplate), sub)];
var program = wtu.setupProgram(gl, shaders, ["a_position"], undefined, true); var program = wtu.setupProgram(gl, shaders, ["vPosition"], undefined, true);
var programLinkedSuccessfully = (program != null); var programLinkedSuccessfully = (program != null);
var expectedProgramToLinkSuccessfully = (test.expectFailure == true); var expectedProgramToLinkSuccessfully = (test.expectFailure == true);
expectTrue(programLinkedSuccessfully != expectedProgramToLinkSuccessfully, test.msg); expectTrue(programLinkedSuccessfully != expectedProgramToLinkSuccessfully, test.msg);
@ -269,10 +265,10 @@ function runShadersTestDisabled() {
var sub = {numDrawingBuffers: 1}; var sub = {numDrawingBuffers: 1};
testShaders([ testShaders([
{ shaders: ["vshader", "fshaderMacroDisabled"], { fragmentShaderTemplate: "fshaderMacroDisabled",
msg: "GL_EXT_draw_buffers should not be defined in GLSL", 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", msg: "#extension GL_EXT_draw_buffers should not be allowed in GLSL",
expectFailure: true, expectFailure: true,
}, },
@ -291,11 +287,11 @@ function runShadersTestEnabled() {
var sub = {numDrawingBuffers: gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL)}; var sub = {numDrawingBuffers: gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL)};
testShaders([ testShaders([
{ shaders: ["vshader", "fshaderMacroEnabled"], { fragmentShaderTemplate: "fshaderMacroEnabled",
msg: "GL_EXT_draw_buffers should be defined as 1 in GLSL", msg: "GL_EXT_draw_buffers should be defined as 1 in GLSL",
}, },
{ shaders: ["vshader", "fshader"], { fragmentShaderTemplate: "fshader",
msg: "fragment shader containing the #extension directive should compile", msg: "fragment shader containing the #extension directive should compile",
}, },
], sub); ], sub);
@ -337,14 +333,6 @@ function makeArray(size, value) {
return array; return array;
} }
function makeColorAttachmentArray(size) {
var array = []
for (var ii = 0; ii < size; ++ii) {
array.push(gl.COLOR_ATTACHMENT0 + ii);
}
return array;
}
function runAttachmentTestEnabled() { function runAttachmentTestEnabled() {
debug(""); debug("");
debug("test attachment enabled"); 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)); 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)); ext.drawBuffersWEBGL(makeArray(maxDrawingBuffers, gl.NONE));
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffersWEBGL with array NONE of size " + maxColorAttachments); 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); ext.drawBuffersWEBGL(bufs);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffersWEBGL with array attachments of size " + maxColorAttachments); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffersWEBGL with array attachments of size " + maxColorAttachments);
bufs[0] = gl.NONE; bufs[0] = gl.NONE;
@ -373,7 +361,7 @@ function runAttachmentTestEnabled() {
bufs[1] = ext.COLOR_ATTACHMENT0_WEBGL; bufs[1] = ext.COLOR_ATTACHMENT0_WEBGL;
ext.drawBuffersWEBGL(bufs); ext.drawBuffersWEBGL(bufs);
wtu.glErrorShouldBe(gl, gl.INVALID_OPERATION, "should not be able to call drawBuffersWEBGL with out of order attachments of size " + maxColorAttachments); 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); ext.drawBuffersWEBGL(bufs);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "should be able to call drawBuffersWEBGL with short array of attachments of size " + bufs.length); 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 middleFB = gl.createFramebuffer();
var maxDrawingBuffers = gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL); var maxDrawingBuffers = gl.getParameter(ext.MAX_DRAW_BUFFERS_WEBGL);
var maxColorAttachments = gl.getParameter(ext.MAX_COLOR_ATTACHMENTS_WEBGL); var maxUsable = drawBuffersUtils.getMaxUsableColorAttachments();
var maxUniformVectors = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);
var maxUsable = Math.min(maxDrawingBuffers, maxColorAttachments, maxUniformVectors);
var half = Math.floor(maxUsable / 2); var half = Math.floor(maxUsable / 2);
var bufs = makeColorAttachmentArray(maxUsable); var bufs = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
var nones = makeArray(maxUsable, gl.NONE); var nones = makeArray(maxUsable, gl.NONE);
[fb, fb2, halfFB1, halfFB2, endsFB, middleFB].forEach(function(fbo) { [fb, fb2, halfFB1, halfFB2, endsFB, middleFB].forEach(function(fbo) {
@ -430,8 +416,8 @@ function runDrawTests() {
}); });
var checkProgram = wtu.setupTexturedQuad(gl); var checkProgram = wtu.setupTexturedQuad(gl);
var redProgram = wtu.setupProgram(gl, ["vshader", "fshaderRed"], ["a_position"]); var redProgram = wtu.setupProgram(gl, [wtu.simpleVertexShader, "fshaderRed"], ["vPosition"]);
var redProgramWithExtension = wtu.setupProgram(gl, ["vshader", "fshaderRedWithExtension"], ["a_position"]); var redProgramWithExtension = wtu.setupProgram(gl, [wtu.simpleVertexShader, "fshaderRedWithExtension"], ["vPosition"]);
var drawProgram = createExtDrawBuffersProgram("fshader", {numDrawingBuffers: maxDrawingBuffers}); var drawProgram = createExtDrawBuffersProgram("fshader", {numDrawingBuffers: maxDrawingBuffers});
var width = 64; var width = 64;
var height = 64; var height = 64;
@ -464,7 +450,6 @@ function runDrawTests() {
gl.uniform4fv(location, floatColor); gl.uniform4fv(location, floatColor);
attachments.push({ attachments.push({
texture: tex, texture: tex,
location: location,
color: color color: color
}); });
} }
@ -473,30 +458,6 @@ function runDrawTests() {
gl.bindFramebuffer(gl.FRAMEBUFFER, fb2); gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE"); 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) { var drawAndCheckAttachments = function(testFB, msg, testFn) {
debug("test clearing " + msg); debug("test clearing " + msg);
@ -517,7 +478,7 @@ function runDrawTests() {
gl.bindFramebuffer(gl.FRAMEBUFFER, fb2); gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
gl.clearColor(0, 0, 0, 0); gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT); gl.clear(gl.COLOR_BUFFER_BIT);
//checkAttachmentsForColorFn(attachments, function(attachment, index) { //drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
// return [0, 0, 0, 0]; // return [0, 0, 0, 0];
//}); //});
//debug("--"); //debug("--");
@ -527,7 +488,7 @@ function runDrawTests() {
gl.clearColor(0, 1, 0, 1); gl.clearColor(0, 1, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT); 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]; return testFn(attachment, index) ? [0, 255, 0, 255] : [0, 0, 0, 0];
}); });
@ -538,7 +499,7 @@ function runDrawTests() {
gl.bindFramebuffer(gl.FRAMEBUFFER, testFB); gl.bindFramebuffer(gl.FRAMEBUFFER, testFB);
wtu.drawUnitQuad(gl); wtu.drawUnitQuad(gl);
checkAttachmentsForColorFn(attachments, function(attachment, index) { drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
return testFn(attachment, index) ? attachment.color : [0, 0, 0, 0]; 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."); debug("test that each texture got the correct color.");
checkAttachmentsForColor(attachments); drawBuffersUtils.checkAttachmentsForColor(attachments);
debug("test clearing clears all the textures"); debug("test clearing clears all the textures");
gl.bindFramebuffer(gl.FRAMEBUFFER, fb); gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.clearColor(0, 1, 0, 1); gl.clearColor(0, 1, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT); 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"); 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"); wtu.glErrorShouldBe(gl, gl.NO_ERROR, "Should be no GL error setting up the program");
if (!noWriteProgram) { if (!noWriteProgram) {
testFailed("Setup a program where fragment shader writes nothing failed"); testFailed("Setup a program where fragment shader writes nothing failed");
@ -571,7 +532,7 @@ function runDrawTests() {
gl.useProgram(noWriteProgram); gl.useProgram(noWriteProgram);
wtu.drawUnitQuad(gl); wtu.drawUnitQuad(gl);
checkAttachmentsForColor(attachments, [0, 255, 0, 255]); drawBuffersUtils.checkAttachmentsForColor(attachments, [0, 255, 0, 255]);
gl.deleteProgram(noWriteProgram); gl.deleteProgram(noWriteProgram);
} }
@ -581,7 +542,7 @@ function runDrawTests() {
gl.useProgram(redProgram); gl.useProgram(redProgram);
wtu.clearAndDrawUnitQuad(gl); 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"); debug("test that gl_FragColor does not broadcast unless extension is enabled in fragment shader");
gl.bindFramebuffer(gl.FRAMEBUFFER, fb); gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
@ -589,7 +550,7 @@ function runDrawTests() {
gl.useProgram(redProgram); gl.useProgram(redProgram);
wtu.drawUnitQuad(gl); 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]; return (index == 0) ? [255, 0, 0, 255] : [0, 255, 0, 255];
}); });
@ -600,17 +561,17 @@ function runDrawTests() {
gl.useProgram(redProgramWithExtension); gl.useProgram(redProgramWithExtension);
wtu.drawUnitQuad(gl); wtu.drawUnitQuad(gl);
checkAttachmentsForColor(attachments, [255, 0, 0, 255]); drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
if (maxUsable > 1) { if (maxUsable > 1) {
// First half of color buffers disable. // First half of color buffers disable.
var bufs1 = makeColorAttachmentArray(maxUsable); var bufs1 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
// Second half of color buffers disable. // Second half of color buffers disable.
var bufs2 = makeColorAttachmentArray(maxUsable); var bufs2 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
// Color buffers with even indices disabled. // Color buffers with even indices disabled.
var bufs3 = makeColorAttachmentArray(maxUsable); var bufs3 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
// Color buffers with odd indices disabled. // Color buffers with odd indices disabled.
var bufs4 = makeColorAttachmentArray(maxUsable); var bufs4 = drawBuffersUtils.makeColorAttachmentArray(maxUsable);
for (var ii = 0; ii < maxUsable; ++ii) { for (var ii = 0; ii < maxUsable; ++ii) {
if (ii < half) { if (ii < half) {
bufs1[ii] = gl.NONE; bufs1[ii] = gl.NONE;
@ -637,7 +598,7 @@ function runDrawTests() {
gl.clearColor(0, 1, 0, 1); gl.clearColor(0, 1, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT); 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]; return index < half ? [255, 0, 0, 255] : [0, 255, 0, 255];
}); });
@ -647,7 +608,7 @@ function runDrawTests() {
gl.useProgram(drawProgram); gl.useProgram(drawProgram);
wtu.drawUnitQuad(gl); wtu.drawUnitQuad(gl);
checkAttachmentsForColorFn(attachments, function(attachment, index) { drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
return index < half ? [255, 0, 0, 255] : attachment.color; return index < half ? [255, 0, 0, 255] : attachment.color;
}); });
@ -661,7 +622,7 @@ function runDrawTests() {
ext.drawBuffersWEBGL(bufs2); ext.drawBuffersWEBGL(bufs2);
gl.clearColor(0, 0, 1, 1); gl.clearColor(0, 0, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT); 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]; return index < half ? [0, 0, 255, 255] : [255, 0, 0, 255];
}); });
@ -671,7 +632,7 @@ function runDrawTests() {
gl.useProgram(drawProgram); gl.useProgram(drawProgram);
wtu.drawUnitQuad(gl); wtu.drawUnitQuad(gl);
checkAttachmentsForColorFn(attachments, function(attachment, index) { drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
return index < half ? attachment.color : [255, 0, 0, 255]; return index < half ? attachment.color : [255, 0, 0, 255];
}); });
@ -685,7 +646,7 @@ function runDrawTests() {
gl.clearColor(1, 0, 1, 1); gl.clearColor(1, 0, 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT); 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]; return (index % 2) ? [255, 0, 0, 255] : [255, 0, 255, 255];
}); });
@ -699,7 +660,7 @@ function runDrawTests() {
ext.drawBuffersWEBGL(bufs4); ext.drawBuffersWEBGL(bufs4);
wtu.drawUnitQuad(gl); wtu.drawUnitQuad(gl);
checkAttachmentsForColorFn(attachments, function(attachment, index) { drawBuffersUtils.checkAttachmentsForColorFn(attachments, function(attachment, index) {
return (index % 2 == 0) ? [0, 0, 0, 255] : attachment.color; return (index % 2 == 0) ? [0, 0, 0, 255] : attachment.color;
}); });
@ -747,18 +708,18 @@ function runDrawTests() {
ext.drawBuffersWEBGL(bufs); ext.drawBuffersWEBGL(bufs);
gl.clearColor(1, 0, 0, 1); gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT); 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. // fb2 still has the NONE draw buffers from before, so this draw should be a no-op.
gl.bindFramebuffer(gl.FRAMEBUFFER, fb2); gl.bindFramebuffer(gl.FRAMEBUFFER, fb2);
gl.useProgram(drawProgram); gl.useProgram(drawProgram);
wtu.drawUnitQuad(gl); wtu.drawUnitQuad(gl);
checkAttachmentsForColor(attachments, [255, 0, 0, 255]); drawBuffersUtils.checkAttachmentsForColor(attachments, [255, 0, 0, 255]);
gl.bindFramebuffer(gl.FRAMEBUFFER, fb); gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.useProgram(drawProgram); gl.useProgram(drawProgram);
wtu.drawUnitQuad(gl); wtu.drawUnitQuad(gl);
checkAttachmentsForColor(attachments); drawBuffersUtils.checkAttachmentsForColor(attachments);
debug("test queries"); debug("test queries");
debug("check framebuffer with all attachments on"); 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 literals/00_test_list.txt
--min-version 1.0.2 matrices/00_test_list.txt --min-version 1.0.2 matrices/00_test_list.txt
misc/00_test_list.txt misc/00_test_list.txt
--min-version 1.0.4 preprocessor/00_test_list.txt
reserved/00_test_list.txt reserved/00_test_list.txt
--min-version 1.0.2 samplers/00_test_list.txt --min-version 1.0.2 samplers/00_test_list.txt
variables/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-d3d11-compiler-error.html
--min-version 1.0.3 angle-dx-variable-bug.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.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.4 bool-type-cast-bug-int-float.html
--min-version 1.0.3 compare-loop-index-to-uniform.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.3 complex-glsl-does-not-crash.html
--min-version 1.0.4 compound-assignment-type-combination.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-in-loop.html
--min-version 1.0.3 conditional-discard-optimization.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 constant-precision-qualifier.html
--min-version 1.0.3 --max-version 1.99 essl3-shaders-with-webgl1.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 --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.3 fragcoord-linking-bug.html
--min-version 1.0.4 gl-fragcoord-multisampling-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 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 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.4 logic-inside-block-without-braces.html
--min-version 1.0.3 long-expressions-should-not-crash.html --min-version 1.0.3 long-expressions-should-not-crash.html
--min-version 1.0.4 loop-if-loop-gradient.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 pow-with-constant-exponent-should-not-crash.html
--min-version 1.0.4 qualcomm-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 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.3 sampler-array-using-loop-index.html
--min-version 1.0.4 sampler-struct-function-arg.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 sequence-operator-evaluation-order.html
--min-version 1.0.4 sketchfab-lighting-shader-crash.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.4 struct-constructor-highp-bug.html
--min-version 1.0.3 temp-expressions-should-not-crash.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.4 undefined-index-should-not-crash.html
--min-version 1.0.3 uniforms-should-not-lose-values.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); gl_FragColor = foo(uv) + foo(um);
} }
</script> </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"> <script type="text/javascript">
"use strict"; "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."); 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', fShaderId: 'fshaderAmbiguousHLSLFunctionCall',
fShaderSuccess: true, fShaderSuccess: true,
linkSuccess: 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> </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"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head> </head>
<body> <body>
<canvas id="canvas" width="256" height="256"> </canvas>
<div id="description"></div> <div id="description"></div>
<div id="console"></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"> <script id="fshader" type="x-shader/x-fragment">
precision mediump float; precision mediump float;
uniform int uCount; uniform int uCount;
@ -62,25 +55,16 @@ void main() {
<script type="application/javascript"> <script type="application/javascript">
"use strict"; "use strict";
description("Comparing loop index to an uniform in a fragment shader should work."); 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(); GLSLConformanceTester.runRenderTests([
var successfullyParsed = true; {
finishTest(); fShaderId: 'fshader',
fShaderSuccess: true,
linkSuccess: true,
passMsg: 'Compare a loop index to an uniform',
uniforms: [{name: "uCount", functionName: "uniform1i", value: 5}]
}
]);
</script> </script>
</body> </body>
</html> </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"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head> </head>
<body> <body>
<canvas id="canvas" width="256" height="256"> </canvas>
<div id="description"></div> <div id="description"></div>
<div id="console"></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"> <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. // It is assumed that uTest is set to 0. It's here to make the expression not constant.
uniform mediump float uTest; uniform mediump float uTest;
@ -96,49 +89,48 @@ void main() {
<script type="application/javascript"> <script type="application/javascript">
"use strict"; "use strict";
description(); description();
var wtu = WebGLTestUtils;
function test() { function test() {
var gl = wtu.create3DContext("canvas"); var wtu = WebGLTestUtils;
var gl = wtu.create3DContext();
if (!gl) { if (!gl) {
testFailed("context does not exist"); testFailed("context does not exist");
finishTest();
return; return;
} }
if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision == 0) { if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision == 0) {
testPassed("highp precision not supported"); testPassed("highp precision not supported");
finishTest();
} else { } else {
wtu.setupUnitQuad(gl); GLSLConformanceTester.runRenderTests([
{
debug("Testing shader where the precision qualifier of a constant affects built-in function results"); fShaderId: 'fshader',
var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosition"], undefined, true); fShaderSuccess: true,
var uniformLoc = gl.getUniformLocation(program, 'uTest'); linkSuccess: true,
gl.uniform1f(uniformLoc, 0); passMsg: 'The precision qualifier of a constant affects built-in function results',
wtu.drawUnitQuad(gl); uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}]
wtu.checkCanvasRect(gl, 0, 0, 256, 256, [0, 255, 0, 255]); },
{
debug(""); fShaderId: 'fshaderNoConstants',
debug("Testing shader where the precision qualifier of a variable affects built-in function results"); fShaderSuccess: true,
program = wtu.setupProgram(gl, ["vshader", "fshaderNoConstants"], ["aPosition"], undefined, true); linkSuccess: true,
uniformLoc = gl.getUniformLocation(program, 'uTest'); passMsg: 'The precision qualifier of a variable affects built-in function results',
gl.uniform1f(uniformLoc, 0); uniforms: [{name: "uTest", functionName: "uniform1f", value: 0},
uniformLoc = gl.getUniformLocation(program, 'uTestHigh'); {name: "uTestHigh", functionName: "uniform1f", value: 0}]
gl.uniform1f(uniformLoc, 0); },
wtu.drawUnitQuad(gl); {
wtu.checkCanvasRect(gl, 0, 0, 256, 256, [0, 255, 0, 255]); fShaderId: 'fshaderAllHighp',
fShaderSuccess: true,
debug(""); linkSuccess: true,
debug("Testing shader where all variables are qualified as highp"); passMsg: 'All variables are qualified as highp',
program = wtu.setupProgram(gl, ["vshader", "fshaderAllHighp"], ["aPosition"], undefined, true); uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}]
uniformLoc = gl.getUniformLocation(program, 'uTest'); },
gl.uniform1f(uniformLoc, 0); ]);
wtu.drawUnitQuad(gl);
wtu.checkCanvasRect(gl, 0, 0, 256, 256, [0, 255, 0, 255]);
} }
}; };
test(); test();
var successfullyParsed = true; var successfullyParsed = true;
finishTest();
</script> </script>
</body> </body>
</html> </html>

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

@ -35,19 +35,19 @@
<link rel="stylesheet" href="../../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head> </head>
<body> <body>
<canvas id="repro" style="border: none;" width="256" height="256"></canvas>
<div id="description"></div> <div id="description"></div>
<div id="console"></div> <div id="console"></div>
<script id="shader-vs" type="x-shader/x-vertex"> <script id="shader-vs" type="x-shader/x-vertex">
attribute vec2 pos; attribute vec4 vPosition;
uniform float divisor; uniform float divisor;
varying vec4 vColor; varying vec4 vColor;
void main(void) { void main(void) {
gl_Position = vec4(pos, 0.0, 1.0); gl_Position = vPosition;
float index = 9.0; float index = 9.0;
// Floating point operations don't have any guaranteed precision, but they // Floating point operations don't have any guaranteed precision, but they
// should at least be accurate to 1 part in 10^5. // should at least be accurate to 1 part in 10^5.
@ -65,31 +65,26 @@ void main(void) {
</script> </script>
<script> <script>
"use strict"; "use strict";
description(); description();
debug(""); debug("");
// Reproduces bug seen on Mac OS X with AMD Radeon HD 6490 GPU // 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 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("If your card thinks floor(9. / 3.) is not 3 to within 1 part in 10^5, ");
debug("then the square will be red."); debug("then the square will be red.");
var wtu = WebGLTestUtils; GLSLConformanceTester.runRenderTests([
var canvas = document.getElementById("repro"); {
var gl = wtu.create3DContext(canvas); vShaderId: 'shader-vs',
if (!gl) { vShaderSuccess: true,
testFailed("context does not exist"); fShaderId: 'shader-fs',
} else { fShaderSuccess: true,
gl.clearColor(0.0, 0.0, 0.0, 1.0); linkSuccess: true,
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); passMsg: 'Test that floor(9. / 3.) is 3 to within 1 part in 10^5',
wtu.setupUnitQuad(gl); uniforms: [{name: "divisor", functionName: "uniform1f", value: 3}]
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);
} }
]);
var successfullyParsed = true;
</script> </script>
<script src="../../../js/js-test-post.js"></script>
</body> </body>
</html> </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"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head> </head>
<body> <body>
<canvas id="canvas" width="256" height="256"> </canvas>
<div id="description"></div> <div id="description"></div>
<div id="console"></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"> <script id="fshaderIf" type="x-shader/x-fragment">
precision mediump float; precision mediump float;
uniform bool uFalse; uniform bool uFalse;
@ -92,33 +85,22 @@ void main() {
"use strict"; "use strict";
description("Short-circuiting logic operator with side effects inside if/for statement without braces should work."); description("Short-circuiting logic operator with side effects inside if/for statement without braces should work.");
debug(""); debug("");
var wtu = WebGLTestUtils;
function test() {
var gl = wtu.create3DContext("canvas");
if (!gl) {
testFailed("context does not exist");
return;
}
wtu.setupUnitQuad(gl);
debug(""); GLSLConformanceTester.runRenderTests([
debug("Testing if"); {
var program = wtu.setupProgram(gl, ["vshader", "fshaderIf"], ["aPosition"], undefined, true); fShaderId: 'fshaderIf',
var uniformLoc = gl.getUniformLocation(program, 'uFalse'); fShaderSuccess: true,
gl.uniform1i(uniformLoc, 0); linkSuccess: true,
wtu.drawUnitQuad(gl); passMsg: 'Short-circuiting operator inside if statement without braces',
wtu.checkCanvas(gl, [0, 255, 0, 255]); uniforms: [{name: "uFalse", functionName: "uniform1i", value: 0}]
},
debug(""); {
debug("Testing for"); fShaderId: 'fshaderFor',
var program = wtu.setupProgram(gl, ["vshader", "fshaderFor"], ["aPosition"], undefined, true); fShaderSuccess: true,
wtu.drawUnitQuad(gl); linkSuccess: true,
wtu.checkCanvas(gl, [0, 255, 0, 255]); passMsg: 'Short-circuiting operator inside for statement without braces'
}; }
]);
test();
var successfullyParsed = true;
finishTest();
</script> </script>
</body> </body>
</html> </html>

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

@ -35,19 +35,19 @@
<link rel="stylesheet" href="../../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head> </head>
<body> <body>
<canvas id="repro" style="border: none;" width="256" height="256"></canvas>
<div id="description"></div> <div id="description"></div>
<div id="console"></div> <div id="console"></div>
<script id="shader-vs" type="x-shader/x-vertex"> <script id="shader-vs" type="x-shader/x-vertex">
attribute vec2 pos; attribute vec4 vPosition;
uniform float divisor; uniform float divisor;
varying vec4 vColor; varying vec4 vColor;
void main(void) { void main(void) {
gl_Position = vec4(pos, 0.0, 1.0); gl_Position = vPosition;
float index = 9.0; float index = 9.0;
// mod(x, y) is computed as x-y*floor(x/y). There are no guarantees on // 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 // 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 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."); debug("If your card thinks mod(9,3) is not 0, then the square will be red.");
var wtu = WebGLTestUtils; GLSLConformanceTester.runRenderTests([
var canvas = document.getElementById("repro"); {
var gl = wtu.create3DContext(canvas); vShaderId: 'shader-vs',
if (!gl) { vShaderSuccess: true,
testFailed("context does not exist"); fShaderId: 'shader-fs',
} else { fShaderSuccess: true,
gl.clearColor(0.0, 0.0, 0.0, 1.0); linkSuccess: true,
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); passMsg: 'Test that mod(9/3) is 0',
wtu.setupUnitQuad(gl); uniforms: [{name: "divisor", functionName: "uniform1f", value: 3}]
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);
} }
]);
var successfullyParsed = true;
</script> </script>
<script src="../../../js/js-test-post.js"></script>
</body> </body>
</html> </html>

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

@ -33,14 +33,10 @@
<link rel="stylesheet" href="../../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head> </head>
<body> <body>
<script id="shader-vs" type="x-shader/x-vertex"> <script id="fshader" type="x-shader/x-fragment">
void main(){
gl_Position = vec4(0);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float; precision mediump float;
uniform mat3 rot; uniform mat3 rot;
float foo(vec3 bar) { float foo(vec3 bar) {
@ -60,21 +56,16 @@ void main(void){
description(); description();
debug(""); 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>'); 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>
<script src="../../../js/js-test-post.js"></script>
</body> </body>
</html> </html>

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

@ -1,4 +1,4 @@
<!-- <!--
/* /*
** Copyright (c) 2014 The Khronos Group Inc. ** 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> </head>
<body> <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="description"></div>
<div id="console"></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"> <script id="shader-fs" type="x-shader/x-fragment">
precision mediump float; precision mediump float;
@ -63,35 +56,49 @@
} }
</script> </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> <script>
"use strict"; "use strict";
description(); description();
debug("");
debug("If the test passes correctly the viewport will be green."); debug("If the test passes correctly the viewport will be green.");
var wtu = WebGLTestUtils; var wtu = WebGLTestUtils;
var canvas = document.getElementById("output"); var canvas = document.getElementById("output");
var gl = wtu.create3DContext(canvas); var gl = wtu.create3DContext(canvas);
if (!gl) {
testFailed("context does not exist"); var textureGreen;
} else {
var textureGreen = gl.createTexture() var createGreenTexture = function() {
gl.bindTexture(gl.TEXTURE_2D, textureGreen); 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_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_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_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, 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); gl.bindTexture(gl.TEXTURE_2D, null);
return texture;
};
// Clear complete viewport to red var test = function(fragShaderId, texUniformName) {
gl.clearColor(1.0, 0.0, 0.0, 1.0); var program = wtu.setupProgram(gl, [wtu.simpleVertexShader, fragShaderId], ["a_position"], [0], true);
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);
if (!program) { if (!program) {
testFailed("Shader compilation/link failed"); testFailed("Shader compilation/link failed");
@ -100,14 +107,23 @@ if (!gl) {
var uniformMap = wtu.getUniformMap(gl, program); var uniformMap = wtu.getUniformMap(gl, program);
gl.activeTexture(gl.TEXTURE0); gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, textureGreen); gl.bindTexture(gl.TEXTURE_2D, textureGreen);
gl.uniform1i(uniformMap['green.source'].location, 0); gl.uniform1i(uniformMap[texUniformName].location, 0);
// Draw // Draw
wtu.drawUnitQuad(gl); wtu.clearAndDrawUnitQuad(gl);
// Verify output // Verify output
wtu.checkCanvasRect(gl, 0, 128, 256, 128, [0, 255,0, 255], "should be green", 1); 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; var successfullyParsed = true;
</script> </script>

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

@ -6,19 +6,11 @@
<link rel="stylesheet" href="../../../resources/js-test-style.css"/> <link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script> <script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"></script> <script src="../../../js/webgl-test-utils.js"></script>
<script src="../../../js/glsl-conformance-test.js"></script>
</head> </head>
<body> <body>
<canvas id="canvas" width="256" height="256"> </canvas>
<div id="description"></div> <div id="description"></div>
<div id="console"></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"> <script id="fshader" type="x-shader/x-fragment">
#ifdef GL_FRAGMENT_PRECISION_HIGH #ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float; precision highp float;
@ -42,22 +34,17 @@ void main() {
description("Struct constructors should evaluate properly."); 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("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."); 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); GLSLConformanceTester.runRenderTests([
gl.clear(gl.COLOR_BUFFER_BIT); {
fShaderId: 'fshader',
var attribBuffers = wtu.setupUnitQuad(gl, 0, 1); fShaderSuccess: true,
var program = wtu.setupProgram(gl, ['vshader', 'fshader'], ['a_position'], [0], true); linkSuccess: true,
if (!program) { passMsg: "Struct contstructor evaluation"
testFailed("Shader compilation/link failed");
} else {
// Draw
wtu.drawUnitQuad(gl);
// Verify output
wtu.checkCanvas(gl, [0, 255, 0, 255], "should be green");
} }
]);
finishTest();
</script> </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>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше