Merge inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2015-02-06 09:06:38 -05:00
commit 306a1550a3
331 changed files with 20815 additions and 16683 deletions

View File

@ -1187,15 +1187,15 @@ pref("browser.tabs.remote.desktopbehavior", true);
// This will require a restart.
pref("security.sandbox.windows.log", false);
// Controls whether the Windows NPAPI plugin process is sandboxed by default.
// Controls whether and how the Windows NPAPI plugin process is sandboxed.
// To get a different setting for a particular plugin replace "default", with
// the plugin's nice file name, see: nsPluginTag::GetNiceFileName.
pref("dom.ipc.plugins.sandbox.default", false);
pref("dom.ipc.plugins.sandbox.flash", true);
// This controls whether the Windows NPAPI process sandbox is using a more
// strict sandboxing policy. This will require a restart.
pref("dom.ipc.plugins.moreStrictSandbox", false);
// On windows these levels are:
// 0 - no sandbox
// 1 - sandbox with USER_NON_ADMIN access token level
// 2 - a more strict sandbox, which might cause functionality issues
pref("dom.ipc.plugins.sandbox-level.default", 0);
pref("dom.ipc.plugins.sandbox-level.flash", 1);
#if defined(MOZ_CONTENT_SANDBOX)
// This controls whether the Windows content process sandbox is using a more

View File

@ -673,10 +673,17 @@ this.AppsUtils = {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(aPath);
let channel = NetUtil.newChannel(file);
let channel = NetUtil.newChannel2(file,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
channel.contentType = "application/json";
NetUtil.asyncFetch(channel, function(aStream, aResult) {
NetUtil.asyncFetch2(channel, function(aStream, aResult) {
if (!Components.isSuccessCode(aResult)) {
deferred.resolve(null);

View File

@ -37,13 +37,11 @@ function debug(aMsg) {
}
function enableOfflineCacheForApp(origin, appId) {
let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
origin, appId, false);
Services.perms.addFromPrincipal(principal, 'offline-app',
function enableOfflineCacheForApp(aPrincipal) {
Services.perms.addFromPrincipal(aPrincipal, 'offline-app',
Ci.nsIPermissionManager.ALLOW_ACTION);
// Prevent cache from being evicted:
Services.perms.addFromPrincipal(principal, 'pin-app',
Services.perms.addFromPrincipal(aPrincipal, 'pin-app',
Ci.nsIPermissionManager.ALLOW_ACTION);
}
@ -80,10 +78,18 @@ function storeCache(applicationCache, url, file, itemType) {
});
}
function readFile(aFile, aCallback) {
let channel = NetUtil.newChannel(aFile);
function readFile(aFile, aPrincipal, aCallback) {
let channel = NetUtil.newChannel2(aFile,
null,
null,
null, // aLoadingNode
aPrincipal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
channel.contentType = "plain/text";
NetUtil.asyncFetch(channel, function(aStream, aResult) {
NetUtil.asyncFetch2(channel, function(aStream, aResult) {
if (!Components.isSuccessCode(aResult)) {
Cu.reportError("OfflineCacheInstaller: Could not read file " + aFile.path);
if (aCallback)
@ -211,7 +217,10 @@ function installCache(app) {
if (!cacheManifest.exists())
return;
enableOfflineCacheForApp(app.origin, app.localId);
let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
app.origin, app.localId, false);
enableOfflineCacheForApp(principal);
// Get the url for the manifest.
let appcacheURL = app.appcache_path;
@ -223,7 +232,7 @@ function installCache(app) {
let applicationCache = applicationCacheService.createApplicationCache(groupID);
applicationCache.activate();
readFile(cacheManifest, function readAppCache(content) {
readFile(cacheManifest, principal, function readAppCache(content) {
let entries = parseAppCache(app, cacheManifest.path, content);
entries.urls.forEach(function processCachedFile(url) {

View File

@ -200,7 +200,17 @@ this.TrustedHostedAppsUtils = {
throw "CERTDB_ERROR";
}
let mRequestChannel = NetUtil.newChannel(aApp.manifestURL)
let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
aApp.origin, aApp.localId, false);
let mRequestChannel = NetUtil.newChannel2(aApp.manifestURL,
null,
null,
null, // aLoadingNode
principal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER)
.QueryInterface(Ci.nsIHttpChannel);
mRequestChannel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
mRequestChannel.notificationCallbacks =
@ -222,7 +232,14 @@ this.TrustedHostedAppsUtils = {
return;
}
let sRequestChannel = NetUtil.newChannel(signatureURL)
let sRequestChannel = NetUtil.newChannel2(signatureURL,
null,
null,
null, // aLoadingNode
principal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER)
.QueryInterface(Ci.nsIHttpChannel);
sRequestChannel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
sRequestChannel.notificationCallbacks =
@ -239,12 +256,12 @@ this.TrustedHostedAppsUtils = {
Promise.all([
new Promise((resolve, reject) => {
NetUtil.asyncFetch(mRequestChannel,
getAsyncFetchCallback(resolve, reject));
NetUtil.asyncFetch2(mRequestChannel,
getAsyncFetchCallback(resolve, reject));
}),
new Promise((resolve, reject) => {
NetUtil.asyncFetch(sRequestChannel,
getAsyncFetchCallback(resolve, reject));
NetUtil.asyncFetch2(sRequestChannel,
getAsyncFetchCallback(resolve, reject));
})
]).then(([aManifestStream, aSignatureStream]) => {
this._verifySignedFile(aManifestStream, aSignatureStream, certDb)

View File

@ -3429,11 +3429,29 @@ this.DOMApplicationRegistry = {
aNewApp) {
let requestChannel;
let appURI = NetUtil.newURI(aNewApp.origin, null, null);
let principal = Services.scriptSecurityManager.getAppCodebasePrincipal(
appURI, aNewApp.localId, false);
if (aIsLocalFileInstall) {
requestChannel = NetUtil.newChannel(aFullPackagePath)
requestChannel = NetUtil.newChannel2(aFullPackagePath,
null,
null,
null, // aLoadingNode
principal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER)
.QueryInterface(Ci.nsIFileChannel);
} else {
requestChannel = NetUtil.newChannel(aFullPackagePath)
requestChannel = NetUtil.newChannel2(aFullPackagePath,
null,
null,
null, // aLoadingNode
principal,
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER)
.QueryInterface(Ci.nsIHttpChannel);
requestChannel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
}
@ -3529,7 +3547,7 @@ this.DOMApplicationRegistry = {
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(aFilePath);
NetUtil.asyncFetch(file, function(inputStream, status) {
NetUtil.asyncFetch2(file, function(inputStream, status) {
if (!Components.isSuccessCode(status)) {
debug("Error reading " + aFilePath + ": " + e);
deferred.reject();
@ -3556,7 +3574,12 @@ this.DOMApplicationRegistry = {
debug("File hash computed: " + hash);
deferred.resolve(hash);
});
},
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
return deferred.promise;
},

View File

@ -37,7 +37,7 @@ ArchiveReader::Constructor(const GlobalObject& aGlobal,
nsAutoCString encoding;
if (!EncodingUtils::FindEncodingForLabelNoReplacement(aOptions.mEncoding,
encoding)) {
aError.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED, &aOptions.mEncoding);
aError.ThrowRangeError(MSG_ENCODING_NOT_SUPPORTED, &aOptions.mEncoding);
return nullptr;
}

View File

@ -63,7 +63,7 @@
new ArchiveReader(binaryFile, { encoding: "random stuff" });
ok(false, "Should have thrown for bogus encoding label.");
} catch (e) {
ok(e instanceof TypeError, "Expected a TypeError");
ok(e instanceof RangeError, "Expected a RangeError");
finishTest();
}
}

View File

@ -45,8 +45,7 @@
// This tags are used in the Structured Clone Algorithm to move js values from
// worker thread to main thread
#define CONSOLE_TAG_STRING JS_SCTAG_USER_MIN
#define CONSOLE_TAG_BLOB JS_SCTAG_USER_MIN + 1
#define CONSOLE_TAG_BLOB JS_SCTAG_USER_MIN
using namespace mozilla::dom::exceptions;
using namespace mozilla::dom::workers;
@ -58,7 +57,6 @@ struct
ConsoleStructuredCloneData
{
nsCOMPtr<nsISupports> mParent;
nsTArray<nsString> mStrings;
nsTArray<nsRefPtr<FileImpl>> mFiles;
};
@ -82,22 +80,6 @@ ConsoleStructuredCloneCallbacksRead(JSContext* aCx,
static_cast<ConsoleStructuredCloneData*>(aClosure);
MOZ_ASSERT(data);
if (aTag == CONSOLE_TAG_STRING) {
MOZ_ASSERT(data->mStrings.Length() > aIndex);
JS::Rooted<JS::Value> value(aCx);
if (!xpc::StringToJsval(aCx, data->mStrings.ElementAt(aIndex), &value)) {
return nullptr;
}
JS::Rooted<JSObject*> obj(aCx);
if (!JS_ValueToObject(aCx, value, &obj)) {
return nullptr;
}
return obj;
}
if (aTag == CONSOLE_TAG_BLOB) {
MOZ_ASSERT(data->mFiles.Length() > aIndex);
@ -146,17 +128,10 @@ ConsoleStructuredCloneCallbacksWrite(JSContext* aCx,
return false;
}
nsAutoJSString string;
if (!string.init(aCx, jsString)) {
if (!JS_WriteString(aWriter, jsString)) {
return false;
}
if (!JS_WriteUint32Pair(aWriter, CONSOLE_TAG_STRING,
data->mStrings.Length())) {
return false;
}
data->mStrings.AppendElement(string);
return true;
}

View File

@ -159,7 +159,7 @@ WindowNamedPropertiesHandler::defineProperty(JSContext* aCx,
{
ErrorResult rv;
rv.ThrowTypeError(MSG_DEFINEPROPERTY_ON_GSP);
rv.ReportTypeError(aCx);
rv.ReportErrorWithMessage(aCx);
return false;
}

View File

@ -38,8 +38,6 @@ DOM4_MSG_DEF(RangeError, "The method parameter is out of valid range.", NS_ERROR
/* StringEncoding API errors from http://wiki.whatwg.org/wiki/StringEncoding */
DOM4_MSG_DEF(EncodingError, "The given encoding is not supported.", NS_ERROR_DOM_ENCODING_NOT_SUPPORTED_ERR)
DOM4_MSG_DEF(EncodingError, "The encoding must be utf-8, utf-16, or utf-16be.", NS_ERROR_DOM_ENCODING_NOT_UTF_ERR)
DOM4_MSG_DEF(EncodingError, "The decoder failed to convert.", NS_ERROR_DOM_ENCODING_DECODE_ERR)
/* WebCrypto API errors from http://www.w3.org/TR/WebCryptoAPI/ */
DOM4_MSG_DEF(UnknownError, "The operation failed for an unknown transient reason", NS_ERROR_DOM_UNKNOWN_ERR)

View File

@ -50,8 +50,8 @@ namespace mozilla {
namespace dom {
JSErrorFormatString ErrorFormatString[] = {
#define MSG_DEF(_name, _argc, _str) \
{ _str, _argc, JSEXN_TYPEERR },
#define MSG_DEF(_name, _argc, _exn, _str) \
{ _str, _argc, _exn },
#include "mozilla/dom/Errors.msg"
#undef MSG_DEF
};
@ -123,22 +123,20 @@ struct ErrorResult::Message {
};
void
ErrorResult::ThrowTypeError(const dom::ErrNum errorNumber, ...)
ErrorResult::ThrowErrorWithMessage(va_list ap, const dom::ErrNum errorNumber,
nsresult errorType)
{
va_list ap;
va_start(ap, errorNumber);
if (IsJSException()) {
// We have rooted our mJSException, and we don't have the info
// needed to unroot here, so just bail.
va_end(ap);
MOZ_ASSERT(false,
"Ignoring ThrowTypeError call because we have a JS exception");
"Ignoring ThrowErrorWithMessage call because we have a JS exception");
return;
}
if (IsTypeError()) {
if (IsErrorWithMessage()) {
delete mMessage;
}
mResult = NS_ERROR_TYPE_ERR;
mResult = errorType;
Message* message = new Message();
message->mErrorNumber = errorNumber;
uint16_t argCount = dom::GetErrorMessage(nullptr, errorNumber)->argCount;
@ -148,13 +146,30 @@ ErrorResult::ThrowTypeError(const dom::ErrNum errorNumber, ...)
message->mArgs.AppendElement(*va_arg(ap, nsString*));
}
mMessage = message;
}
void
ErrorResult::ThrowTypeError(const dom::ErrNum errorNumber, ...)
{
va_list ap;
va_start(ap, errorNumber);
ThrowErrorWithMessage(ap, errorNumber, NS_ERROR_TYPE_ERR);
va_end(ap);
}
void
ErrorResult::ReportTypeError(JSContext* aCx)
ErrorResult::ThrowRangeError(const dom::ErrNum errorNumber, ...)
{
MOZ_ASSERT(mMessage, "ReportTypeError() can be called only once");
va_list ap;
va_start(ap, errorNumber);
ThrowErrorWithMessage(ap, errorNumber, NS_ERROR_RANGE_ERR);
va_end(ap);
}
void
ErrorResult::ReportErrorWithMessage(JSContext* aCx)
{
MOZ_ASSERT(mMessage, "ReportErrorWithMessage() can be called only once");
Message* message = mMessage;
const uint32_t argCount = message->mArgs.Length();
@ -174,7 +189,7 @@ ErrorResult::ReportTypeError(JSContext* aCx)
void
ErrorResult::ClearMessage()
{
if (IsTypeError()) {
if (IsErrorWithMessage()) {
delete mMessage;
mMessage = nullptr;
}
@ -186,7 +201,7 @@ ErrorResult::ThrowJSException(JSContext* cx, JS::Handle<JS::Value> exn)
MOZ_ASSERT(mMightHaveUnreportedJSException,
"Why didn't you tell us you planned to throw a JS exception?");
if (IsTypeError()) {
if (IsErrorWithMessage()) {
delete mMessage;
}

View File

@ -103,8 +103,8 @@ ThrowMethodFailedWithDetails(JSContext* cx, ErrorResult& rv,
const char* memberName,
bool reportJSContentExceptions = false)
{
if (rv.IsTypeError()) {
rv.ReportTypeError(cx);
if (rv.IsErrorWithMessage()) {
rv.ReportErrorWithMessage(cx);
return false;
}
if (rv.IsJSException()) {

View File

@ -23,7 +23,7 @@ namespace mozilla {
namespace dom {
enum ErrNum {
#define MSG_DEF(_name, _argc, _str) \
#define MSG_DEF(_name, _argc, _exn, _str) \
_name,
#include "mozilla/dom/Errors.msg"
#undef MSG_DEF
@ -51,7 +51,7 @@ public:
#ifdef DEBUG
~ErrorResult() {
MOZ_ASSERT_IF(IsTypeError(), !mMessage);
MOZ_ASSERT_IF(IsErrorWithMessage(), !mMessage);
MOZ_ASSERT(!mMightHaveUnreportedJSException);
}
#endif
@ -59,7 +59,8 @@ public:
void Throw(nsresult rv) {
MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
MOZ_ASSERT(!IsTypeError(), "Don't overwite TypeError");
MOZ_ASSERT(rv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
MOZ_ASSERT(rv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
MOZ_ASSERT(rv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()");
@ -68,9 +69,10 @@ public:
}
void ThrowTypeError(const dom::ErrNum errorNumber, ...);
void ReportTypeError(JSContext* cx);
void ThrowRangeError(const dom::ErrNum errorNumber, ...);
void ReportErrorWithMessage(JSContext* cx);
void ClearMessage();
bool IsTypeError() const { return ErrorCode() == NS_ERROR_TYPE_ERR; }
bool IsErrorWithMessage() const { return ErrorCode() == NS_ERROR_TYPE_ERR || ErrorCode() == NS_ERROR_RANGE_ERR; }
// Facilities for throwing a preexisting JS exception value via this
// ErrorResult. The contract is that any code which might end up calling
@ -123,7 +125,8 @@ public:
// this.
void operator=(nsresult rv) {
MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
MOZ_ASSERT(!IsTypeError(), "Don't overwite TypeError");
MOZ_ASSERT(rv != NS_ERROR_RANGE_ERR, "Use ThrowRangeError()");
MOZ_ASSERT(!IsErrorWithMessage(), "Don't overwrite errors with message");
MOZ_ASSERT(rv != NS_ERROR_DOM_JS_EXCEPTION, "Use ThrowJSException()");
MOZ_ASSERT(!IsJSException(), "Don't overwrite JS exceptions");
MOZ_ASSERT(rv != NS_ERROR_XPC_NOT_ENOUGH_ARGS, "Use ThrowNotEnoughArgsError()");
@ -142,12 +145,12 @@ public:
private:
nsresult mResult;
struct Message;
// mMessage is set by ThrowTypeError and cleared (and deallocatd) by
// ReportTypeError.
// mMessage is set by ThrowErrorWithMessage and cleared (and deallocated) by
// ReportErrorWithMessage.
// mJSException is set (and rooted) by ThrowJSException and unrooted
// by ReportJSException.
union {
Message* mMessage; // valid when IsTypeError()
Message* mMessage; // valid when IsErrorWithMessage()
JS::Value mJSException; // valid when IsJSException()
};
@ -160,6 +163,8 @@ private:
// Not to be implemented, to make sure people always pass this by
// reference, not by value.
ErrorResult(const ErrorResult&) = delete;
void ThrowErrorWithMessage(va_list ap, const dom::ErrNum errorNumber,
nsresult errorType);
};
/******************************************************************************

View File

@ -19,50 +19,55 @@
* be replaced with a string value when the error is reported.
*/
MSG_DEF(MSG_INVALID_ENUM_VALUE, 3, "{0} '{1}' is not a valid value for enumeration {2}.")
MSG_DEF(MSG_MISSING_ARGUMENTS, 1, "Not enough arguments to {0}.")
MSG_DEF(MSG_NOT_OBJECT, 1, "{0} is not an object.")
MSG_DEF(MSG_NOT_CALLABLE, 1, "{0} is not callable.")
MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, "{0} does not implement interface {1}.")
MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' called on an object that does not implement interface {1}.")
MSG_DEF(MSG_METHOD_THIS_UNWRAPPING_DENIED, 1, "Permission to call '{0}' denied.")
MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' getter called on an object that does not implement interface {1}.")
MSG_DEF(MSG_GETTER_THIS_UNWRAPPING_DENIED, 1, "Permission to call '{0}' getter denied.")
MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' setter called on an object that does not implement interface {1}.")
MSG_DEF(MSG_SETTER_THIS_UNWRAPPING_DENIED, 1, "Permission to call '{0}' setter denied.")
MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "\"this\" object does not implement interface {0}.")
MSG_DEF(MSG_NOT_IN_UNION, 2, "{0} could not be converted to any of: {1}.")
MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.")
MSG_DEF(MSG_CONSTRUCTOR_WITHOUT_NEW, 1, "Constructor {0} requires 'new'")
MSG_DEF(MSG_NO_INDEXED_SETTER, 1, "{0} doesn't have an indexed property setter.")
MSG_DEF(MSG_NO_NAMED_SETTER, 1, "{0} doesn't have a named property setter.")
MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, "Non-finite value is out of range for {0}.")
MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, "Value is out of range for {0}.")
MSG_DEF(MSG_NOT_SEQUENCE, 1, "{0} can't be converted to a sequence.")
MSG_DEF(MSG_NOT_DICTIONARY, 1, "{0} can't be converted to a dictionary.")
MSG_DEF(MSG_OVERLOAD_RESOLUTION_FAILED, 3, "Argument {0} is not valid for any of the {1}-argument overloads of {2}.")
MSG_DEF(MSG_GLOBAL_NOT_NATIVE, 0, "Global is not a native object.")
MSG_DEF(MSG_ENCODING_NOT_SUPPORTED, 1, "The given encoding '{0}' is not supported.")
MSG_DEF(MSG_DOM_ENCODING_NOT_UTF, 0, "The encoding must be utf-8, utf-16, or utf-16be.")
MSG_DEF(MSG_NOT_FINITE, 1, "{0} is not a finite floating-point value.")
MSG_DEF(MSG_INVALID_VERSION, 0, "0 (Zero) is not a valid database version.")
MSG_DEF(MSG_INVALID_BYTESTRING, 2, "Cannot convert string to ByteString because the character"
MSG_DEF(MSG_INVALID_ENUM_VALUE, 3, JSEXN_TYPEERR, "{0} '{1}' is not a valid value for enumeration {2}.")
MSG_DEF(MSG_MISSING_ARGUMENTS, 1, JSEXN_TYPEERR, "Not enough arguments to {0}.")
MSG_DEF(MSG_NOT_OBJECT, 1, JSEXN_TYPEERR, "{0} is not an object.")
MSG_DEF(MSG_NOT_CALLABLE, 1, JSEXN_TYPEERR, "{0} is not callable.")
MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "{0} does not implement interface {1}.")
MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' called on an object that does not implement interface {1}.")
MSG_DEF(MSG_METHOD_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' denied.")
MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' getter called on an object that does not implement interface {1}.")
MSG_DEF(MSG_GETTER_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' getter denied.")
MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, JSEXN_TYPEERR, "'{0}' setter called on an object that does not implement interface {1}.")
MSG_DEF(MSG_SETTER_THIS_UNWRAPPING_DENIED, 1, JSEXN_TYPEERR, "Permission to call '{0}' setter denied.")
MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, JSEXN_TYPEERR, "\"this\" object does not implement interface {0}.")
MSG_DEF(MSG_NOT_IN_UNION, 2, JSEXN_TYPEERR, "{0} could not be converted to any of: {1}.")
MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, JSEXN_TYPEERR, "Illegal constructor.")
MSG_DEF(MSG_CONSTRUCTOR_WITHOUT_NEW, 1, JSEXN_TYPEERR, "Constructor {0} requires 'new'")
MSG_DEF(MSG_NO_INDEXED_SETTER, 1, JSEXN_TYPEERR, "{0} doesn't have an indexed property setter.")
MSG_DEF(MSG_NO_NAMED_SETTER, 1, JSEXN_TYPEERR, "{0} doesn't have a named property setter.")
MSG_DEF(MSG_ENFORCE_RANGE_NON_FINITE, 1, JSEXN_TYPEERR, "Non-finite value is out of range for {0}.")
MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, JSEXN_TYPEERR, "Value is out of range for {0}.")
MSG_DEF(MSG_NOT_SEQUENCE, 1, JSEXN_TYPEERR, "{0} can't be converted to a sequence.")
MSG_DEF(MSG_NOT_DICTIONARY, 1, JSEXN_TYPEERR, "{0} can't be converted to a dictionary.")
MSG_DEF(MSG_OVERLOAD_RESOLUTION_FAILED, 3, JSEXN_TYPEERR, "Argument {0} is not valid for any of the {1}-argument overloads of {2}.")
MSG_DEF(MSG_GLOBAL_NOT_NATIVE, 0, JSEXN_TYPEERR, "Global is not a native object.")
MSG_DEF(MSG_ENCODING_NOT_SUPPORTED, 1, JSEXN_RANGEERR, "The given encoding '{0}' is not supported.")
MSG_DEF(MSG_DOM_ENCODING_NOT_UTF, 0, JSEXN_RANGEERR, "The encoding must be utf-8, utf-16, or utf-16be.")
MSG_DEF(MSG_DOM_DECODING_FAILED, 0, JSEXN_TYPEERR, "Decoding failed.")
MSG_DEF(MSG_NOT_FINITE, 1, JSEXN_TYPEERR, "{0} is not a finite floating-point value.")
MSG_DEF(MSG_INVALID_VERSION, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid database version.")
MSG_DEF(MSG_INVALID_BYTESTRING, 2, JSEXN_TYPEERR, "Cannot convert string to ByteString because the character"
" at index {0} has value {1} which is greater than 255.")
MSG_DEF(MSG_NOT_DATE, 1, "{0} is not a date.")
MSG_DEF(MSG_INVALID_ADVANCE_COUNT, 0, "0 (Zero) is not a valid advance count.")
MSG_DEF(MSG_DEFINEPROPERTY_ON_GSP, 0, "Not allowed to define a property on the named properties object.")
MSG_DEF(MSG_INVALID_URL, 1, "{0} is not a valid URL.")
MSG_DEF(MSG_METADATA_NOT_CONFIGURED, 0, "Either size or lastModified should be true.")
MSG_DEF(MSG_INVALID_READ_SIZE, 0, "0 (Zero) is not a valid read size.")
MSG_DEF(MSG_HEADERS_IMMUTABLE, 0, "Headers are immutable and cannot be modified.")
MSG_DEF(MSG_INVALID_HEADER_NAME, 1, "{0} is an invalid header name.")
MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, "{0} is an invalid header value.")
MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, "Headers require name/value tuples when being initialized by a sequence.")
MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, "Permission denied to pass cross-origin object as {0}.")
MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, "Missing required {0}.")
MSG_DEF(MSG_INVALID_REQUEST_METHOD, 1, "Invalid request method {0}.")
MSG_DEF(MSG_REQUEST_BODY_CONSUMED_ERROR, 0, "Request body has already been consumed.")
MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, "Response statusText may not contain newline or carriage return.")
MSG_DEF(MSG_FETCH_FAILED, 0, "NetworkError when attempting to fetch resource.")
MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, "HEAD or GET Request cannot have a body.")
MSG_DEF(MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW, 0, "Not allowed to define a non-configurable property on the WindowProxy object")
MSG_DEF(MSG_NOT_DATE, 1, JSEXN_TYPEERR, "{0} is not a date.")
MSG_DEF(MSG_INVALID_ADVANCE_COUNT, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid advance count.")
MSG_DEF(MSG_DEFINEPROPERTY_ON_GSP, 0, JSEXN_TYPEERR, "Not allowed to define a property on the named properties object.")
MSG_DEF(MSG_INVALID_URL, 1, JSEXN_TYPEERR, "{0} is not a valid URL.")
MSG_DEF(MSG_METADATA_NOT_CONFIGURED, 0, JSEXN_TYPEERR, "Either size or lastModified should be true.")
MSG_DEF(MSG_INVALID_READ_SIZE, 0, JSEXN_TYPEERR, "0 (Zero) is not a valid read size.")
MSG_DEF(MSG_HEADERS_IMMUTABLE, 0, JSEXN_TYPEERR, "Headers are immutable and cannot be modified.")
MSG_DEF(MSG_INVALID_HEADER_NAME, 1, JSEXN_TYPEERR, "{0} is an invalid header name.")
MSG_DEF(MSG_INVALID_HEADER_VALUE, 1, JSEXN_TYPEERR, "{0} is an invalid header value.")
MSG_DEF(MSG_INVALID_HEADER_SEQUENCE, 0, JSEXN_TYPEERR, "Headers require name/value tuples when being initialized by a sequence.")
MSG_DEF(MSG_PERMISSION_DENIED_TO_PASS_ARG, 1, JSEXN_TYPEERR, "Permission denied to pass cross-origin object as {0}.")
MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, JSEXN_TYPEERR, "Missing required {0}.")
MSG_DEF(MSG_INVALID_REQUEST_METHOD, 1, JSEXN_TYPEERR, "Invalid request method {0}.")
MSG_DEF(MSG_REQUEST_BODY_CONSUMED_ERROR, 0, JSEXN_TYPEERR, "Request body has already been consumed.")
MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, JSEXN_TYPEERR, "Response statusText may not contain newline or carriage return.")
MSG_DEF(MSG_FETCH_FAILED, 0, JSEXN_TYPEERR, "NetworkError when attempting to fetch resource.")
MSG_DEF(MSG_NO_BODY_ALLOWED_FOR_GET_AND_HEAD, 0, JSEXN_TYPEERR, "HEAD or GET Request cannot have a body.")
MSG_DEF(MSG_DEFINE_NON_CONFIGURABLE_PROP_ON_WINDOW, 0, JSEXN_TYPEERR, "Not allowed to define a non-configurable property on the WindowProxy object")
MSG_DEF(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR, 0, JSEXN_RANGEERR, "Invalid zoom and pan value.")
MSG_DEF(MSG_INVALID_TRANSFORM_ANGLE_ERROR, 0, JSEXN_RANGEERR, "Invalid transform angle.")
MSG_DEF(MSG_INVALID_RESPONSE_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid response status code.")
MSG_DEF(MSG_INVALID_REDIRECT_STATUSCODE_ERROR, 0, JSEXN_RANGEERR, "Invalid redirect status code.")

View File

@ -166,27 +166,13 @@ ShaderValidator::ValidateAndTranslate(const char* source)
return ShCompile(mHandle, parts, ArrayLength(parts), mCompileOptions);
}
void
ShaderValidator::GetInfo(ShShaderInfo pname, size_t* params) const
{
MOZ_ASSERT(mHasRun);
ShGetInfo(mHandle, pname, params);
}
void
ShaderValidator::GetInfoLog(nsACString* out) const
{
MOZ_ASSERT(mHasRun);
size_t lenWithNull = 0;
GetInfo(SH_INFO_LOG_LENGTH, &lenWithNull);
MOZ_ASSERT(lenWithNull >= 1);
// SetLength allocates len+1, for the null-term.
out->SetLength(lenWithNull - 1);
ShGetInfoLog(mHandle, out->BeginWriting());
const std::string &log = ShGetInfoLog(mHandle);
out->Assign(log.data(), log.length());
}
void
@ -194,14 +180,8 @@ ShaderValidator::GetOutput(nsACString* out) const
{
MOZ_ASSERT(mHasRun);
size_t lenWithNull = 0;
GetInfo(SH_OBJECT_CODE_LENGTH, &lenWithNull);
MOZ_ASSERT(lenWithNull >= 1);
// SetLength allocates len+1, for the null-term.
out->SetLength(lenWithNull - 1);
ShGetObjectCode(mHandle, out->BeginWriting());
const std::string &output = ShGetObjectCode(mHandle);
out->Assign(output.data(), output.length());
}
template<size_t N>

View File

@ -37,7 +37,6 @@ public:
~ShaderValidator();
bool ValidateAndTranslate(const char* source);
void GetInfo(ShShaderInfo pname, size_t* params) const;
void GetInfoLog(nsACString* out) const;
void GetOutput(nsACString* out) const;
bool CanLinkTo(const ShaderValidator* prev, nsCString* const out_log) const;

View File

@ -124,7 +124,14 @@ ContactDB.prototype = {
}
}
let chan = jsm.NetUtil.newChannel(contactsFile);
let chan = jsm.NetUtil.newChannel2(contactsFile,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
let stream = chan.open();
// Obtain a converter to read from a UTF-8 encoded input stream.
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]

View File

@ -20,11 +20,12 @@ TextDecoder::Init(const nsAString& aLabel, const bool aFatal,
{
nsAutoCString encoding;
// Let encoding be the result of getting an encoding from label.
// If encoding is failure or replacement, throw a TypeError.
// If encoding is failure or replacement, throw a RangeError
// (https://encoding.spec.whatwg.org/#dom-textdecoder).
if (!EncodingUtils::FindEncodingForLabelNoReplacement(aLabel, encoding)) {
nsAutoString label(aLabel);
EncodingUtils::TrimSpaceCharacters(label);
aRv.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED, &label);
aRv.ThrowRangeError(MSG_ENCODING_NOT_SUPPORTED, &label);
return;
}
InitWithEncoding(encoding, aFatal);
@ -81,7 +82,7 @@ TextDecoder::Decode(const char* aInput, const int32_t aLength,
mDecoder->Reset();
if (rv == NS_OK_UDEC_MOREINPUT) {
if (mFatal) {
aRv.Throw(NS_ERROR_DOM_ENCODING_DECODE_ERR);
aRv.ThrowTypeError(MSG_DOM_DECODING_FAILED);
} else {
// Need to emit a decode error manually
// to simulate the EOF handling of the Encoding spec.
@ -91,7 +92,7 @@ TextDecoder::Decode(const char* aInput, const int32_t aLength,
}
if (NS_FAILED(rv)) {
aRv.Throw(NS_ERROR_DOM_ENCODING_DECODE_ERR);
aRv.ThrowTypeError(MSG_DOM_DECODING_FAILED);
}
}

View File

@ -18,16 +18,16 @@ TextEncoder::Init(const nsAString& aEncoding, ErrorResult& aRv)
// Let encoding be the result of getting an encoding from label.
// If encoding is failure, or is none of utf-8, utf-16, and utf-16be,
// throw a TypeError.
// throw a RangeError (https://encoding.spec.whatwg.org/#dom-textencoder).
if (!EncodingUtils::FindEncodingForLabel(label, mEncoding)) {
aRv.ThrowTypeError(MSG_ENCODING_NOT_SUPPORTED, &label);
aRv.ThrowRangeError(MSG_ENCODING_NOT_SUPPORTED, &label);
return;
}
if (!mEncoding.EqualsLiteral("UTF-8") &&
!mEncoding.EqualsLiteral("UTF-16LE") &&
!mEncoding.EqualsLiteral("UTF-16BE")) {
aRv.ThrowTypeError(MSG_DOM_ENCODING_NOT_UTF);
aRv.ThrowRangeError(MSG_DOM_ENCODING_NOT_UTF);
return;
}

View File

@ -35,7 +35,7 @@ function testBOMEncodingUTF8() {
// test valid encoding provided with invalid byte OM also provided.
data = [0xFF, 0xFE, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27];
testBOMCharset({encoding: "utf-8", fatal: true, data: data, error: "EncodingError",
testBOMCharset({encoding: "utf-8", fatal: true, data: data, error: "TypeError",
msg: "valid utf-8 encoding provided with invalid utf-8 fatal BOM test."});
// test valid encoding provided with invalid byte OM also provided.
@ -46,7 +46,7 @@ function testBOMEncodingUTF8() {
// test empty encoding provided with invalid byte OM also provided.
data = [0xFF, 0xFE, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27];
testBOMCharset({encoding: "", data: data, error: "TypeError",
testBOMCharset({encoding: "", data: data, error: "RangeError",
msg: "empty encoding provided with invalid utf-8 BOM test."});
}
@ -88,7 +88,7 @@ function testMoreBOMEncoding() {
// Testing user provided encoding is UTF-8 & bom encoding is utf-16be
data = [0xFE, 0xFF, 0x22, 0xd0, 0x92, 0xd1, 0x81, 0xd0, 0xb5, 0x20, 0xd1, 0x81, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb2, 0xd1, 0x8b, 0xd0, 0xb5, 0x20, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x8c, 0xd0, 0xb8, 0x20, 0xd0, 0xbf, 0xd0, 0xbe, 0xd1, 0x85, 0xd0, 0xbe, 0xd0, 0xb6, 0xd0, 0xb8, 0x20, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0x20, 0xd0, 0xbd, 0xd0, 0xb0, 0x20, 0xd0, 0xb4, 0xd1, 0x80, 0xd1, 0x83, 0xd0, 0xb3, 0xd0, 0xb0, 0x2c, 0x20, 0xd0, 0xba, 0xd0, 0xb0, 0xd0, 0xb6, 0xd0, 0xb4, 0xd0, 0xb0, 0xd1, 0x8f, 0x20, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb2, 0xd0, 0xb0, 0xd1, 0x8f, 0x20, 0xd1, 0x81, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x8c, 0xd1, 0x8f, 0x20, 0xd0, 0xbd, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x87, 0xd0, 0xb0, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbb, 0xd0, 0xb8, 0xd0, 0xb2, 0xd0, 0xb0, 0x20, 0xd0, 0xbf, 0xd0, 0xbe, 0x2d, 0xd1, 0x81, 0xd0, 0xb2, 0xd0, 0xbe, 0xd0, 0xb5, 0xd0, 0xbc, 0xd1, 0x83, 0x2e, 0x22];
testBOMCharset({encoding: "utf-8", fatal: true, data: data, error: "EncodingError",
testBOMCharset({encoding: "utf-8", fatal: true, data: data, error: "TypeError",
msg: "test decoder invalid BOM encoding for valid utf-8 fatal provided label."});
testBOMCharset({encoding: "utf-8", data: data, expected: "\ufffd\ufffd" + expectedString,
@ -104,7 +104,7 @@ function testMoreBOMEncoding() {
+ "\u03B0\u03B1\u03B2\u03B3\u03B4\u03B5\u03B6\u03B7\u03B8\u03B9\u03BA\u03BB\u03BC\u03BD\u03BE\u03BF"
+ "\u03C0\u03C1\u03C2\u03C3\u03C4\u03C5\u03C6\u03C7\u03C8\u03C9\u03CA\u03CB\u03CC\u03CD\u03CE";
testBOMCharset({encoding: "greek", fatal: true, data: data, error: "EncodingError",
testBOMCharset({encoding: "greek", fatal: true, data: data, error: "TypeError",
msg: "test decoder encoding provided with invalid BOM encoding for greek."});
testBOMCharset({encoding: "greek", data: data, expected: expectedString,

View File

@ -68,25 +68,38 @@ function testConstructorFatalOption(data, expectedString)
function testConstructorEncodingOption(aData, aExpectedString)
{
function errorMessage(encoding) {
return `The given encoding '${String(encoding).trim()}' is not supported.`;
}
// valid encoding passed
testCharset({encoding: "iso-8859-11", input: aData, expected: aExpectedString,
var encoding = "iso-8859-11";
testCharset({encoding: encoding, input: aData, expected: aExpectedString,
msg: "decoder testing constructor valid encoding."});
// invalid encoding passed
testCharset({encoding: "asdfasdf", input: aData, error: "TypeError",
msg: "constructor encoding, invalid encoding test."});
// passing spaces for encoding
testCharset({encoding: " ", input: aData, error: "TypeError",
encoding = " ";
testCharset({encoding: encoding, input: aData, error: "RangeError",
errorMessage: errorMessage(encoding),
msg: "constructor encoding, spaces encoding test."});
// passing null for encoding
testCharset({encoding: null, input: aData, error: "TypeError",
// invalid encoding passed
encoding = "asdfasdf";
testCharset({encoding: encoding, input: aData, error: "RangeError",
errorMessage: errorMessage(encoding),
msg: "constructor encoding, invalid encoding test."});
// null encoding passed
encoding = null;
testCharset({encoding: encoding, input: aData, error: "RangeError",
errorMessage: errorMessage(encoding),
msg: "constructor encoding, \"null\" encoding test."});
// empty encoding passed
testCharset({encoding: "", input: aData, error: "TypeError",
msg: "constuctor encoding, empty encoding test."});
encoding = "";
testCharset({encoding: encoding, input: aData, error: "RangeError",
errorMessage: errorMessage(encoding),
msg: "constructor encoding, empty encoding test."});
// replacement character test
aExpectedString = "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
@ -170,8 +183,8 @@ function testDecodeStreamOption(data, expectedString)
], msg: "decode() stream test utf-8."});
testCharset({encoding: "utf-8", fatal: true, array: [
{input: [0xC2], error: "EncodingError"},
{input: [0x80], error: "EncodingError"},
{input: [0xC2], error: "TypeError"},
{input: [0x80], error: "TypeError"},
], msg: "decode() stream test utf-8 fatal."});
}
@ -351,7 +364,7 @@ function testDecoderGetEncoding()
{encoding: "utf-16le", labels: ["utf-16", "utf-16le"]},
{encoding: "utf-16be", labels: ["utf-16be"]},
{encoding: "x-user-defined", labels: ["x-user-defined"]},
{error: "TypeError", labels: ["x-windows-949", "\u0130SO-8859-1", "csiso2022kr", "iso-2022-kr", "iso-2022-cn", "iso-2022-cn-ext", "replacement", "hz-gb-2312"]},
{error: "RangeError", labels: ["x-windows-949", "\u0130SO-8859-1", "csiso2022kr", "iso-2022-kr", "iso-2022-cn", "iso-2022-cn-ext", "replacement", "hz-gb-2312"]},
];
for (var le of labelEncodings) {
@ -376,6 +389,9 @@ function testCharset(test)
var decoder = new TextDecoder(test.encoding, fatal);
} catch (e) {
assert_equals(e.name, test.error, test.msg + " error thrown from the constructor.");
if (test.errorMessage) {
assert_equals(e.message, test.errorMessage, test.msg + " error thrown from the constructor.");
}
return;
}
@ -439,7 +455,7 @@ function testInvalid2022JP()
// decode() should never throw unless {fatal: true} is specified
(new TextDecoder("iso-2022-jp")).decode(new Uint8Array(input));
} catch (e) {
if (e.name !== "EncodingError") {
if (e.name !== "TypeError") {
throw e;
}
failureCount++;

View File

@ -90,31 +90,44 @@ function testEncodeUTF16ToUTF16()
function testConstructorEncodingOption(aData, aExpectedString)
{
function errorMessage(encoding) {
return `The given encoding '${String(encoding).trim()}' is not supported.`;
}
// valid encoding passed
testSingleString({encoding: "UTF-8", input: aData, expected: aExpectedString,
var encoding = "UTF-8";
testSingleString({encoding: encoding, input: aData, expected: aExpectedString,
msg: "testing encoding with valid utf-8 encoding."});
// passing spaces for encoding
testSingleString({encoding: " ", input: aData, error: "TypeError",
encoding = " ";
testSingleString({encoding: encoding, input: aData, error: "RangeError",
errorMessage: errorMessage(encoding),
msg: "constructor encoding, spaces encoding test."});
// invalid encoding passed
testSingleString({encoding: "asdfasdf", input: aData, error: "TypeError",
encoding = "asdfasdf";
testSingleString({encoding: encoding, input: aData, error: "RangeError",
errorMessage: errorMessage(encoding),
msg: "constructor encoding, invalid encoding test."});
// null encoding passed
testSingleString({encoding: null, input: aData, error: "TypeError",
encoding = null;
testSingleString({encoding: encoding, input: aData, error: "RangeError",
errorMessage: errorMessage(encoding),
msg: "constructor encoding, \"null\" encoding test."});
// null encoding passed
testSingleString({encoding: "", input: aData, error: "TypeError",
// empty encoding passed
encoding = "";
testSingleString({encoding: encoding, input: aData, error: "RangeError",
errorMessage: errorMessage(encoding),
msg: "constructor encoding, empty encoding test."});
}
function testEncodingValues(aData, aExpectedString)
{
var encoding = "ISO-8859-11";
testSingleString({encoding: aData, input: encoding, error: "TypeError",
testSingleString({encoding: aData, input: encoding, error: "RangeError",
msg: "encoder encoding values test."});
}
@ -136,7 +149,10 @@ function testSingleString(test)
var stream = test.stream ? {stream: true} : null;
outText = (new TextEncoder(test.encoding)).encode(test.input, stream);
} catch (e) {
assert_equals(e.name, test.error, test.msg);
assert_equals(e.name, test.error, test.msg + " error thrown from the constructor.");
if (test.errorMessage) {
assert_equals(e.message, test.errorMessage, test.msg + " error thrown from the constructor.");
}
return;
}
assert_true(!test.error, test.msg);

View File

@ -43,7 +43,7 @@ test(
bad.forEach(
function(t) {
assert_throws({name: 'EncodingError'}, function () {
assert_throws({name: 'TypeError'}, function () {
new TextDecoder(t.encoding, {fatal: true}).decode(new Uint8Array(t.input));
});
});
@ -186,15 +186,15 @@ test(
test(
function () {
assert_throws({name: 'EncodingError'}, function() { new TextDecoder("utf-8", {fatal: true}).decode(new Uint8Array([0xff])); });
assert_throws({name: 'TypeError'}, function() { new TextDecoder("utf-8", {fatal: true}).decode(new Uint8Array([0xff])); });
// This should not hang:
new TextDecoder("utf-8").decode(new Uint8Array([0xff]));
assert_throws({name: 'EncodingError'}, function() { new TextDecoder("utf-16", {fatal: true}).decode(new Uint8Array([0x00])); });
assert_throws({name: 'TypeError'}, function() { new TextDecoder("utf-16", {fatal: true}).decode(new Uint8Array([0x00])); });
// This should not hang:
new TextDecoder("utf-16").decode(new Uint8Array([0x00]));
assert_throws({name: 'EncodingError'}, function() { new TextDecoder("utf-16be", {fatal: true}).decode(new Uint8Array([0x00])); });
assert_throws({name: 'TypeError'}, function() { new TextDecoder("utf-16be", {fatal: true}).decode(new Uint8Array([0x00])); });
// This should not hang:
new TextDecoder("utf-16be").decode(new Uint8Array([0x00]));
},
@ -215,7 +215,7 @@ test(
legacy_encodings.forEach(function(encoding) {
assert_equals(new TextDecoder(encoding).encoding, encoding);
assert_throws({name: 'TypeError'}, function() { new TextEncoder(encoding); });
assert_throws({name: 'RangeError'}, function() { new TextEncoder(encoding); });
});
},
"Non-UTF encodings supported only for decode, not encode"

View File

@ -95,7 +95,7 @@ Response::Redirect(const GlobalObject& aGlobal, const nsAString& aUrl,
}
if (aStatus != 301 && aStatus != 302 && aStatus != 303 && aStatus != 307 && aStatus != 308) {
aRv.Throw(NS_ERROR_RANGE_ERR);
aRv.ThrowRangeError(MSG_INVALID_REDIRECT_STATUSCODE_ERROR);
return nullptr;
}
@ -122,7 +122,7 @@ Response::Constructor(const GlobalObject& aGlobal,
const ResponseInit& aInit, ErrorResult& aRv)
{
if (aInit.mStatus < 200 || aInit.mStatus > 599) {
aRv.Throw(NS_ERROR_RANGE_ERR);
aRv.ThrowRangeError(MSG_INVALID_RESPONSE_STATUSCODE_ERROR);
return nullptr;
}

View File

@ -3252,7 +3252,10 @@ void HTMLMediaElement::CheckProgress(bool aHaveNewProgress)
if (now - mDataTime >= TimeDuration::FromMilliseconds(STALL_MS)) {
DispatchAsyncEvent(NS_LITERAL_STRING("stalled"));
ChangeDelayLoadStatus(false);
if (IsMediaSourceURI(mLoadingSrc)) {
ChangeDelayLoadStatus(false);
}
NS_ASSERTION(mProgressTimer, "detected stalled without timer");
// Stop timer events, which prevents repeated stalled events until there

View File

@ -33,7 +33,8 @@ parent:
async __delete__();
parent:
async Create();
sync Create() returns (nsresult aResult);
async Destroy();
async SetFocus(bool aRaise);

View File

@ -1096,8 +1096,7 @@ TabChild::Init()
mWidget->Create(
nullptr, 0, // no parents
nsIntRect(nsIntPoint(0, 0), nsIntSize(0, 0)),
nullptr, // HandleWidgetEvent
nullptr // nsDeviceContext
nullptr // HandleWidgetEvent
);
baseWindow->InitWindow(0, mWidget, 0, 0, 0, 0);
@ -3481,19 +3480,20 @@ TabChild::DeallocPPluginWidgetChild(mozilla::plugins::PPluginWidgetChild* aActor
return true;
}
already_AddRefed<nsIWidget>
TabChild::CreatePluginWidget(nsIWidget* aParent)
nsresult
TabChild::CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut)
{
*aOut = nullptr;
mozilla::plugins::PluginWidgetChild* child =
static_cast<mozilla::plugins::PluginWidgetChild*>(SendPPluginWidgetConstructor());
if (!child) {
NS_ERROR("couldn't create PluginWidgetChild");
return nullptr;
return NS_ERROR_UNEXPECTED;
}
nsCOMPtr<nsIWidget> pluginWidget = nsIWidget::CreatePluginProxyWidget(this, child);
if (!pluginWidget) {
NS_ERROR("couldn't create PluginWidgetProxy");
return nullptr;
return NS_ERROR_UNEXPECTED;
}
nsWidgetInitData initData;
@ -3502,11 +3502,12 @@ TabChild::CreatePluginWidget(nsIWidget* aParent)
initData.clipChildren = true;
initData.clipSiblings = true;
nsresult rv = pluginWidget->Create(aParent, nullptr, nsIntRect(nsIntPoint(0, 0),
nsIntSize(0, 0)), nullptr, &initData);
nsIntSize(0, 0)), &initData);
if (NS_FAILED(rv)) {
NS_WARNING("Creating native plugin widget on the chrome side failed.");
}
return pluginWidget.forget();
pluginWidget.forget(aOut);
return rv;
}
TabChildGlobal::TabChildGlobal(TabChildBase* aTabChild)

View File

@ -494,7 +494,7 @@ public:
*/
PPluginWidgetChild* AllocPPluginWidgetChild() MOZ_OVERRIDE;
bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) MOZ_OVERRIDE;
already_AddRefed<nsIWidget> CreatePluginWidget(nsIWidget* aParent);
nsresult CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut);
nsIntPoint GetChromeDisplacement() { return mChromeDisp; };

View File

@ -47,10 +47,13 @@ MediaKeyStatusMap::MediaKeyStatusMap(JSContext* aCx,
if (NS_WARN_IF(!mMap)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
}
mozilla::HoldJSObjects(this);
}
MediaKeyStatusMap::~MediaKeyStatusMap()
{
mozilla::DropJSObjects(this);
}
JSObject*

View File

@ -35,8 +35,7 @@ skip-if = (toolkit == 'android' || buildapp == 'mulet') #timeout android/mulet o
[test_SeekableBeforeEndOfStream.html]
[test_SeekableBeforeEndOfStreamSplit.html]
[test_SeekTwice_mp4.html]
#skip-if = os == 'linux' # No fmp4 support on linux
skip-if = true # Fails on most platforms and was pushed anyway.
skip-if = ((os == "win" && os_version == "5.1") || (os != "win" && os != "mac")) # Only supported on osx and vista+
[test_SetModeThrows.html]
[test_SplitAppendDelay.html]
[test_SplitAppend.html]

View File

@ -2872,7 +2872,10 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
dom::TabChild* tc = dom::TabChild::GetFrom(topWindow);
if (tc) {
// This returns a PluginWidgetProxy which remotes a number of calls.
mWidget = tc->CreatePluginWidget(parentWidget.get());
rv = tc->CreatePluginWidget(parentWidget.get(), getter_AddRefs(mWidget));
if (NS_FAILED(rv)) {
return rv;
}
}
}
}
@ -2888,7 +2891,7 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
initData.clipChildren = true;
initData.clipSiblings = true;
rv = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
nullptr, &initData);
&initData);
if (NS_FAILED(rv)) {
mWidget->Destroy();
mWidget = nullptr;

View File

@ -394,12 +394,12 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
{
PLUGIN_LOG_DEBUG_FUNCTION;
bool enableSandbox = false;
int32_t sandboxLevel = 0;
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
nsAutoCString sandboxPref("dom.ipc.plugins.sandbox.");
nsAutoCString sandboxPref("dom.ipc.plugins.sandbox-level.");
sandboxPref.Append(aPluginTag->GetNiceFileName());
if (NS_FAILED(Preferences::GetBool(sandboxPref.get(), &enableSandbox))) {
enableSandbox = Preferences::GetBool("dom.ipc.plugins.sandbox.default");
if (NS_FAILED(Preferences::GetInt(sandboxPref.get(), &sandboxLevel))) {
sandboxLevel = Preferences::GetInt("dom.ipc.plugins.sandbox-level.default");
}
#endif
@ -408,7 +408,7 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
parent->mSubprocess->SetCallRunnableImmediately(!parent->mIsStartingAsync);
TimeStamp launchStart = TimeStamp::Now();
bool launched = parent->mSubprocess->Launch(Move(onLaunchedRunnable),
enableSandbox);
sandboxLevel);
if (!launched) {
// We never reached open
parent->mShutdown = true;

View File

@ -14,10 +14,6 @@
#include "mozilla/Telemetry.h"
#include "nsThreadUtils.h"
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
#include "mozilla/Preferences.h"
#endif
using std::vector;
using std::string;
@ -48,14 +44,12 @@ PluginProcessParent::~PluginProcessParent()
bool
PluginProcessParent::Launch(mozilla::UniquePtr<LaunchCompleteTask> aLaunchCompleteTask,
bool aEnableSandbox)
int32_t aSandboxLevel)
{
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mEnableNPAPISandbox = aEnableSandbox;
mMoreStrictSandbox =
Preferences::GetBool("dom.ipc.plugins.moreStrictSandbox");
mSandboxLevel = aSandboxLevel;
#else
if (aEnableSandbox) {
if (aSandboxLevel != 0) {
MOZ_ASSERT(false,
"Can't enable an NPAPI process sandbox for platform/build.");
}

View File

@ -50,11 +50,11 @@ public:
*
* @param aLaunchCompleteTask Task that is executed on the main
* thread once the asynchonous launch has completed.
* @param aEnableSandbox Enables a process sandbox if one is available for
* this platform/build. Will assert if true passed and one is not available.
* @param aSandboxLevel Determines the strength of the sandbox.
* <= 0 means no sandbox.
*/
bool Launch(UniquePtr<LaunchCompleteTask> aLaunchCompleteTask = UniquePtr<LaunchCompleteTask>(),
bool aEnableSandbox = false);
int32_t aSandboxLevel = 0);
void Delete();

View File

@ -4,6 +4,7 @@
#include "PluginWidgetParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/ContentParent.h"
#include "nsComponentManagerUtils.h"
#include "nsWidgetsCID.h"
#include "mozilla/DebugOnly.h"
@ -99,14 +100,12 @@ PluginWidgetParent::SendAsyncUpdate(nsIWidget* aWidget)
// makes use of some of the utility functions as well.
bool
PluginWidgetParent::RecvCreate()
PluginWidgetParent::RecvCreate(nsresult* aResult)
{
PWLOG("PluginWidgetParent::RecvCreate()\n");
nsresult rv;
mWidget = do_CreateInstance(kWidgetCID, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "widget create failure");
mWidget = do_CreateInstance(kWidgetCID, aResult);
NS_ASSERTION(NS_SUCCEEDED(*aResult), "widget create failure");
#if defined(MOZ_WIDGET_GTK)
// We need this currently just for GTK in setting up a socket widget
@ -122,17 +121,23 @@ PluginWidgetParent::RecvCreate()
// This returns the top level window widget
nsCOMPtr<nsIWidget> parentWidget = GetTabParent()->GetWidget();
// If this fails, bail.
if (!parentWidget) {
*aResult = NS_ERROR_NOT_AVAILABLE;
return true;
}
nsWidgetInitData initData;
initData.mWindowType = eWindowType_plugin_ipc_chrome;
initData.mUnicode = false;
initData.clipChildren = true;
initData.clipSiblings = true;
rv = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
nullptr, &initData);
if (NS_FAILED(rv)) {
*aResult = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
&initData);
if (NS_FAILED(*aResult)) {
mWidget->Destroy();
mWidget = nullptr;
// This should never fail, abort.
return false;
}

View File

@ -37,7 +37,7 @@ public:
virtual ~PluginWidgetParent();
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool RecvCreate() MOZ_OVERRIDE;
virtual bool RecvCreate(nsresult* aResult) MOZ_OVERRIDE;
virtual bool RecvDestroy() MOZ_OVERRIDE;
virtual bool RecvSetFocus(const bool& aRaise) MOZ_OVERRIDE;
virtual bool RecvGetNativePluginPort(uintptr_t* value) MOZ_OVERRIDE;

View File

@ -80,7 +80,14 @@ SettingsDB.prototype = {
}
}
let chan = NetUtil.newChannel(settingsFile);
let chan = NetUtil.newChannel2(settingsFile,
null,
null,
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
let stream = chan.open();
// Obtain a converter to read from a UTF-8 encoded input stream.
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]

View File

@ -471,7 +471,7 @@ SVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
return;
}
rv.Throw(NS_ERROR_RANGE_ERR);
rv.ThrowRangeError(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR, &aZoomAndPan);
}
//----------------------------------------------------------------------

View File

@ -260,7 +260,7 @@ SVGTransform::SetSkewX(float angle, ErrorResult& rv)
}
if (!IsFinite(tan(angle * kRadPerDegree))) {
rv.Throw(NS_ERROR_RANGE_ERR);
rv.ThrowRangeError(MSG_INVALID_TRANSFORM_ANGLE_ERROR);
return;
}
@ -283,7 +283,7 @@ SVGTransform::SetSkewY(float angle, ErrorResult& rv)
}
if (!IsFinite(tan(angle * kRadPerDegree))) {
rv.Throw(NS_ERROR_RANGE_ERR);
rv.ThrowRangeError(MSG_INVALID_TRANSFORM_ANGLE_ERROR);
return;
}

View File

@ -59,7 +59,7 @@ SVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
return;
}
rv.Throw(NS_ERROR_RANGE_ERR);
rv.ThrowRangeError(MSG_INVALID_ZOOMANDPAN_VALUE_ERROR);
}
//----------------------------------------------------------------------

View File

@ -131,7 +131,7 @@ NetworkService.prototype = {
return;
}
NetUtil.asyncFetch(file, function(inputStream, status) {
NetUtil.asyncFetch2(file, function(inputStream, status) {
let rxBytes = 0,
txBytes = 0,
now = Date.now();
@ -154,7 +154,12 @@ NetworkService.prototype = {
// netd always return success even interface doesn't exist.
callback.networkStatsAvailable(true, rxBytes, txBytes, now);
});
},
null, // aLoadingNode
Services.scriptSecurityManager.getSystemPrincipal(),
null, // aTriggeringPrincipal
Ci.nsILoadInfo.SEC_NORMAL,
Ci.nsIContentPolicy.TYPE_OTHER);
},
setNetworkInterfaceAlarm: function(networkName, threshold, callback) {

View File

@ -58,14 +58,13 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
}
[mHandoffTimer invalidate];
[mHandoffTimer release];
mHandoffTimer = nil;
}
- (void)handoffToGeoIPProvider
{
// Single-shot timers are invalid once executed and are released by the run loop
mHandoffTimer = nil;
[self shutdownHandoffTimer];
mProvider->CreateMLSFallbackProvider();
}
@ -96,11 +95,11 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
// The 2 sec delay is arbitrarily large enough that CL has a reasonable head start and
// if it is likely to succeed, it should complete before the MLS provider.
// Take note that in locationManager:didUpdateLocations: the handoff to MLS is stopped.
mHandoffTimer = [NSTimer scheduledTimerWithTimeInterval:2.0
mHandoffTimer = [[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(handoffToGeoIPProvider)
userInfo:nil
repeats:NO];
repeats:NO] retain];
}
}

View File

@ -1112,7 +1112,7 @@ NS_IMETHODIMP nsWebBrowser::Create()
nsIntRect bounds(mInitInfo->x, mInitInfo->y, mInitInfo->cx, mInitInfo->cy);
mInternalWidget->SetWidgetListener(this);
mInternalWidget->Create(nullptr, mParentNativeWindow, bounds, nullptr, &widgetInit);
mInternalWidget->Create(nullptr, mParentNativeWindow, bounds, &widgetInit);
}
nsCOMPtr<nsIDocShell> docShell(do_CreateInstance("@mozilla.org/docshell;1", &rv));

View File

@ -164,6 +164,9 @@ if (is_win) {
]
libs = []
# Windows-specific sources.
sources += rebase_path(gles_gypi.angle_libangle_win_sources, ".", "src")
# Shared D3dD sources.
if (angle_enable_d3d9 || angle_enable_d3d11) {
sources += rebase_path(gles_gypi.angle_d3d_shared_sources, ".", "src")
@ -218,7 +221,10 @@ if (is_win) {
]
if (is_debug) {
defines += [ "ANGLE_ENABLE_PERF" ]
defines += [
"ANGLE_ENABLE_PERF",
"ANGLE_GENERATE_SHADER_DEBUG_INFO"
]
}
include_dirs = [ "src/libGLESv2" ]

View File

@ -75,7 +75,13 @@
typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP /* Windows Store */
#include <inspectable.h>
typedef IInspectable* EGLNativeWindowType;
#else
typedef HWND EGLNativeWindowType;
#endif
#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */

View File

@ -27,6 +27,10 @@
#include "KHR/khrplatform.h"
#include <map>
#include <string>
#include <vector>
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
@ -42,18 +46,17 @@ typedef unsigned int GLenum;
// Note: make sure to increment ANGLE_SH_VERSION when changing ShaderVars.h
#include "ShaderVars.h"
#ifdef __cplusplus
extern "C" {
#endif
// Version number for shader translation API.
// It is incremented every time the API changes.
#define ANGLE_SH_VERSION 130
#define ANGLE_SH_VERSION 132
typedef enum {
SH_GLES2_SPEC = 0x8B40,
SH_WEBGL_SPEC = 0x8B41,
SH_GLES3_SPEC = 0x8B86,
SH_WEBGL2_SPEC = 0x8B87,
// The CSS Shaders spec is a subset of the WebGL spec.
//
// In both CSS vertex and fragment shaders, ANGLE:
@ -85,31 +88,6 @@ typedef enum {
SH_HLSL11_OUTPUT = 0x8B48
} ShShaderOutput;
typedef enum {
SH_PRECISION_HIGHP = 0x5001,
SH_PRECISION_MEDIUMP = 0x5002,
SH_PRECISION_LOWP = 0x5003,
SH_PRECISION_UNDEFINED = 0
} ShPrecisionType;
typedef enum {
SH_INFO_LOG_LENGTH = 0x8B84,
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
SH_ACTIVE_UNIFORMS = 0x8B86,
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
SH_ACTIVE_ATTRIBUTES = 0x8B89,
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
SH_VARYINGS = 0x8BBB,
SH_VARYING_MAX_LENGTH = 0x8BBC,
SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
SH_NAME_MAX_LENGTH = 0x6001,
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
SH_HASHED_NAMES_COUNT = 0x6003,
SH_SHADER_VERSION = 0x6004,
SH_RESOURCES_STRING_LENGTH = 0x6005,
SH_OUTPUT_TYPE = 0x6006
} ShShaderInfo;
// Compile options.
typedef enum {
SH_VALIDATE = 0,
@ -208,14 +186,14 @@ typedef enum {
//
// Driver must call this first, once, before doing any other
// compiler operations.
// If the function succeeds, the return value is nonzero, else zero.
// If the function succeeds, the return value is true, else false.
//
COMPILER_EXPORT int ShInitialize();
COMPILER_EXPORT bool ShInitialize();
//
// Driver should call this at shutdown.
// If the function succeeds, the return value is nonzero, else zero.
// If the function succeeds, the return value is true, else false.
//
COMPILER_EXPORT int ShFinalize();
COMPILER_EXPORT bool ShFinalize();
// The 64 bits hash function. The first parameter is the input string; the
// second parameter is the string length.
@ -280,8 +258,10 @@ typedef struct
//
// Initialize built-in resources with minimum expected values.
// Parameters:
// resources: The object to initialize. Will be comparable with memcmp.
//
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources *resources);
//
// ShHandle held by but opaque to the driver. It is allocated,
@ -290,18 +270,15 @@ COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources);
//
// If handle creation fails, 0 will be returned.
//
typedef void* ShHandle;
typedef void *ShHandle;
//
// Returns the a concatenated list of the items in ShBuiltInResources as a string.
// Returns the a concatenated list of the items in ShBuiltInResources as a
// null-terminated string.
// This function must be updated whenever ShBuiltInResources is changed.
// Parameters:
// handle: Specifies the handle of the compiler to be used.
// outStringLen: Specifies the size of the buffer, in number of characters. The size
// of the buffer required to store the resources string can be obtained
// by calling ShGetInfo with SH_RESOURCES_STRING_LENGTH.
// outStr: Returns a null-terminated string representing all the built-in resources.
COMPILER_EXPORT void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outStr);
COMPILER_EXPORT const std::string &ShGetBuiltInResourcesString(const ShHandle handle);
//
// Driver calls these to create and destroy compiler objects.
@ -319,12 +296,12 @@ COMPILER_EXPORT ShHandle ShConstructCompiler(
sh::GLenum type,
ShShaderSpec spec,
ShShaderOutput output,
const ShBuiltInResources* resources);
const ShBuiltInResources *resources);
COMPILER_EXPORT void ShDestruct(ShHandle handle);
//
// Compiles the given shader source.
// If the function succeeds, the return value is nonzero, else zero.
// If the function succeeds, the return value is true, else false.
// Parameters:
// handle: Specifies the handle of compiler to be used.
// shaderStrings: Specifies an array of pointers to null-terminated strings
@ -346,123 +323,36 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle);
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
// Can be queried by calling ShGetVariableInfo().
//
COMPILER_EXPORT int ShCompile(
COMPILER_EXPORT bool ShCompile(
const ShHandle handle,
const char* const shaderStrings[],
const char * const shaderStrings[],
size_t numStrings,
int compileOptions
);
int compileOptions);
// Returns a parameter from a compiled shader.
// Return the version of the shader language.
COMPILER_EXPORT int ShGetShaderVersion(const ShHandle handle);
// Return the currently set language output type.
COMPILER_EXPORT ShShaderOutput ShGetShaderOutputType(
const ShHandle handle);
// Returns null-terminated information log for a compiled shader.
// Parameters:
// handle: Specifies the compiler
// pname: Specifies the parameter to query.
// The following parameters are defined:
// SH_INFO_LOG_LENGTH: the number of characters in the information log
// including the null termination character.
// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
// including the null termination character.
// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
// variable name including the null
// termination character.
// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
// variable name including the null
// termination character.
// SH_VARYINGS: the number of varying variables.
// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
// including the null termination character.
// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
// the null termination character.
// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
// null termination character.
// SH_HASHED_NAME_MAX_LENGTH: the max length of a hashed name including the
// null termination character.
// SH_HASHED_NAMES_COUNT: the number of hashed names from the latest compile.
// SH_SHADER_VERSION: the version of the shader language
// SH_OUTPUT_TYPE: the currently set language output type
//
// params: Requested parameter
COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
ShShaderInfo pname,
size_t* params);
// Returns nul-terminated information log for a compiled shader.
// Parameters:
// handle: Specifies the compiler
// infoLog: Specifies an array of characters that is used to return
// the information log. It is assumed that infoLog has enough memory
// to accomodate the information log. The size of the buffer required
// to store the returned information log can be obtained by calling
// ShGetInfo with SH_INFO_LOG_LENGTH.
COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
COMPILER_EXPORT const std::string &ShGetInfoLog(const ShHandle handle);
// Returns null-terminated object code for a compiled shader.
// Parameters:
// handle: Specifies the compiler
// infoLog: Specifies an array of characters that is used to return
// the object code. It is assumed that infoLog has enough memory to
// accomodate the object code. The size of the buffer required to
// store the returned object code can be obtained by calling
// ShGetInfo with SH_OBJECT_CODE_LENGTH.
COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
COMPILER_EXPORT const std::string &ShGetObjectCode(const ShHandle handle);
// Returns information about a shader variable.
// Returns a (original_name, hash) map containing all the user defined
// names in the shader, including variable names, function names, struct
// names, and struct field names.
// Parameters:
// handle: Specifies the compiler
// variableType: Specifies the variable type; options include
// SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
// index: Specifies the index of the variable to be queried.
// length: Returns the number of characters actually written in the string
// indicated by name (excluding the null terminator) if a value other
// than NULL is passed.
// size: Returns the size of the variable.
// type: Returns the data type of the variable.
// precision: Returns the precision of the variable.
// staticUse: Returns 1 if the variable is accessed in a statement after
// pre-processing, whether or not run-time flow of control will
// cause that statement to be executed.
// Returns 0 otherwise.
// name: Returns a null terminated string containing the name of the
// variable. It is assumed that name has enough memory to accormodate
// the variable name. The size of the buffer required to store the
// variable name can be obtained by calling ShGetInfo with
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
// SH_VARYING_MAX_LENGTH.
// mappedName: Returns a null terminated string containing the mapped name of
// the variable, It is assumed that mappedName has enough memory
// (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the
// mapped name. If the name is not mapped, then name and mappedName
// are the same.
COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
ShShaderInfo variableType,
int index,
size_t* length,
int* size,
sh::GLenum* type,
ShPrecisionType* precision,
int* staticUse,
char* name,
char* mappedName);
// Returns information about a name hashing entry from the latest compile.
// Parameters:
// handle: Specifies the compiler
// index: Specifies the index of the name hashing entry to be queried.
// name: Returns a null terminated string containing the user defined name.
// It is assumed that name has enough memory to accomodate the name.
// The size of the buffer required to store the user defined name can
// be obtained by calling ShGetInfo with SH_NAME_MAX_LENGTH.
// hashedName: Returns a null terminated string containing the hashed name of
// the uniform variable, It is assumed that hashedName has enough
// memory to accomodate the name. The size of the buffer required
// to store the name can be obtained by calling ShGetInfo with
// SH_HASHED_NAME_MAX_LENGTH.
COMPILER_EXPORT void ShGetNameHashingEntry(const ShHandle handle,
int index,
char* name,
char* hashedName);
COMPILER_EXPORT const std::map<std::string, std::string> *ShGetNameHashingMap(
const ShHandle handle);
// Shader variable inspection.
// Returns a pointer to a list of variables of the designated type.
@ -482,17 +372,17 @@ typedef struct
int size;
} ShVariableInfo;
// Returns 1 if the passed in variables pack in maxVectors following
// Returns true if the passed in variables pack in maxVectors following
// the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
// Returns 0 otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
// Returns false otherwise. Also look at the SH_ENFORCE_PACKING_RESTRICTIONS
// flag above.
// Parameters:
// maxVectors: the available rows of registers.
// varInfoArray: an array of variable info (types and sizes).
// varInfoArraySize: the size of the variable array.
COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
COMPILER_EXPORT bool ShCheckVariablesWithinPackingLimits(
int maxVectors,
ShVariableInfo* varInfoArray,
ShVariableInfo *varInfoArray,
size_t varInfoArraySize);
// Gives the compiler-assigned register for an interface block.
@ -503,7 +393,7 @@ COMPILER_EXPORT int ShCheckVariablesWithinPackingLimits(
// interfaceBlockName: Specifies the interface block
// indexOut: output variable that stores the assigned register
COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
const char *interfaceBlockName,
const std::string &interfaceBlockName,
unsigned int *indexOut);
// Gives the compiler-assigned register for uniforms in the default
@ -515,11 +405,7 @@ COMPILER_EXPORT bool ShGetInterfaceBlockRegister(const ShHandle handle,
// interfaceBlockName: Specifies the uniform
// indexOut: output variable that stores the assigned register
COMPILER_EXPORT bool ShGetUniformRegister(const ShHandle handle,
const char *uniformName,
const std::string &uniformName,
unsigned int *indexOut);
#ifdef __cplusplus
}
#endif
#endif // _COMPILER_INTERFACE_INCLUDED_

View File

@ -0,0 +1,37 @@
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// angle_windowsstore.h:
#ifndef ANGLE_WINDOWSSTORE_H_
#define ANGLE_WINDOWSSTORE_H_
// The following properties can be set on the CoreApplication to support additional
// ANGLE configuration options.
//
// The Visual Studio sample templates provided with this version of ANGLE have examples
// of how to set these property values.
//
// Property: EGLNativeWindowTypeProperty
// Type: IInspectable
// Description: Set this property to specify the window type to use for creating a surface.
// If this property is missing, surface creation will fail.
//
const wchar_t EGLNativeWindowTypeProperty[] = L"EGLNativeWindowTypeProperty";
//
// Property: EGLRenderSurfaceSizeProperty
// Type: Size
// Description: Set this property to specify a preferred size in pixels of the render surface.
// The render surface size width and height must be greater than 0.
// If this property is set, then the render surface size is fixed.
// If this property is missing, a default behavior will be provided.
// The default behavior uses the window size if a CoreWindow is specified or
// the size of the SwapChainPanel control if one is specified.
//
const wchar_t EGLRenderSurfaceSizeProperty[] = L"EGLRenderSurfaceSizeProperty";
#endif // ANGLE_WINDOWSSTORE_H_

View File

@ -13,6 +13,16 @@
'angle_id_header_base': 'commit.h',
'angle_id_header': '<(angle_gen_path)/id/<(angle_id_header_base)',
'angle_use_commit_id%': '<!(python <(angle_id_script_base) check ..)',
'angle_enable_d3d9%': 0,
'angle_enable_d3d11%': 0,
'conditions':
[
['OS=="win"',
{
'angle_enable_d3d9%': 1,
'angle_enable_d3d11%': 1,
}],
],
},
'includes':
[
@ -26,6 +36,7 @@
{
'target_name': 'copy_scripts',
'type': 'none',
'includes': [ '../build/common_defines.gypi', ],
'hard_dependency': 1,
'copies':
[
@ -34,6 +45,18 @@
'files': [ 'copy_compiler_dll.bat', '<(angle_id_script_base)' ],
},
],
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'type' : 'shared_library',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
],
'conditions':
@ -70,6 +93,18 @@
'<(angle_gen_path)',
],
},
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'type' : 'shared_library',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
}
]
},
@ -80,6 +115,7 @@
'target_name': 'commit_id',
'type': 'none',
'hard_dependency': 1,
'includes': [ '../build/common_defines.gypi', ],
'copies':
[
{
@ -94,6 +130,18 @@
'<(angle_gen_path)',
],
},
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'type' : 'shared_library',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
}
]
}],
@ -106,23 +154,38 @@
'type': 'none',
'dependencies': [ 'copy_scripts', ],
'includes': [ '../build/common_defines.gypi', ],
'actions':
'conditions':
[
['angle_build_winrt==0',
{
'action_name': 'copy_dll',
'message': 'Copying D3D Compiler DLL...',
'msvs_cygwin_shell': 0,
'inputs': [ 'copy_compiler_dll.bat' ],
'outputs': [ '<(PRODUCT_DIR)/d3dcompiler_46.dll' ],
'action':
'actions':
[
"<(angle_gen_path)/copy_compiler_dll.bat",
"$(PlatformName)",
"<(windows_sdk_path)",
"<(PRODUCT_DIR)"
],
},
], #actions
{
'action_name': 'copy_dll',
'message': 'Copying D3D Compiler DLL...',
'msvs_cygwin_shell': 0,
'inputs': [ 'copy_compiler_dll.bat' ],
'outputs': [ '<(PRODUCT_DIR)/d3dcompiler_46.dll' ],
'action':
[
"<(angle_gen_path)/copy_compiler_dll.bat",
"$(PlatformName)",
"<(windows_sdk_path)",
"<(PRODUCT_DIR)"
],
},
], #actions
}],
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
'type' : 'shared_library',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
]
},
], # targets
}],

View File

@ -1,10 +0,0 @@
# Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'includes':
[
'angle.gypi',
],
}

View File

@ -1,3 +1,3 @@
#define ANGLE_COMMIT_HASH "0fb6a60df77b"
#define ANGLE_COMMIT_HASH "180bf375fb42"
#define ANGLE_COMMIT_HASH_SIZE 12
#define ANGLE_COMMIT_DATE "2014-11-28 13:56:37 -0500"
#define ANGLE_COMMIT_DATE "2015-02-05 14:21:03 -0500"

View File

@ -16,28 +16,41 @@
#include "common/debug.h"
#include "common/platform.h"
#ifdef ANGLE_ENABLE_D3D11
// DXGISwapChain and DXGIFactory are typedef'd to specific required
// types. The HWND NativeWindow implementation requires IDXGISwapChain
// and IDXGIFactory and the Windows Store NativeWindow
// implementation requires IDXGISwapChain1 and IDXGIFactory2.
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
typedef IDXGISwapChain1 DXGISwapChain;
typedef IDXGIFactory2 DXGIFactory;
#include <wrl.h>
#include <wrl/wrappers/corewrappers.h>
#include <windows.applicationmodel.core.h>
#include <memory>
class IInspectableNativeWindow;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
#else
#ifdef ANGLE_ENABLE_D3D11
typedef IDXGISwapChain DXGISwapChain;
typedef IDXGIFactory DXGIFactory;
#endif
#endif
namespace rx
{
class NativeWindow
{
public:
public:
explicit NativeWindow(EGLNativeWindowType window);
// The HWND NativeWindow implementation can benefit
// by having inline versions of these methods to
// reduce the calling overhead.
inline bool initialize() { return true; }
inline bool getClientRect(LPRECT rect) { return GetClientRect(mWindow, rect) == TRUE; }
inline bool isIconic() { return IsIconic(mWindow) == TRUE; }
bool initialize();
bool getClientRect(LPRECT rect);
bool isIconic();
#ifdef ANGLE_ENABLE_D3D11
HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory,
@ -47,8 +60,13 @@ class NativeWindow
inline EGLNativeWindowType getNativeWindow() const { return mWindow; }
private:
private:
EGLNativeWindowType mWindow;
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
std::shared_ptr<IInspectableNativeWindow> mImpl;
#endif
};
}

View File

@ -5,26 +5,32 @@
//
#include "common/angleutils.h"
#include "debug.h"
#include <stdio.h>
#include <vector>
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& outBuffer)
{
// Attempt to just print to the current buffer
int len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
if (len < 0 || static_cast<size_t>(len) >= outBuffer.size())
{
// Buffer was not large enough, calculate the required size and resize the buffer
len = vsnprintf(NULL, 0, fmt, vararg);
outBuffer.resize(len + 1);
// Print again
len = vsnprintf(&(outBuffer.front()), outBuffer.size(), fmt, vararg);
}
ASSERT(len >= 0);
return static_cast<size_t>(len);
}
std::string FormatString(const char *fmt, va_list vararg)
{
static std::vector<char> buffer(512);
// Attempt to just print to the current buffer
int len = vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
if (len < 0 || static_cast<size_t>(len) >= buffer.size())
{
// Buffer was not large enough, calculate the required size and resize the buffer
len = vsnprintf(NULL, 0, fmt, vararg);
buffer.resize(len + 1);
// Print again
vsnprintf(&buffer[0], buffer.size(), fmt, vararg);
}
size_t len = FormatStringIntoVector(fmt, vararg, buffer);
return std::string(&buffer[0], len);
}

View File

@ -17,6 +17,7 @@
#include <set>
#include <sstream>
#include <cstdarg>
#include <vector>
// A macro to disallow the copy constructor and operator= functions
// This must be used in the private: declarations for a class
@ -95,6 +96,13 @@ inline void StructZero(T *obj)
memset(obj, 0, sizeof(T));
}
template <typename T>
inline bool IsMaskFlagSet(T mask, T flag)
{
// Handles multibit flags as well
return (mask & flag) == flag;
}
inline const char* MakeStaticString(const std::string &str)
{
static std::set<std::string> strings;
@ -132,6 +140,8 @@ inline std::string Str(int i)
return strstr.str();
}
size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
std::string FormatString(const char *fmt, va_list vararg);
std::string FormatString(const char *fmt, ...);

View File

@ -17,41 +17,211 @@
namespace gl
{
#if defined(ANGLE_ENABLE_PERF)
typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
#else
typedef void (*PerfOutputFunction)(unsigned int, const wchar_t*);
#endif
static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
// Wraps the D3D9/D3D11 debug annotation functions.
class DebugAnnotationWrapper
{
#if defined(ANGLE_ENABLE_PERF) || defined(ANGLE_ENABLE_TRACE)
std::string formattedMessage = FormatString(format, vararg);
public:
DebugAnnotationWrapper() { };
virtual ~DebugAnnotationWrapper() { };
virtual void beginEvent(const std::wstring &eventName) = 0;
virtual void endEvent() = 0;
virtual void setMarker(const std::wstring &markerName) = 0;
virtual bool getStatus() = 0;
};
#if defined(ANGLE_ENABLE_D3D9)
class D3D9DebugAnnotationWrapper : public DebugAnnotationWrapper
{
public:
void beginEvent(const std::wstring &eventName)
{
D3DPERF_BeginEvent(0, eventName.c_str());
}
void endEvent()
{
D3DPERF_EndEvent();
}
void setMarker(const std::wstring &markerName)
{
D3DPERF_SetMarker(0, markerName.c_str());
}
bool getStatus()
{
return !!D3DPERF_GetStatus();
}
};
#endif // ANGLE_ENABLE_D3D9
#if defined(ANGLE_ENABLE_D3D11)
class D3D11DebugAnnotationWrapper : public DebugAnnotationWrapper
{
public:
D3D11DebugAnnotationWrapper()
: mInitialized(false),
mD3d11Module(NULL),
mUserDefinedAnnotation(NULL)
{
// D3D11 devices can't be created during DllMain.
// We defer device creation until the object is actually used.
}
~D3D11DebugAnnotationWrapper()
{
if (mInitialized)
{
SafeRelease(mUserDefinedAnnotation);
FreeLibrary(mD3d11Module);
}
}
virtual void beginEvent(const std::wstring &eventName)
{
initializeDevice();
mUserDefinedAnnotation->BeginEvent(eventName.c_str());
}
virtual void endEvent()
{
initializeDevice();
mUserDefinedAnnotation->EndEvent();
}
virtual void setMarker(const std::wstring &markerName)
{
initializeDevice();
mUserDefinedAnnotation->SetMarker(markerName.c_str());
}
virtual bool getStatus()
{
// ID3DUserDefinedAnnotation::GetStatus doesn't work with the Graphics Diagnostics tools in Visual Studio 2013.
#if defined(_DEBUG) && defined(ANGLE_ENABLE_WINDOWS_STORE)
// In the Windows Store, we can use IDXGraphicsAnalysis. The call to GetDebugInterface1 only succeeds if the app is under capture.
// This should only be called in DEBUG mode.
// If an app links against DXGIGetDebugInterface1 in release mode then it will fail Windows Store ingestion checks.
IDXGraphicsAnalysis* graphicsAnalysis;
DXGIGetDebugInterface1(0, IID_PPV_ARGS(&graphicsAnalysis));
bool underCapture = (graphicsAnalysis != NULL);
SafeRelease(graphicsAnalysis);
return underCapture;
#endif
#if defined(ANGLE_ENABLE_PERF)
// Otherwise, we have to return true here.
return true;
}
protected:
void initializeDevice()
{
if (!mInitialized)
{
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
ASSERT(mD3d11Module);
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
ASSERT(D3D11CreateDevice != NULL);
#endif // !ANGLE_ENABLE_WINDOWS_STORE
ID3D11Device* device = NULL;
ID3D11DeviceContext* context = NULL;
HRESULT hr = E_FAIL;
// Create a D3D_DRIVER_TYPE_NULL device, which is much cheaper than other types of device.
hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context);
ASSERT(SUCCEEDED(hr));
hr = context->QueryInterface(__uuidof(mUserDefinedAnnotation), reinterpret_cast<void**>(&mUserDefinedAnnotation));
ASSERT(SUCCEEDED(hr) && mUserDefinedAnnotation != NULL);
SafeRelease(device);
SafeRelease(context);
mInitialized = true;
}
}
bool mInitialized;
HMODULE mD3d11Module;
ID3DUserDefinedAnnotation* mUserDefinedAnnotation;
};
#endif // ANGLE_ENABLE_D3D11
static DebugAnnotationWrapper* g_DebugAnnotationWrapper = NULL;
void InitializeDebugAnnotations()
{
#if defined(ANGLE_ENABLE_D3D9)
g_DebugAnnotationWrapper = new D3D9DebugAnnotationWrapper();
#elif defined(ANGLE_ENABLE_D3D11)
// If the project uses D3D9 then we can use the D3D9 debug annotations, even with the D3D11 renderer.
// However, if D3D9 is unavailable (e.g. in Windows Store), then we use D3D11 debug annotations.
// The D3D11 debug annotations are methods on ID3DUserDefinedAnnotation, which is implemented by the DeviceContext.
// This doesn't have to be the same DeviceContext that the renderer uses, though.
g_DebugAnnotationWrapper = new D3D11DebugAnnotationWrapper();
#endif
}
void UninitializeDebugAnnotations()
{
if (g_DebugAnnotationWrapper != NULL)
{
SafeDelete(g_DebugAnnotationWrapper);
}
}
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
enum DebugTraceOutputType
{
DebugTraceOutputTypeNone,
DebugTraceOutputTypeSetMarker,
DebugTraceOutputTypeBeginEvent
};
static void output(bool traceInDebugOnly, DebugTraceOutputType outputType, const char *format, va_list vararg)
{
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
static std::vector<char> buffer(512);
if (perfActive())
{
// The perf function only accepts wide strings, widen the ascii message
static std::wstring wideMessage;
if (wideMessage.capacity() < formattedMessage.length())
size_t len = FormatStringIntoVector(format, vararg, buffer);
std::wstring formattedWideMessage(buffer.begin(), buffer.begin() + len);
switch (outputType)
{
wideMessage.reserve(formattedMessage.size());
case DebugTraceOutputTypeNone:
break;
case DebugTraceOutputTypeBeginEvent:
g_DebugAnnotationWrapper->beginEvent(formattedWideMessage);
break;
case DebugTraceOutputTypeSetMarker:
g_DebugAnnotationWrapper->setMarker(formattedWideMessage);
break;
}
wideMessage.assign(formattedMessage.begin(), formattedMessage.end());
perfFunc(0, wideMessage.c_str());
}
#endif // ANGLE_ENABLE_PERF
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
#if defined(ANGLE_ENABLE_TRACE)
#if defined(ANGLE_ENABLE_DEBUG_TRACE)
#if defined(NDEBUG)
if (traceFileDebugOnly)
if (traceInDebugOnly)
{
return;
}
#endif // NDEBUG
std::string formattedMessage = FormatString(format, vararg);
static std::ofstream file(TRACE_OUTPUT_FILE, std::ofstream::app);
if (file)
@ -60,25 +230,29 @@ static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const c
file.flush();
}
#endif // ANGLE_ENABLE_TRACE
#if defined(ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER)
OutputDebugStringA(formattedMessage.c_str());
#endif // ANGLE_ENABLE_DEBUG_TRACE_TO_DEBUGGER
#endif // ANGLE_ENABLE_DEBUG_TRACE
}
void trace(bool traceFileDebugOnly, const char *format, ...)
void trace(bool traceInDebugOnly, const char *format, ...)
{
va_list vararg;
va_start(vararg, format);
#if defined(ANGLE_ENABLE_PERF)
output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
output(traceInDebugOnly, DebugTraceOutputTypeSetMarker, format, vararg);
#else
output(traceFileDebugOnly, NULL, format, vararg);
output(traceInDebugOnly, DebugTraceOutputTypeNone, format, vararg);
#endif
va_end(vararg);
}
bool perfActive()
{
#if defined(ANGLE_ENABLE_PERF)
static bool active = D3DPERF_GetStatus() != 0;
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
static bool active = g_DebugAnnotationWrapper->getStatus();
return active;
#else
return false;
@ -87,28 +261,28 @@ bool perfActive()
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
{
#if !defined(ANGLE_ENABLE_TRACE)
#if !defined(ANGLE_ENABLE_DEBUG_TRACE)
if (!perfActive())
{
return;
}
#endif // !ANGLE_ENABLE_TRACE
#endif // !ANGLE_ENABLE_DEBUG_TRACE
va_list vararg;
va_start(vararg, format);
#if defined(ANGLE_ENABLE_PERF)
output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
output(true, DebugTraceOutputTypeBeginEvent, format, vararg);
#else
output(true, NULL, format, vararg);
#endif // ANGLE_ENABLE_PERF
output(true, DebugTraceOutputTypeNone, format, vararg);
#endif // ANGLE_ENABLE_DEBUG_ANNOTATIONS
va_end(vararg);
}
ScopedPerfEventHelper::~ScopedPerfEventHelper()
{
#if defined(ANGLE_ENABLE_PERF)
#if defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
if (perfActive())
{
D3DPERF_EndEvent();
g_DebugAnnotationWrapper->endEvent();
}
#endif
}

View File

@ -20,8 +20,8 @@
namespace gl
{
// Outputs text to the debugging log
void trace(bool traceFileDebugOnly, const char *format, ...);
// Outputs text to the debugging log, or the debugging window
void trace(bool traceInDebugOnly, const char *format, ...);
// Returns whether D3DPERF is active.
bool perfActive();
@ -36,31 +36,34 @@ namespace gl
private:
DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper);
};
void InitializeDebugAnnotations();
void UninitializeDebugAnnotations();
}
// A macro to output a trace of a function call and its arguments to the debugging log
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define TRACE(message, ...) (void(0))
#endif
// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing.
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define FIXME(message, ...) (void(0))
#endif
// A macro to output a function call and its arguments to the debugging log, in case of error.
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#define ERR(message, ...) gl::trace(false, "err: %s(%d): " message "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#else
#define ERR(message, ...) (void(0))
#endif
// A macro to log a performance event around a scope.
#if defined(ANGLE_ENABLE_TRACE) || defined(ANGLE_ENABLE_PERF)
#if defined(ANGLE_ENABLE_DEBUG_TRACE) || defined(ANGLE_ENABLE_DEBUG_ANNOTATIONS)
#if defined(_MSC_VER)
#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__("%s" message "\n", __FUNCTION__, __VA_ARGS__);
#else
@ -83,7 +86,7 @@ namespace gl
#define UNUSED_ASSERTION_VARIABLE(variable) ((void)variable)
#endif
#ifndef ANGLE_ENABLE_TRACE
#ifndef ANGLE_ENABLE_DEBUG_TRACE
#define UNUSED_TRACE_VARIABLE(variable) ((void)variable)
#else
#define UNUSED_TRACE_VARIABLE(variable)

View File

@ -0,0 +1,35 @@
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#define ANGLE_DISABLED 0
#define ANGLE_ENABLED 1
// Feature defaults
// Direct3D9EX
// The "Debug This Pixel..." feature in PIX often fails when using the
// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7
// machine, define "ANGLE_D3D9EX=0" in your project file.
#if !defined(ANGLE_D3D9EX)
#define ANGLE_D3D9EX ANGLE_ENABLED
#endif
// Vsync
// ENABLED allows Vsync to be configured at runtime
// DISABLED disallows Vsync
#if !defined(ANGLE_VSYNC)
#define ANGLE_VSYNC ANGLE_ENABLED
#endif
// Program binary loading
#if !defined(ANGLE_PROGRAM_BINARY_LOAD)
#define ANGLE_PROGRAM_BINARY_LOAD ANGLE_ENABLED
#endif
// Shader debug info
#if !defined(ANGLE_SHADER_DEBUG_INFO)
#define ANGLE_SHADER_DEBUG_INFO ANGLE_DISABLED
#endif

View File

@ -109,7 +109,7 @@ inline unsigned int unorm(float x)
inline bool supportsSSE2()
{
#ifdef ANGLE_PLATFORM_WINDOWS
#if ANGLE_PLATFORM_WINDOWS && !defined(_M_ARM)
static bool checked = false;
static bool supports = false;

View File

@ -34,6 +34,9 @@
#endif
#ifdef ANGLE_PLATFORM_WINDOWS
# if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP
# define ANGLE_ENABLE_WINDOWS_STORE 1
# endif
# ifndef STRICT
# define STRICT 1
# endif
@ -47,7 +50,7 @@
# include <windows.h>
# include <intrin.h>
# if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_PERF)
# if defined(ANGLE_ENABLE_D3D9)
# include <d3d9.h>
# include <d3dcompiler.h>
# endif
@ -55,11 +58,20 @@
# if defined(ANGLE_ENABLE_D3D11)
# include <d3d10_1.h>
# include <d3d11.h>
# include <d3d11_1.h>
# include <dxgi.h>
# include <dxgi1_2.h>
# include <d3dcompiler.h>
# endif
# if defined(ANGLE_ENABLE_WINDOWS_STORE)
# include <dxgi1_3.h>
# if defined(_DEBUG)
# include <DXProgrammableCapture.h>
# include <dxgidebug.h>
# endif
# endif
# undef near
# undef far
#endif

View File

@ -10,12 +10,50 @@
#include <assert.h>
#ifdef ANGLE_ENABLE_WINDOWS_STORE
#include <vector>
#include <set>
#include <map>
#include <mutex>
#include <wrl/client.h>
#include <wrl/async.h>
#include <Windows.System.Threading.h>
using namespace std;
using namespace Windows::Foundation;
using namespace ABI::Windows::System::Threading;
// Thread local storage for Windows Store support
typedef vector<void*> ThreadLocalData;
static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
static set<ThreadLocalData*> allThreadData;
static DWORD nextTlsIndex = 0;
static vector<DWORD> freeTlsIndices;
#endif
TLSIndex CreateTLSIndex()
{
TLSIndex index;
#ifdef ANGLE_PLATFORM_WINDOWS
#ifdef ANGLE_ENABLE_WINDOWS_STORE
if (!freeTlsIndices.empty())
{
DWORD result = freeTlsIndices.back();
freeTlsIndices.pop_back();
index = result;
}
else
{
index = nextTlsIndex++;
}
#else
index = TlsAlloc();
#endif
#elif defined(ANGLE_PLATFORM_POSIX)
// Create global pool key
if ((pthread_key_create(&index, NULL)) != 0)
@ -37,7 +75,22 @@ bool DestroyTLSIndex(TLSIndex index)
}
#ifdef ANGLE_PLATFORM_WINDOWS
#ifdef ANGLE_ENABLE_WINDOWS_STORE
assert(index < nextTlsIndex);
assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
freeTlsIndices.push_back(index);
for (auto threadData : allThreadData)
{
if (threadData->size() > index)
{
threadData->at(index) = nullptr;
}
}
return true;
#else
return (TlsFree(index) == TRUE);
#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return (pthread_key_delete(index) == 0);
#endif
@ -52,7 +105,24 @@ bool SetTLSValue(TLSIndex index, void *value)
}
#ifdef ANGLE_PLATFORM_WINDOWS
#ifdef ANGLE_ENABLE_WINDOWS_STORE
ThreadLocalData* threadData = currentThreadData;
if (!threadData)
{
threadData = new ThreadLocalData(index + 1, nullptr);
allThreadData.insert(threadData);
currentThreadData = threadData;
}
else if (threadData->size() <= index)
{
threadData->resize(index + 1, nullptr);
}
threadData->at(index) = value;
return true;
#else
return (TlsSetValue(index, value) == TRUE);
#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return (pthread_setspecific(index, value) == 0);
#endif
@ -67,7 +137,19 @@ void *GetTLSValue(TLSIndex index)
}
#ifdef ANGLE_PLATFORM_WINDOWS
#ifdef ANGLE_ENABLE_WINDOWS_STORE
ThreadLocalData* threadData = currentThreadData;
if (threadData && threadData->size() > index)
{
return threadData->at(index);
}
else
{
return nullptr;
}
#else
return TlsGetValue(index);
#endif
#elif defined(ANGLE_PLATFORM_POSIX)
return pthread_getspecific(index);
#endif

View File

@ -12,6 +12,14 @@
#include "common/platform.h"
#ifdef ANGLE_PLATFORM_WINDOWS
// TLS does not exist for Windows Store and needs to be emulated
# ifdef ANGLE_ENABLE_WINDOWS_STORE
# define TLS_OUT_OF_INDEXES -1
# ifndef CREATE_SUSPENDED
# define CREATE_SUSPENDED 0x00000004
# endif
# endif
typedef DWORD TLSIndex;
# define TLS_INVALID_INDEX (TLS_OUT_OF_INDEXES)
#elif defined(ANGLE_PLATFORM_POSIX)
@ -24,6 +32,9 @@
# error Unsupported platform.
#endif
// TODO(kbr): for POSIX platforms this will have to be changed to take
// in a destructor function pointer, to allow the thread-local storage
// to be properly deallocated upon thread exit.
TLSIndex CreateTLSIndex();
bool DestroyTLSIndex(TLSIndex index);

View File

@ -12,6 +12,13 @@
#include <set>
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
# include <wrl.h>
# include <wrl/wrappers/corewrappers.h>
# include <windows.applicationmodel.core.h>
# include <windows.graphics.display.h>
#endif
namespace gl
{
@ -439,6 +446,7 @@ int VariableSortOrder(GLenum type)
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
std::string getTempPath()
{
#ifdef ANGLE_PLATFORM_WINDOWS
@ -476,3 +484,33 @@ void writeFile(const char* path, const void* content, size_t size)
fwrite(content, sizeof(char), size, file);
fclose(file);
}
#endif // !ANGLE_ENABLE_WINDOWS_STORE
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
void Sleep(unsigned long dwMilliseconds)
{
static HANDLE singletonEvent = nullptr;
HANDLE sleepEvent = singletonEvent;
if (!sleepEvent)
{
sleepEvent = CreateEventEx(nullptr, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS);
if (!sleepEvent)
return;
HANDLE previousEvent = InterlockedCompareExchangePointerRelease(&singletonEvent, sleepEvent, nullptr);
if (previousEvent)
{
// Back out if multiple threads try to demand create at the same time.
CloseHandle(sleepEvent);
sleepEvent = previousEvent;
}
}
// Emulate sleep by waiting with timeout on an event that is never signalled.
WaitForSingleObjectEx(sleepEvent, dwMilliseconds, false);
}
#endif // ANGLE_ENABLE_WINDOWS_STORE

View File

@ -46,7 +46,13 @@ template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(
}
#if !defined(ANGLE_ENABLE_WINDOWS_STORE)
std::string getTempPath();
void writeFile(const char* path, const void* data, size_t size);
#endif
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
void Sleep(_In_ unsigned long dwMilliseconds);
#endif
#endif // LIBGLESV2_UTILITIES_H

View File

@ -20,6 +20,21 @@ NativeWindow::NativeWindow(EGLNativeWindowType window) : mWindow(window)
{
}
bool NativeWindow::initialize()
{
return true;
}
bool NativeWindow::getClientRect(LPRECT rect)
{
return GetClientRect(mWindow, rect) == TRUE;
}
bool NativeWindow::isIconic()
{
return IsIconic(mWindow) == TRUE;
}
#ifdef ANGLE_ENABLE_D3D11
HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory,
DXGI_FORMAT format, unsigned int width, unsigned int height,

View File

@ -0,0 +1,184 @@
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CoreWindowNativeWindow.cpp: NativeWindow for managing ICoreWindow native window types.
#include <windows.graphics.display.h>
#include "common/winrt/CoreWindowNativeWindow.h"
using namespace ABI::Windows::Foundation::Collections;
CoreWindowNativeWindow::~CoreWindowNativeWindow()
{
unregisterForSizeChangeEvents();
}
bool CoreWindowNativeWindow::initialize(EGLNativeWindowType window, IPropertySet *propertySet)
{
ComPtr<IPropertySet> props = propertySet;
ComPtr<IInspectable> win = window;
SIZE swapChainSize = {};
bool swapChainSizeSpecified = false;
HRESULT result = S_OK;
// IPropertySet is an optional parameter and can null.
// If one is specified, cache as an IMap and read the properties
// used for initial host initialization.
if (propertySet)
{
result = props.As(&mPropertyMap);
if (SUCCEEDED(result))
{
// The EGLRenderSurfaceSizeProperty is optional and may be missing. The IPropertySet
// was prevalidated to contain the EGLNativeWindowType before being passed to
// this host.
result = getOptionalSizePropertyValue(mPropertyMap, EGLRenderSurfaceSizeProperty, &swapChainSize, &swapChainSizeSpecified);
}
}
if (SUCCEEDED(result))
{
result = win.As(&mCoreWindow);
}
if (SUCCEEDED(result))
{
// If a swapchain size is specfied, then the automatic resize
// behaviors implemented by the host should be disabled. The swapchain
// will be still be scaled when being rendered to fit the bounds
// of the host.
// Scaling of the swapchain output occurs automatically because if
// the scaling mode setting DXGI_SCALING_STRETCH on the swapchain.
if (swapChainSizeSpecified)
{
mClientRect = { 0, 0, swapChainSize.cx, swapChainSize.cy };
mSupportsSwapChainResize = false;
}
else
{
result = getCoreWindowSizeInPixels(mCoreWindow, &mClientRect);
}
}
if (SUCCEEDED(result))
{
mNewClientRect = mClientRect;
mClientRectChanged = false;
return registerForSizeChangeEvents();
}
return false;
}
bool CoreWindowNativeWindow::registerForSizeChangeEvents()
{
ComPtr<IWindowSizeChangedEventHandler> sizeChangedHandler;
HRESULT result = Microsoft::WRL::MakeAndInitialize<CoreWindowSizeChangedHandler>(sizeChangedHandler.ReleaseAndGetAddressOf(), this->shared_from_this());
if (SUCCEEDED(result))
{
result = mCoreWindow->add_SizeChanged(sizeChangedHandler.Get(), &mSizeChangedEventToken);
}
if (SUCCEEDED(result))
{
return true;
}
return false;
}
void CoreWindowNativeWindow::unregisterForSizeChangeEvents()
{
if (mCoreWindow)
{
(void)mCoreWindow->remove_SizeChanged(mSizeChangedEventToken);
}
mSizeChangedEventToken.value = 0;
}
HRESULT CoreWindowNativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
{
if (device == NULL || factory == NULL || swapChain == NULL || width == 0 || height == 0)
{
return E_INVALIDARG;
}
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
swapChainDesc.Width = width;
swapChainDesc.Height = height;
swapChainDesc.Format = format;
swapChainDesc.Stereo = FALSE;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER;
swapChainDesc.BufferCount = 2;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
*swapChain = nullptr;
ComPtr<IDXGISwapChain1> newSwapChain;
HRESULT result = factory->CreateSwapChainForCoreWindow(device, mCoreWindow.Get(), &swapChainDesc, nullptr, newSwapChain.ReleaseAndGetAddressOf());
if (SUCCEEDED(result))
{
#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
// Test if swapchain supports resize. On Windows Phone devices, this will return DXGI_ERROR_UNSUPPORTED. On
// other devices DXGI_ERROR_INVALID_CALL should be returned because the combination of flags passed
// (DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) are invalid flag combinations.
if (newSwapChain->ResizeBuffers(swapChainDesc.BufferCount, swapChainDesc.Width, swapChainDesc.Height, swapChainDesc.Format, DXGI_SWAP_CHAIN_FLAG_NONPREROTATED | DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE) == DXGI_ERROR_UNSUPPORTED)
{
mSupportsSwapChainResize = false;
}
#endif // (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
result = newSwapChain.CopyTo(swapChain);
}
if (SUCCEEDED(result))
{
// If automatic swapchain resize behaviors have been disabled, then
// unregister for the resize change events.
if (mSupportsSwapChainResize == false)
{
unregisterForSizeChangeEvents();
}
}
return result;
}
HRESULT getCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize)
{
ABI::Windows::Foundation::Rect bounds;
HRESULT result = coreWindow->get_Bounds(&bounds);
if (SUCCEEDED(result))
{
*windowSize = { 0, 0, ConvertDipsToPixels(bounds.Width), ConvertDipsToPixels(bounds.Height) };
}
return result;
}
static float GetLogicalDpi()
{
ComPtr<ABI::Windows::Graphics::Display::IDisplayPropertiesStatics> displayProperties;
float dpi = 96.0f;
if (SUCCEEDED(GetActivationFactory(HStringReference(RuntimeClass_Windows_Graphics_Display_DisplayProperties).Get(), displayProperties.GetAddressOf())))
{
if (SUCCEEDED(displayProperties->get_LogicalDpi(&dpi)))
{
return dpi;
}
}
return dpi;
}
long ConvertDipsToPixels(float dips)
{
static const float dipsPerInch = 96.0f;
return lround((dips * GetLogicalDpi() / dipsPerInch));
}

View File

@ -0,0 +1,71 @@
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CoreWindowNativeWindow.h: NativeWindow for managing ICoreWindow native window types.
#ifndef COMMON_COREWINDOWNATIVEWINDOW_H_
#define COMMON_COREWINDOWNATIVEWINDOW_H_
#include "common/winrt/IInspectableNativeWindow.h"
#include <memory>
typedef ABI::Windows::Foundation::__FITypedEventHandler_2_Windows__CUI__CCore__CCoreWindow_Windows__CUI__CCore__CWindowSizeChangedEventArgs_t IWindowSizeChangedEventHandler;
long ConvertDipsToPixels(float dips);
class CoreWindowNativeWindow : public IInspectableNativeWindow, public std::enable_shared_from_this<CoreWindowNativeWindow>
{
public:
~CoreWindowNativeWindow();
bool initialize(EGLNativeWindowType window, IPropertySet *propertySet);
bool registerForSizeChangeEvents();
void unregisterForSizeChangeEvents();
HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain);
private:
ComPtr<ABI::Windows::UI::Core::ICoreWindow> mCoreWindow;
ComPtr<IMap<HSTRING, IInspectable*>> mPropertyMap;
};
[uuid(7F924F66-EBAE-40E5-A10B-B8F35E245190)]
class CoreWindowSizeChangedHandler :
public Microsoft::WRL::RuntimeClass<Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>, IWindowSizeChangedEventHandler>
{
public:
CoreWindowSizeChangedHandler() { }
HRESULT RuntimeClassInitialize(std::shared_ptr<IInspectableNativeWindow> host)
{
if (!host)
{
return E_INVALIDARG;
}
mHost = host;
return S_OK;
}
// IWindowSizeChangedEventHandler
IFACEMETHOD(Invoke)(ABI::Windows::UI::Core::ICoreWindow *sender, ABI::Windows::UI::Core::IWindowSizeChangedEventArgs *e)
{
std::shared_ptr<IInspectableNativeWindow> host = mHost.lock();
if (host)
{
ABI::Windows::Foundation::Size windowSize;
if (SUCCEEDED(e->get_Size(&windowSize)))
{
SIZE windowSizeInPixels = { ConvertDipsToPixels(windowSize.Width), ConvertDipsToPixels(windowSize.Height) };
host->setNewClientSize(windowSizeInPixels);
}
}
return S_OK;
}
private:
std::weak_ptr<IInspectableNativeWindow> mHost;
};
HRESULT getCoreWindowSizeInPixels(const ComPtr<ABI::Windows::UI::Core::ICoreWindow>& coreWindow, RECT *windowSize);
#endif // COMMON_COREWINDOWNATIVEWINDOW_H_

View File

@ -0,0 +1,245 @@
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// iinspectablehost.cpp: NativeWindow base class for managing IInspectable native window types.
#include "common/winrt/CoreWindowNativeWindow.h"
namespace rx
{
NativeWindow::NativeWindow(EGLNativeWindowType window)
{
mWindow = window;
}
bool NativeWindow::initialize()
{
// If the native window type is a IPropertySet, extract the
// EGLNativeWindowType (IInspectable) and initialize the
// proper host with this IPropertySet.
ComPtr<ABI::Windows::Foundation::Collections::IPropertySet> propertySet;
ComPtr<IInspectable> eglNativeWindow;
if (isEGLConfiguredPropertySet(mWindow, &propertySet, &eglNativeWindow))
{
// A property set was found and the EGLNativeWindowType was
// retrieved. The mWindow member of the host to must be updated
// to use the EGLNativeWindowType specified in the property set.
// mWindow is treated as a raw pointer not an AddRef'd interface, so
// the old mWindow does not need a Release() before this assignment.
mWindow = eglNativeWindow.Get();
}
// If the native window is a ICoreWindow, initialize a CoreWindowNativeWindow
ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
if (isCoreWindow(mWindow, &coreWindow))
{
mImpl = std::make_shared<CoreWindowNativeWindow>();
if (mImpl)
{
return mImpl->initialize(mWindow, propertySet.Get());
}
}
else
{
ERR("Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include ICoreWindow and IPropertySet");
}
return false;
}
bool NativeWindow::getClientRect(RECT *rect)
{
if (mImpl)
{
return mImpl->getClientRect(rect);
}
return false;
}
bool NativeWindow::isIconic()
{
return false;
}
HRESULT NativeWindow::createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain)
{
if (mImpl)
{
return mImpl->createSwapChain(device, factory, format, width, height, swapChain);
}
return E_UNEXPECTED;
}
}
bool isCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow)
{
if (!window)
{
return false;
}
ComPtr<IInspectable> win = window;
ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWin;
if (SUCCEEDED(win.As(&coreWin)))
{
if (coreWindow != nullptr)
{
*coreWindow = coreWin.Detach();
}
return true;
}
return false;
}
bool isEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet, IInspectable **eglNativeWindow)
{
if (!window)
{
return false;
}
ComPtr<IInspectable> props = window;
ComPtr<IPropertySet> propSet;
ComPtr<IInspectable> nativeWindow;
ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> propMap;
boolean hasEglNativeWindowPropertyKey = false;
HRESULT result = props.As(&propSet);
if (SUCCEEDED(result))
{
result = propSet.As(&propMap);
}
// Look for the presence of the EGLNativeWindowType in the property set
if (SUCCEEDED(result))
{
result = propMap->HasKey(HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEglNativeWindowPropertyKey);
}
// If the IPropertySet does not contain the required EglNativeWindowType key, the property set is
// considered invalid.
if (SUCCEEDED(result) && !hasEglNativeWindowPropertyKey)
{
ERR("Could not find EGLNativeWindowTypeProperty in IPropertySet. Valid EGLNativeWindowTypeProperty values include ICoreWindow");
return false;
}
// The EglNativeWindowType property exists, so retreive the IInspectable that represents the EGLNativeWindowType
if (SUCCEEDED(result) && hasEglNativeWindowPropertyKey)
{
result = propMap->Lookup(HStringReference(EGLNativeWindowTypeProperty).Get(), &nativeWindow);
}
if (SUCCEEDED(result))
{
if (propertySet != nullptr)
{
result = propSet.CopyTo(propertySet);
}
}
if (SUCCEEDED(result))
{
if (eglNativeWindow != nullptr)
{
result = nativeWindow.CopyTo(eglNativeWindow);
}
}
if (SUCCEEDED(result))
{
return true;
}
return false;
}
// A Valid EGLNativeWindowType IInspectable can only be:
//
// ICoreWindow
// IPropertySet
//
// Anything else will be rejected as an invalid IInspectable.
bool isValidEGLNativeWindowType(EGLNativeWindowType window)
{
return isCoreWindow(window) || isEGLConfiguredPropertySet(window);
}
// Attempts to read an optional SIZE property value that is assumed to be in the form of
// an ABI::Windows::Foundation::Size. This function validates the Size value before returning
// it to the caller.
//
// Possible return values are:
// S_OK, valueExists == true - optional SIZE value was successfully retrieved and validated
// S_OK, valueExists == false - optional SIZE value was not found
// E_INVALIDARG, valueExists = false - optional SIZE value was malformed in the property set.
// * Incorrect property type ( must be PropertyType_Size)
// * Invalid property value (width/height must be > 0)
// Additional errors may be returned from IMap or IPropertyValue
//
HRESULT getOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists)
{
if (!propertyMap || !propertyName || !value || !valueExists)
{
return false;
}
// Assume that the value does not exist
*valueExists = false;
*value = { 0, 0 };
ComPtr<ABI::Windows::Foundation::IPropertyValue> propertyValue;
ABI::Windows::Foundation::PropertyType propertyType = ABI::Windows::Foundation::PropertyType::PropertyType_Empty;
Size sizeValue = { 0, 0 };
boolean hasKey = false;
HRESULT result = propertyMap->HasKey(HStringReference(propertyName).Get(), &hasKey);
if (SUCCEEDED(result) && !hasKey)
{
// Value does not exist, so return S_OK and set the exists parameter to false to indicate
// that a the optional property does not exist.
*valueExists = false;
return S_OK;
}
if (SUCCEEDED(result))
{
result = propertyMap->Lookup(HStringReference(propertyName).Get(), &propertyValue);
}
if (SUCCEEDED(result))
{
result = propertyValue->get_Type(&propertyType);
}
// Check if the expected Size property is of PropertyType_Size type.
if (SUCCEEDED(result) && propertyType == ABI::Windows::Foundation::PropertyType::PropertyType_Size)
{
if (SUCCEEDED(propertyValue->GetSize(&sizeValue)) && (sizeValue.Width > 0 && sizeValue.Height > 0))
{
// A valid property value exists
*value = { static_cast<long>(sizeValue.Width), static_cast<long>(sizeValue.Height) };
*valueExists = true;
result = S_OK;
}
else
{
// An invalid Size property was detected. Width/Height values must > 0
result = E_INVALIDARG;
}
}
else
{
// An invalid property type was detected. Size property must be of PropertyType_Size
result = E_INVALIDARG;
}
return result;
}

View File

@ -0,0 +1,86 @@
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// IInspectableNativeWindow.h: Host specific implementation interface for
// managing IInspectable native window types.
#ifndef COMMON_IINSPECTABLENATIVEWINDOW_H_
#define COMMON_IINSPECTABLENATIVEWINDOW_H_
#include "common/platform.h"
#include "common/NativeWindow.h"
#include "angle_windowsstore.h"
#include <windows.ui.xaml.h>
#include <windows.ui.xaml.media.dxinterop.h>
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
class IInspectableNativeWindow
{
public:
virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
virtual HRESULT createSwapChain(ID3D11Device *device, DXGIFactory *factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain **swapChain) = 0;
virtual bool registerForSizeChangeEvents() = 0;
virtual void unregisterForSizeChangeEvents() = 0;
virtual HRESULT scaleSwapChain(const SIZE& newSize) { return S_OK; }
IInspectableNativeWindow() :
mSupportsSwapChainResize(true),
mRequiresSwapChainScaling(false),
mClientRectChanged(false),
mClientRect({0,0,0,0}),
mNewClientRect({0,0,0,0})
{
mSizeChangedEventToken.value = 0;
}
virtual ~IInspectableNativeWindow(){}
bool getClientRect(RECT *rect)
{
if (mClientRectChanged && mSupportsSwapChainResize)
{
mClientRect = mNewClientRect;
}
*rect = mClientRect;
return true;
}
void setNewClientSize(const SIZE &newSize)
{
if (mSupportsSwapChainResize && !mRequiresSwapChainScaling)
{
mNewClientRect = { 0, 0, newSize.cx, newSize.cy };
mClientRectChanged = true;
}
if (mRequiresSwapChainScaling)
{
scaleSwapChain(newSize);
}
}
protected:
bool mSupportsSwapChainResize;
bool mRequiresSwapChainScaling;
RECT mClientRect;
RECT mNewClientRect;
bool mClientRectChanged;
EventRegistrationToken mSizeChangedEventToken;
};
bool isCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
bool isEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);
HRESULT getOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>>& propertyMap, const wchar_t *propertyName, SIZE *value, bool *valueExists);
#endif // COMMON_IINSPECTABLENATIVEWINDOW_H_

View File

@ -205,6 +205,17 @@
'type': 'static_library',
'includes': [ '../build/common_defines.gypi', ],
'sources': [ '<@(angle_preprocessor_sources)', ],
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
{
'target_name': 'translator_lib',
@ -233,6 +244,17 @@
'AdditionalOptions': ['/ignore:4221']
},
},
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
{
@ -254,6 +276,17 @@
'compiler/translator/ShaderLang.cpp',
'compiler/translator/ShaderVars.cpp'
],
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
{
@ -282,6 +315,17 @@
'compiler/translator/ShaderLang.cpp',
'compiler/translator/ShaderVars.cpp'
],
'conditions':
[
['angle_build_winrt==1',
{
'msvs_enable_winrt' : '1',
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
},
],
}

View File

@ -29,7 +29,8 @@ class DirectiveHandler
// Handle pragma of form: #pragma name[(value)]
virtual void handlePragma(const SourceLocation &loc,
const std::string &name,
const std::string &value) = 0;
const std::string &value,
bool stdgl) = 0;
virtual void handleExtension(const SourceLocation &loc,
const std::string &name,

View File

@ -38,19 +38,19 @@ enum DirectiveType
DirectiveType getDirective(const pp::Token *token)
{
static const std::string kDirectiveDefine("define");
static const std::string kDirectiveUndef("undef");
static const std::string kDirectiveIf("if");
static const std::string kDirectiveIfdef("ifdef");
static const std::string kDirectiveIfndef("ifndef");
static const std::string kDirectiveElse("else");
static const std::string kDirectiveElif("elif");
static const std::string kDirectiveEndif("endif");
static const std::string kDirectiveError("error");
static const std::string kDirectivePragma("pragma");
static const std::string kDirectiveExtension("extension");
static const std::string kDirectiveVersion("version");
static const std::string kDirectiveLine("line");
const char kDirectiveDefine[] = "define";
const char kDirectiveUndef[] = "undef";
const char kDirectiveIf[] = "if";
const char kDirectiveIfdef[] = "ifdef";
const char kDirectiveIfndef[] = "ifndef";
const char kDirectiveElse[] = "else";
const char kDirectiveElif[] = "elif";
const char kDirectiveEndif[] = "endif";
const char kDirectiveError[] = "error";
const char kDirectivePragma[] = "pragma";
const char kDirectiveExtension[] = "extension";
const char kDirectiveVersion[] = "version";
const char kDirectiveLine[] = "line";
if (token->type != pp::Token::IDENTIFIER)
return DIRECTIVE_NONE;
@ -155,7 +155,7 @@ class DefinedParser : public Lexer
protected:
virtual void lex(Token *token)
{
static const std::string kDefined("defined");
const char kDefined[] = "defined";
mLexer->lex(token);
if (token->type != Token::IDENTIFIER)
@ -592,6 +592,11 @@ void DirectiveParser::parsePragma(Token *token)
int state = PRAGMA_NAME;
mTokenizer->lex(token);
bool stdgl = token->text == "STDGL";
if (stdgl)
{
mTokenizer->lex(token);
}
while ((token->type != '\n') && (token->type != Token::LAST))
{
switch(state++)
@ -627,7 +632,7 @@ void DirectiveParser::parsePragma(Token *token)
}
else if (state > PRAGMA_NAME) // Do not notify for empty pragma.
{
mDirectiveHandler->handlePragma(token->location, name, value);
mDirectiveHandler->handlePragma(token->location, name, value, stdgl);
}
}

View File

@ -194,8 +194,8 @@ bool MacroExpander::expandMacro(const Macro &macro,
if (macro.predefined)
{
static const std::string kLine = "__LINE__";
static const std::string kFile = "__FILE__";
const char kLine[] = "__LINE__";
const char kFile[] = "__FILE__";
assert(replacements->size() == 1);
Token& repl = replacements->front();

View File

@ -29,24 +29,27 @@
bool IsWebGLBasedSpec(ShShaderSpec spec)
{
return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
return (spec == SH_WEBGL_SPEC ||
spec == SH_CSS_SHADERS_SPEC ||
spec == SH_WEBGL2_SPEC);
}
size_t GetGlobalMaxTokenSize(ShShaderSpec spec)
{
// WebGL defines a max token legnth of 256, while ES2 leaves max token
// size undefined. ES3 defines a max size of 1024 characters.
if (IsWebGLBasedSpec(spec))
switch (spec)
{
case SH_WEBGL_SPEC:
case SH_CSS_SHADERS_SPEC:
return 256;
}
else
{
default:
return 1024;
}
}
namespace {
class TScopedPoolAllocator
{
public:
@ -82,6 +85,24 @@ class TScopedSymbolTableLevel
private:
TSymbolTable* mTable;
};
int MapSpecToShaderVersion(ShShaderSpec spec)
{
switch (spec)
{
case SH_GLES2_SPEC:
case SH_WEBGL_SPEC:
case SH_CSS_SHADERS_SPEC:
return 100;
case SH_GLES3_SPEC:
case SH_WEBGL2_SPEC:
return 300;
default:
UNREACHABLE();
return 0;
}
}
} // namespace
TShHandleBase::TShHandleBase()
@ -178,9 +199,21 @@ bool TCompiler::compile(const char* const shaderStrings[],
(parseContext.treeRoot != NULL);
shaderVersion = parseContext.getShaderVersion();
if (success && MapSpecToShaderVersion(shaderSpec) < shaderVersion)
{
infoSink.info.prefix(EPrefixError);
infoSink.info << "unsupported shader version";
success = false;
}
if (success)
{
mPragma = parseContext.pragma();
if (mPragma.stdgl.invariantAll)
{
symbolTable.setGlobalInvariant();
}
TIntermNode* root = parseContext.treeRoot;
success = intermediate.postProcess(root);
@ -378,7 +411,6 @@ void TCompiler::clearResults()
uniforms.clear();
expandedUniforms.clear();
varyings.clear();
expandedVaryings.clear();
interfaceBlocks.clear();
builtInFunctionEmulator.Cleanup();
@ -508,13 +540,12 @@ void TCompiler::collectVariables(TIntermNode* root)
&uniforms,
&varyings,
&interfaceBlocks,
hashFunction);
hashFunction,
symbolTable);
root->traverse(&collect);
// For backwards compatiblity with ShGetVariableInfo, expand struct
// uniforms and varyings into separate variables for each field.
sh::ExpandVariables(uniforms, &expandedUniforms);
sh::ExpandVariables(varyings, &expandedVaryings);
// This is for enforcePackingRestriction().
sh::ExpandUniforms(uniforms, &expandedUniforms);
}
bool TCompiler::enforcePackingRestrictions()
@ -582,3 +613,10 @@ const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
{
return builtInFunctionEmulator;
}
void TCompiler::writePragma()
{
TInfoSinkBase &sink = infoSink.obj;
if (mPragma.stdgl.invariantAll)
sink << "#pragma STDGL invariant(all)\n";
}

View File

@ -18,6 +18,7 @@
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/HashNames.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/Pragma.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VariableInfo.h"
#include "third_party/compiler/ArrayBoundsClamper.h"
@ -71,9 +72,7 @@ class TCompiler : public TShHandleBase
const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
const std::vector<sh::ShaderVariable> &getExpandedUniforms() const { return expandedUniforms; }
const std::vector<sh::Varying> &getVaryings() const { return varyings; }
const std::vector<sh::ShaderVariable> &getExpandedVaryings() const { return expandedVaryings; }
const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
ShHashFunction64 getHashFunction() const { return hashFunction; }
@ -81,7 +80,7 @@ class TCompiler : public TShHandleBase
TSymbolTable& getSymbolTable() { return symbolTable; }
ShShaderSpec getShaderSpec() const { return shaderSpec; }
ShShaderOutput getOutputType() const { return outputType; }
std::string getBuiltInResourcesString() const { return builtInResourcesString; }
const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
// Get the resources set by InitBuiltInSymbolTable
const ShBuiltInResources& getResources() const;
@ -131,6 +130,8 @@ class TCompiler : public TShHandleBase
bool limitExpressionComplexity(TIntermNode* root);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
const TPragma& getPragma() const { return mPragma; }
void writePragma();
const ArrayBoundsClamper& getArrayBoundsClamper() const;
ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
@ -141,7 +142,6 @@ class TCompiler : public TShHandleBase
std::vector<sh::Uniform> uniforms;
std::vector<sh::ShaderVariable> expandedUniforms;
std::vector<sh::Varying> varyings;
std::vector<sh::ShaderVariable> expandedVaryings;
std::vector<sh::InterfaceBlock> interfaceBlocks;
private:
@ -174,6 +174,8 @@ class TCompiler : public TShHandleBase
// name hashing.
ShHashFunction64 hashFunction;
NameMap nameMap;
TPragma mPragma;
};
//

View File

@ -13,10 +13,10 @@
static TBehavior getBehavior(const std::string& str)
{
static const std::string kRequire("require");
static const std::string kEnable("enable");
static const std::string kDisable("disable");
static const std::string kWarn("warn");
const char kRequire[] = "require";
const char kEnable[] = "enable";
const char kDisable[] = "disable";
const char kWarn[] = "warn";
if (str == kRequire) return EBhRequire;
else if (str == kEnable) return EBhEnable;
@ -46,50 +46,61 @@ void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
const std::string& name,
const std::string& value)
const std::string& value,
bool stdgl)
{
static const std::string kSTDGL("STDGL");
static const std::string kOptimize("optimize");
static const std::string kDebug("debug");
static const std::string kOn("on");
static const std::string kOff("off");
if (stdgl)
{
const char kInvariant[] = "invariant";
const char kAll[] = "all";
bool invalidValue = false;
if (name == kSTDGL)
{
if (name == kInvariant && value == kAll)
mPragma.stdgl.invariantAll = true;
// The STDGL pragma is used to reserve pragmas for use by future
// revisions of GLSL. Ignore it.
// revisions of GLSL. Do not generate an error on unexpected
// name and value.
return;
}
else if (name == kOptimize)
{
if (value == kOn) mPragma.optimize = true;
else if (value == kOff) mPragma.optimize = false;
else invalidValue = true;
}
else if (name == kDebug)
{
if (value == kOn) mPragma.debug = true;
else if (value == kOff) mPragma.debug = false;
else invalidValue = true;
}
else
{
mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
return;
}
const char kOptimize[] = "optimize";
const char kDebug[] = "debug";
const char kOn[] = "on";
const char kOff[] = "off";
if (invalidValue)
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
"invalid pragma value", value,
"'on' or 'off' expected");
bool invalidValue = false;
if (name == kOptimize)
{
if (value == kOn) mPragma.optimize = true;
else if (value == kOff) mPragma.optimize = false;
else invalidValue = true;
}
else if (name == kDebug)
{
if (value == kOn) mPragma.debug = true;
else if (value == kOff) mPragma.debug = false;
else invalidValue = true;
}
else
{
mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
return;
}
if (invalidValue)
{
mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
"invalid pragma value", value,
"'on' or 'off' expected");
}
}
}
void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
const std::string& name,
const std::string& behavior)
{
static const std::string kExtAll("all");
const char kExtAll[] = "all";
TBehavior behaviorVal = getBehavior(behavior);
if (behaviorVal == EBhUndefined)

View File

@ -29,7 +29,8 @@ class TDirectiveHandler : public pp::DirectiveHandler
virtual void handlePragma(const pp::SourceLocation& loc,
const std::string& name,
const std::string& value);
const std::string& value,
bool stdgl);
virtual void handleExtension(const pp::SourceLocation& loc,
const std::string& name,

View File

@ -133,6 +133,14 @@ bool CompareStructure(const TType &leftNodeType,
//
////////////////////////////////////////////////////////////////
void TIntermTyped::setTypePreservePrecision(const TType &t)
{
TPrecision precision = getPrecision();
mType = t;
ASSERT(mType.getBasicType() != EbtBool || precision == EbpUndefined);
mType.setPrecision(precision);
}
#define REPLACE_IF_IS(node, type, original, replacement) \
if (node == original) { \
node = static_cast<type *>(replacement); \
@ -237,6 +245,52 @@ void TIntermAggregate::enqueueChildren(std::queue<TIntermNode *> *nodeQueue) con
}
}
void TIntermAggregate::setPrecisionFromChildren()
{
if (getBasicType() == EbtBool)
{
mType.setPrecision(EbpUndefined);
return;
}
TPrecision precision = EbpUndefined;
TIntermSequence::iterator childIter = mSequence.begin();
while (childIter != mSequence.end())
{
TIntermTyped *typed = (*childIter)->getAsTyped();
if (typed)
precision = GetHigherPrecision(typed->getPrecision(), precision);
++childIter;
}
mType.setPrecision(precision);
}
void TIntermAggregate::setBuiltInFunctionPrecision()
{
// All built-ins returning bool should be handled as ops, not functions.
ASSERT(getBasicType() != EbtBool);
TPrecision precision = EbpUndefined;
TIntermSequence::iterator childIter = mSequence.begin();
while (childIter != mSequence.end())
{
TIntermTyped *typed = (*childIter)->getAsTyped();
// ESSL spec section 8: texture functions get their precision from the sampler.
if (typed && IsSampler(typed->getBasicType()))
{
precision = typed->getPrecision();
break;
}
++childIter;
}
// ESSL 3.0 spec section 8: textureSize always gets highp precision.
// All other functions that take a sampler are assumed to be texture functions.
if (mName.find("textureSize") == 0)
mType.setPrecision(EbpHigh);
else
mType.setPrecision(precision);
}
bool TIntermSelection::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@ -336,6 +390,7 @@ bool TIntermUnary::promote(TInfoSink &)
return false;
break;
case EOpNegative:
case EOpPositive:
case EOpPostIncrement:
case EOpPostDecrement:
case EOpPreIncrement:
@ -1068,6 +1123,27 @@ TIntermTyped *TIntermConstantUnion::fold(
}
break;
case EOpPositive:
switch (getType().getBasicType())
{
case EbtFloat:
tempConstArray[i].setFConst(unionArray[i].getFConst());
break;
case EbtInt:
tempConstArray[i].setIConst(unionArray[i].getIConst());
break;
case EbtUInt:
tempConstArray[i].setUConst(static_cast<unsigned int>(
static_cast<int>(unionArray[i].getUConst())));
break;
default:
infoSink.info.message(
EPrefixInternalError, getLine(),
"Unary operation not folded into constant");
return NULL;
}
break;
case EOpLogicalNot:
// this code is written for possible future use,
// will not get executed currently

View File

@ -45,6 +45,7 @@ enum TOperator
//
EOpNegative,
EOpPositive,
EOpLogicalNot,
EOpVectorLogicalNot,
@ -265,6 +266,7 @@ class TIntermTyped : public TIntermNode
virtual bool hasSideEffects() const = 0;
void setType(const TType &t) { mType = t; }
void setTypePreservePrecision(const TType &t);
const TType &getType() const { return mType; }
TType *getTypePointer() { return &mType; }
@ -613,6 +615,9 @@ class TIntermAggregate : public TIntermOperator
virtual void enqueueChildren(std::queue<TIntermNode *> *nodeQueue) const;
void setPrecisionFromChildren();
void setBuiltInFunctionPrecision();
protected:
TIntermAggregate(const TIntermAggregate &); // disallow copy constructor
TIntermAggregate &operator=(const TIntermAggregate &); // disallow assignment operator

View File

@ -198,6 +198,7 @@ TIntermTyped *TIntermediate::addUnaryMath(
case EOpPostDecrement:
case EOpPreDecrement:
case EOpNegative:
case EOpPositive:
if (child->getType().getBasicType() == EbtStruct ||
child->getType().isArray())
{

View File

@ -395,6 +395,7 @@ bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: preString = "(-"; break;
case EOpPositive: preString = "(+"; break;
case EOpVectorLogicalNot: preString = "not("; break;
case EOpLogicalNot: preString = "(!"; break;
@ -649,17 +650,18 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
mDeclaringVariables = false;
}
break;
case EOpInvariantDeclaration: {
// Invariant declaration.
ASSERT(visit == PreVisit);
case EOpInvariantDeclaration:
// Invariant declaration.
ASSERT(visit == PreVisit);
{
const TIntermSequence *sequence = node->getSequence();
ASSERT(sequence && sequence->size() == 1);
const TIntermSymbol *symbol = sequence->front()->getAsSymbolNode();
ASSERT(symbol);
out << "invariant " << symbol->getSymbol() << ";";
visitChildren = false;
break;
out << "invariant " << hashVariableName(symbol->getSymbol());
}
visitChildren = false;
break;
case EOpConstructFloat:
writeTriplet(visit, "float(", NULL, ")");
break;
@ -741,7 +743,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate *node)
writeBuiltInFunctionTriplet(visit, "notEqual(", useEmulatedFunction);
break;
case EOpComma:
writeTriplet(visit, NULL, ", ", NULL);
writeTriplet(visit, "(", ", ", ")");
break;
case EOpMod:

View File

@ -320,14 +320,22 @@ void OutputHLSL::header()
if (mUsesDiscardRewriting)
{
out << "#define ANGLE_USES_DISCARD_REWRITING" << "\n";
out << "#define ANGLE_USES_DISCARD_REWRITING\n";
}
if (mUsesNestedBreak)
{
out << "#define ANGLE_USES_NESTED_BREAK" << "\n";
out << "#define ANGLE_USES_NESTED_BREAK\n";
}
out << "#ifdef ANGLE_ENABLE_LOOP_FLATTEN\n"
"#define LOOP [loop]\n"
"#define FLATTEN [flatten]\n"
"#else\n"
"#define LOOP\n"
"#define FLATTEN\n"
"#endif\n";
if (mContext.shaderType == GL_FRAGMENT_SHADER)
{
TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
@ -1747,6 +1755,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: outputTriplet(visit, "(-", "", ")"); break;
case EOpPositive: outputTriplet(visit, "(+", "", ")"); break;
case EOpVectorLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpLogicalNot: outputTriplet(visit, "(!", "", ")"); break;
case EOpPostIncrement: outputTriplet(visit, "(", "", "++)"); break;
@ -1860,15 +1869,20 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (!variable->getAsSymbolNode() || variable->getAsSymbolNode()->getSymbol() != "") // Variable declaration
{
if (!mInsideFunction)
{
out << "static ";
}
out << TypeString(variable->getType()) + " ";
for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
{
if (isSingleStatement(*sit))
{
mUnfoldShortCircuit->traverse(*sit);
}
if (!mInsideFunction)
{
out << "static ";
}
out << TypeString(variable->getType()) + " ";
TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
if (symbol)
@ -1884,7 +1898,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
if (*sit != sequence->back())
{
out << ", ";
out << ";\n";
}
}
}
@ -2287,7 +2301,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
{
mUnfoldShortCircuit->traverse(node->getCondition());
out << "if (";
out << "FLATTEN if (";
node->getCondition()->traverse(this);
@ -2367,14 +2381,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
if (node->getType() == ELoopDoWhile)
{
out << "{do\n";
out << "{LOOP do\n";
outputLineDirective(node->getLine().first_line);
out << "{\n";
}
else
{
out << "{for(";
out << "{LOOP for(";
if (node->getInit())
{
@ -2503,6 +2517,12 @@ bool OutputHLSL::isSingleStatement(TIntermNode *node)
{
return false;
}
else if (aggregate->getOp() == EOpDeclaration)
{
// Declaring multiple comma-separated variables must be considered multiple statements
// because each individual declaration has side effects which are visible in the next.
return false;
}
else
{
for (TIntermSequence::iterator sit = aggregate->getSequence()->begin(); sit != aggregate->getSequence()->end(); sit++)
@ -2675,7 +2695,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
// for(int index = initial; index < clampedLimit; index += increment)
out << "for(";
out << "LOOP for(";
index->traverse(this);
out << " = ";
out << initial;

View File

@ -1004,12 +1004,12 @@ void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char*
directiveHandler.handleExtension(srcLoc, extName, behavior);
}
void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value)
void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl)
{
pp::SourceLocation srcLoc;
srcLoc.file = loc.first_file;
srcLoc.line = loc.first_line;
directiveHandler.handlePragma(srcLoc, name, value);
directiveHandler.handlePragma(srcLoc, name, value, stdgl);
}
/////////////////////////////////////////////////////////////////////////////////
@ -1364,11 +1364,18 @@ TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &inv
{
error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
recover();
return NULL;
}
else
{
const TString kGlFrontFacing("gl_FrontFacing");
if (*identifier == kGlFrontFacing)
{
error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
recover();
return NULL;
}
symbolTable.addInvariantVarying(std::string(identifier->c_str()));
const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
ASSERT(variable);
const TType &type = variable->getType();

View File

@ -116,7 +116,7 @@ struct TParseContext {
bool supportsExtension(const char* extension);
bool isExtensionEnabled(const char* extension) const;
void handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior);
void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value);
void handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl);
bool containsSampler(TType& type);
bool areAllChildConst(TIntermAggregate* aggrNode);

View File

@ -7,13 +7,23 @@
#ifndef COMPILER_PRAGMA_H_
#define COMPILER_PRAGMA_H_
struct TPragma {
struct TPragma
{
struct STDGL
{
STDGL() : invariantAll(false) { }
bool invariantAll;
};
// By default optimization is turned on and debug is turned off.
TPragma() : optimize(true), debug(false) { }
TPragma(bool o, bool d) : optimize(o), debug(d) { }
bool optimize;
bool debug;
STDGL stdgl;
};
#endif // COMPILER_PRAGMA_H_

View File

@ -37,72 +37,6 @@ bool isInitialized = false;
// and the shading language compiler.
//
static bool CheckVariableMaxLengths(const ShHandle handle,
size_t expectedValue)
{
size_t activeUniformLimit = 0;
ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
size_t activeAttribLimit = 0;
ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
size_t varyingLimit = 0;
ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
return (expectedValue == activeUniformLimit &&
expectedValue == activeAttribLimit &&
expectedValue == varyingLimit);
}
bool CheckMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
{
size_t mappedNameMaxLength = 0;
ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
return (expectedValue == mappedNameMaxLength);
}
template <typename VarT>
const sh::ShaderVariable *ReturnVariable(const std::vector<VarT> &infoList, int index)
{
if (index < 0 || static_cast<size_t>(index) >= infoList.size())
{
return NULL;
}
return &infoList[index];
}
const sh::ShaderVariable *GetVariable(const TCompiler *compiler, ShShaderInfo varType, int index)
{
switch (varType)
{
case SH_ACTIVE_ATTRIBUTES:
return ReturnVariable(compiler->getAttributes(), index);
case SH_ACTIVE_UNIFORMS:
return ReturnVariable(compiler->getExpandedUniforms(), index);
case SH_VARYINGS:
return ReturnVariable(compiler->getExpandedVaryings(), index);
default:
UNREACHABLE();
return NULL;
}
}
ShPrecisionType ConvertPrecision(sh::GLenum precision)
{
switch (precision)
{
case GL_HIGH_FLOAT:
case GL_HIGH_INT:
return SH_PRECISION_HIGHP;
case GL_MEDIUM_FLOAT:
case GL_MEDIUM_INT:
return SH_PRECISION_MEDIUMP;
case GL_LOW_FLOAT:
case GL_LOW_INT:
return SH_PRECISION_LOWP;
default:
return SH_PRECISION_UNDEFINED;
}
}
template <typename VarT>
const std::vector<VarT> *GetVariableList(const TCompiler *compiler, ShaderVariableType variableType);
@ -150,32 +84,48 @@ const std::vector<VarT> *GetShaderVariables(const ShHandle handle, ShaderVariabl
return GetVariableList<VarT>(compiler, variableType);
}
TCompiler *GetCompilerFromHandle(ShHandle handle)
{
if (!handle)
return NULL;
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
return base->getAsCompiler();
}
TranslatorHLSL *GetTranslatorHLSLFromHandle(ShHandle handle)
{
if (!handle)
return NULL;
TShHandleBase *base = static_cast<TShHandleBase *>(handle);
return base->getAsTranslatorHLSL();
}
} // namespace anonymous
//
// Driver must call this first, once, before doing any other compiler operations.
// Subsequent calls to this function are no-op.
//
int ShInitialize()
bool ShInitialize()
{
if (!isInitialized)
{
isInitialized = InitProcess();
}
return isInitialized ? 1 : 0;
return isInitialized;
}
//
// Cleanup symbol tables
//
int ShFinalize()
bool ShFinalize()
{
if (isInitialized)
{
DetachProcess();
isInitialized = false;
}
return 1;
return true;
}
//
@ -183,6 +133,9 @@ int ShFinalize()
//
void ShInitBuiltInResources(ShBuiltInResources* resources)
{
// Make comparable.
memset(resources, 0, sizeof(*resources));
// Constants.
resources->MaxVertexAttribs = 8;
resources->MaxVertexUniformVectors = 128;
@ -253,23 +206,13 @@ void ShDestruct(ShHandle handle)
DeleteCompiler(base->getAsCompiler());
}
void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, char *outString)
const std::string &ShGetBuiltInResourcesString(const ShHandle handle)
{
if (!handle || !outString)
{
return;
}
TShHandleBase *base = static_cast<TShHandleBase*>(handle);
TCompiler *compiler = base->getAsCompiler();
if (!compiler)
{
return;
}
strncpy(outString, compiler->getBuiltInResourcesString().c_str(), outStringLen);
outString[outStringLen - 1] = '\0';
TCompiler *compiler = GetCompilerFromHandle(handle);
ASSERT(compiler);
return compiler->getBuiltInResourcesString();
}
//
// Do an actual compile on the given strings. The result is left
// in the given compile object.
@ -277,219 +220,62 @@ void ShGetBuiltInResourcesString(const ShHandle handle, size_t outStringLen, cha
// Return: The return value of ShCompile is really boolean, indicating
// success or failure.
//
int ShCompile(
bool ShCompile(
const ShHandle handle,
const char* const shaderStrings[],
const char *const shaderStrings[],
size_t numStrings,
int compileOptions)
{
if (handle == 0)
return 0;
TCompiler *compiler = GetCompilerFromHandle(handle);
ASSERT(compiler);
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
return 0;
bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
return success ? 1 : 0;
return compiler->compile(shaderStrings, numStrings, compileOptions);
}
void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
int ShGetShaderVersion(const ShHandle handle)
{
if (!handle || !params)
return;
TCompiler* compiler = GetCompilerFromHandle(handle);
ASSERT(compiler);
return compiler->getShaderVersion();
}
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (!compiler) return;
switch(pname)
{
case SH_INFO_LOG_LENGTH:
*params = compiler->getInfoSink().info.size() + 1;
break;
case SH_OBJECT_CODE_LENGTH:
*params = compiler->getInfoSink().obj.size() + 1;
break;
case SH_ACTIVE_UNIFORMS:
*params = compiler->getExpandedUniforms().size();
break;
case SH_ACTIVE_UNIFORM_MAX_LENGTH:
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
break;
case SH_ACTIVE_ATTRIBUTES:
*params = compiler->getAttributes().size();
break;
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
break;
case SH_VARYINGS:
*params = compiler->getExpandedVaryings().size();
break;
case SH_VARYING_MAX_LENGTH:
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
break;
case SH_MAPPED_NAME_MAX_LENGTH:
// Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
// handle array and struct dereferences.
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
break;
case SH_NAME_MAX_LENGTH:
*params = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
break;
case SH_HASHED_NAME_MAX_LENGTH:
if (compiler->getHashFunction() == NULL) {
*params = 0;
} else {
// 64 bits hashing output requires 16 bytes for hex
// representation.
const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
(void)HashedNamePrefix;
*params = 16 + sizeof(HashedNamePrefix);
}
break;
case SH_HASHED_NAMES_COUNT:
*params = compiler->getNameMap().size();
break;
case SH_SHADER_VERSION:
*params = compiler->getShaderVersion();
break;
case SH_RESOURCES_STRING_LENGTH:
*params = compiler->getBuiltInResourcesString().length() + 1;
break;
case SH_OUTPUT_TYPE:
*params = compiler->getOutputType();
break;
default: UNREACHABLE();
}
ShShaderOutput ShGetShaderOutputType(const ShHandle handle)
{
TCompiler* compiler = GetCompilerFromHandle(handle);
ASSERT(compiler);
return compiler->getOutputType();
}
//
// Return any compiler log of messages for the application.
//
void ShGetInfoLog(const ShHandle handle, char* infoLog)
const std::string &ShGetInfoLog(const ShHandle handle)
{
if (!handle || !infoLog)
return;
TCompiler *compiler = GetCompilerFromHandle(handle);
ASSERT(compiler);
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (!compiler) return;
TInfoSink& infoSink = compiler->getInfoSink();
strcpy(infoLog, infoSink.info.c_str());
TInfoSink &infoSink = compiler->getInfoSink();
return infoSink.info.str();
}
//
// Return any object code.
//
void ShGetObjectCode(const ShHandle handle, char* objCode)
const std::string &ShGetObjectCode(const ShHandle handle)
{
if (!handle || !objCode)
return;
TCompiler *compiler = GetCompilerFromHandle(handle);
ASSERT(compiler);
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (!compiler) return;
TInfoSink& infoSink = compiler->getInfoSink();
strcpy(objCode, infoSink.obj.c_str());
TInfoSink &infoSink = compiler->getInfoSink();
return infoSink.obj.str();
}
void ShGetVariableInfo(const ShHandle handle,
ShShaderInfo varType,
int index,
size_t* length,
int* size,
sh::GLenum* type,
ShPrecisionType* precision,
int* staticUse,
char* name,
char* mappedName)
const std::map<std::string, std::string> *ShGetNameHashingMap(
const ShHandle handle)
{
if (!handle || !size || !type || !precision || !staticUse || !name)
return;
ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
(varType == SH_ACTIVE_UNIFORMS) ||
(varType == SH_VARYINGS));
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
return;
const sh::ShaderVariable *varInfo = GetVariable(compiler, varType, index);
if (!varInfo)
{
return;
}
if (length) *length = varInfo->name.size();
*size = varInfo->elementCount();
*type = varInfo->type;
*precision = ConvertPrecision(varInfo->precision);
*staticUse = varInfo->staticUse ? 1 : 0;
// This size must match that queried by
// SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
// in ShGetInfo, below.
size_t variableLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
ASSERT(CheckVariableMaxLengths(handle, variableLength));
strncpy(name, varInfo->name.c_str(), variableLength);
name[variableLength - 1] = 0;
if (mappedName)
{
// This size must match that queried by
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
size_t maxMappedNameLength = 1 + GetGlobalMaxTokenSize(compiler->getShaderSpec());
ASSERT(CheckMappedNameMaxLength(handle, maxMappedNameLength));
strncpy(mappedName, varInfo->mappedName.c_str(), maxMappedNameLength);
mappedName[maxMappedNameLength - 1] = 0;
}
}
void ShGetNameHashingEntry(const ShHandle handle,
int index,
char* name,
char* hashedName)
{
if (!handle || !name || !hashedName || index < 0)
return;
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (!compiler) return;
const NameMap& nameMap = compiler->getNameMap();
if (index >= static_cast<int>(nameMap.size()))
return;
NameMap::const_iterator it = nameMap.begin();
for (int i = 0; i < index; ++i)
++it;
size_t len = it->first.length() + 1;
size_t max_len = 0;
ShGetInfo(handle, SH_NAME_MAX_LENGTH, &max_len);
if (len > max_len) {
ASSERT(false);
len = max_len;
}
strncpy(name, it->first.c_str(), len);
// To be on the safe side in case the source is longer than expected.
name[len - 1] = '\0';
len = it->second.length() + 1;
max_len = 0;
ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &max_len);
if (len > max_len) {
ASSERT(false);
len = max_len;
}
strncpy(hashedName, it->second.c_str(), len);
// To be on the safe side in case the source is longer than expected.
hashedName[len - 1] = '\0';
TCompiler *compiler = GetCompilerFromHandle(handle);
ASSERT(compiler);
return &(compiler->getNameMap());
}
const std::vector<sh::Uniform> *ShGetUniforms(const ShHandle handle)
@ -517,11 +303,11 @@ const std::vector<sh::InterfaceBlock> *ShGetInterfaceBlocks(const ShHandle handl
return GetShaderVariables<sh::InterfaceBlock>(handle, SHADERVAR_INTERFACEBLOCK);
}
int ShCheckVariablesWithinPackingLimits(
int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
bool ShCheckVariablesWithinPackingLimits(
int maxVectors, ShVariableInfo *varInfoArray, size_t varInfoArraySize)
{
if (varInfoArraySize == 0)
return 1;
return true;
ASSERT(varInfoArray);
std::vector<sh::ShaderVariable> variables;
for (size_t ii = 0; ii < varInfoArraySize; ++ii)
@ -530,24 +316,17 @@ int ShCheckVariablesWithinPackingLimits(
variables.push_back(var);
}
VariablePacker packer;
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
return packer.CheckVariablesWithinPackingLimits(maxVectors, variables);
}
bool ShGetInterfaceBlockRegister(const ShHandle handle,
const char *interfaceBlockName,
const std::string &interfaceBlockName,
unsigned int *indexOut)
{
if (!handle || !interfaceBlockName || !indexOut)
{
return false;
}
ASSERT(indexOut);
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
TranslatorHLSL* translator = base->getAsTranslatorHLSL();
if (!translator)
{
return false;
}
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
ASSERT(translator);
if (!translator->hasInterfaceBlock(interfaceBlockName))
{
@ -559,20 +338,12 @@ bool ShGetInterfaceBlockRegister(const ShHandle handle,
}
bool ShGetUniformRegister(const ShHandle handle,
const char *uniformName,
const std::string &uniformName,
unsigned int *indexOut)
{
if (!handle || !uniformName || !indexOut)
{
return false;
}
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
TranslatorHLSL* translator = base->getAsTranslatorHLSL();
if (!translator)
{
return false;
}
ASSERT(indexOut);
TranslatorHLSL *translator = GetTranslatorHLSLFromHandle(handle);
ASSERT(translator);
if (!translator->hasUniform(uniformName))
{

View File

@ -31,6 +31,7 @@
//
#include <assert.h>
#include <set>
#include "common/angleutils.h"
#include "compiler/translator/InfoSink.h"
@ -299,19 +300,21 @@ class TSymbolTableLevel
tLevel level;
};
enum ESymbolLevel
{
COMMON_BUILTINS = 0,
ESSL1_BUILTINS = 1,
ESSL3_BUILTINS = 2,
LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
GLOBAL_LEVEL = 3
};
// Define ESymbolLevel as int rather than an enum since level can go
// above GLOBAL_LEVEL and cause atBuiltInLevel() to fail if the
// compiler optimizes the >= of the last element to ==.
typedef int ESymbolLevel;
const int COMMON_BUILTINS = 0;
const int ESSL1_BUILTINS = 1;
const int ESSL3_BUILTINS = 2;
const int LAST_BUILTIN_LEVEL = ESSL3_BUILTINS;
const int GLOBAL_LEVEL = 3;
class TSymbolTable
{
public:
TSymbolTable()
: mGlobalInvariant(false)
{
// The symbol table cannot be used until push() is called, but
// the lack of an initial call to push() can be used to detect
@ -408,6 +411,25 @@ class TSymbolTable
// for the specified TBasicType
TPrecision getDefaultPrecision(TBasicType type) const;
// This records invariant varyings declared through
// "invariant varying_name;".
void addInvariantVarying(const std::string &originalName)
{
mInvariantVaryings.insert(originalName);
}
// If this returns false, the varying could still be invariant
// if it is set as invariant during the varying variable
// declaration - this piece of information is stored in the
// variable's type, not here.
bool isVaryingInvariant(const std::string &originalName) const
{
return (mGlobalInvariant ||
mInvariantVaryings.count(originalName) > 0);
}
void setGlobalInvariant() { mGlobalInvariant = true; }
bool getGlobalInvariant() const { return mGlobalInvariant; }
static int nextUniqueId()
{
return ++uniqueIdCounter;
@ -423,6 +445,9 @@ class TSymbolTable
typedef TMap<TBasicType, TPrecision> PrecisionStackLevel;
std::vector< PrecisionStackLevel *> precisionStack;
std::set<std::string> mInvariantVaryings;
bool mGlobalInvariant;
static int uniqueIdCounter;
};

View File

@ -16,6 +16,8 @@ TranslatorESSL::TranslatorESSL(sh::GLenum type, ShShaderSpec spec)
void TranslatorESSL::translate(TIntermNode* root) {
TInfoSinkBase& sink = getInfoSink().obj;
writePragma();
// Write built-in extension behaviors.
writeExtensionBehavior();

View File

@ -9,18 +9,6 @@
#include "compiler/translator/OutputGLSL.h"
#include "compiler/translator/VersionGLSL.h"
static void writeVersion(sh::GLenum type, TIntermNode* root,
TInfoSinkBase& sink) {
TVersionGLSL versionGLSL(type);
root->traverse(&versionGLSL);
int version = versionGLSL.getVersion();
// We need to write version directive only if it is greater than 110.
// If there is no version directive in the shader, 110 is implied.
if (version > 110) {
sink << "#version " << version << "\n";
}
}
TranslatorGLSL::TranslatorGLSL(sh::GLenum type, ShShaderSpec spec)
: TCompiler(type, spec, SH_GLSL_OUTPUT) {
}
@ -29,7 +17,9 @@ void TranslatorGLSL::translate(TIntermNode* root) {
TInfoSinkBase& sink = getInfoSink().obj;
// Write GLSL version.
writeVersion(getShaderType(), root, sink);
writeVersion(root);
writePragma();
// Write extension behaviour as needed
writeExtensionBehavior();
@ -46,6 +36,20 @@ void TranslatorGLSL::translate(TIntermNode* root) {
root->traverse(&outputGLSL);
}
void TranslatorGLSL::writeVersion(TIntermNode *root)
{
TVersionGLSL versionGLSL(getShaderType(), getPragma());
root->traverse(&versionGLSL);
int version = versionGLSL.getVersion();
// We need to write version directive only if it is greater than 110.
// If there is no version directive in the shader, 110 is implied.
if (version > 110)
{
TInfoSinkBase& sink = getInfoSink().obj;
sink << "#version " << version << "\n";
}
}
void TranslatorGLSL::writeExtensionBehavior() {
TInfoSinkBase& sink = getInfoSink().obj;
const TExtensionBehavior& extensionBehavior = getExtensionBehavior();

View File

@ -9,14 +9,16 @@
#include "compiler/translator/Compiler.h"
class TranslatorGLSL : public TCompiler {
public:
class TranslatorGLSL : public TCompiler
{
public:
TranslatorGLSL(sh::GLenum type, ShShaderSpec spec);
protected:
virtual void translate(TIntermNode* root);
protected:
virtual void translate(TIntermNode *root);
private:
private:
void writeVersion(TIntermNode *root);
void writeExtensionBehavior();
};

View File

@ -94,6 +94,7 @@ const char *GetOperatorString(TOperator op)
case EOpLogicalXor: return "^^";
case EOpLogicalAnd: return "&&";
case EOpNegative: return "-";
case EOpPositive: return "+";
case EOpVectorLogicalNot: return "not";
case EOpLogicalNot: return "!";
case EOpPostIncrement: return "++";

View File

@ -5,6 +5,7 @@
//
#include "angle_gl.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/VariableInfo.h"
#include "compiler/translator/util.h"
#include "common/utilities.h"
@ -131,7 +132,8 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
std::vector<sh::Uniform> *uniforms,
std::vector<sh::Varying> *varyings,
std::vector<sh::InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction)
ShHashFunction64 hashFunction,
const TSymbolTable &symbolTable)
: mAttribs(attribs),
mOutputVariables(outputVariables),
mUniforms(uniforms),
@ -140,7 +142,10 @@ CollectVariables::CollectVariables(std::vector<sh::Attribute> *attribs,
mPointCoordAdded(false),
mFrontFacingAdded(false),
mFragCoordAdded(false),
mHashFunction(hashFunction)
mPositionAdded(false),
mPointSizeAdded(false),
mHashFunction(hashFunction),
mSymbolTable(symbolTable)
{
}
@ -200,12 +205,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mFragCoordAdded)
{
Varying info;
info.name = "gl_FragCoord";
info.mappedName = "gl_FragCoord";
const char kName[] = "gl_FragCoord";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = 0;
info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mFragCoordAdded = true;
}
@ -214,12 +221,14 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mFrontFacingAdded)
{
Varying info;
info.name = "gl_FrontFacing";
info.mappedName = "gl_FrontFacing";
const char kName[] = "gl_FrontFacing";
info.name = kName;
info.mappedName = kName;
info.type = GL_BOOL;
info.arraySize = 0;
info.precision = GL_NONE;
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mFrontFacingAdded = true;
}
@ -228,16 +237,50 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
if (!mPointCoordAdded)
{
Varying info;
info.name = "gl_PointCoord";
info.mappedName = "gl_PointCoord";
const char kName[] = "gl_PointCoord";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC2;
info.arraySize = 0;
info.precision = GL_MEDIUM_FLOAT; // Use mediump as it doesn't really matter.
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mPointCoordAdded = true;
}
return;
case EvqPosition:
if (!mPositionAdded)
{
Varying info;
const char kName[] = "gl_Position";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT_VEC4;
info.arraySize = 0;
info.precision = GL_HIGH_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mPositionAdded = true;
}
return;
case EvqPointSize:
if (!mPointSizeAdded)
{
Varying info;
const char kName[] = "gl_PointSize";
info.name = kName;
info.mappedName = kName;
info.type = GL_FLOAT;
info.arraySize = 0;
info.precision = GL_MEDIUM_FLOAT; // Defined by spec.
info.staticUse = true;
info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
mVaryings->push_back(info);
mPointSizeAdded = true;
}
return;
default:
break;
}
@ -251,8 +294,10 @@ void CollectVariables::visitSymbol(TIntermSymbol *symbol)
class NameHashingTraverser : public GetVariableTraverser
{
public:
NameHashingTraverser(ShHashFunction64 hashFunction)
: mHashFunction(hashFunction)
NameHashingTraverser(ShHashFunction64 hashFunction,
const TSymbolTable &symbolTable)
: GetVariableTraverser(symbolTable),
mHashFunction(hashFunction)
{}
private:
@ -312,7 +357,7 @@ void CollectVariables::visitVariable(const TIntermSymbol *variable,
const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
const TType &fieldType = *field.type();
GetVariableTraverser traverser;
GetVariableTraverser traverser(mSymbolTable);
traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
@ -325,7 +370,7 @@ template <typename VarT>
void CollectVariables::visitVariable(const TIntermSymbol *variable,
std::vector<VarT> *infoList) const
{
NameHashingTraverser traverser(mHashFunction);
NameHashingTraverser traverser(mHashFunction, mSymbolTable);
traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
}
@ -421,9 +466,8 @@ bool CollectVariables::visitBinary(Visit, TIntermBinary *binaryNode)
return true;
}
template <typename VarT>
void ExpandVariables(const std::vector<VarT> &compact,
std::vector<ShaderVariable> *expanded)
void ExpandUniforms(const std::vector<Uniform> &compact,
std::vector<ShaderVariable> *expanded)
{
for (size_t variableIndex = 0; variableIndex < compact.size(); variableIndex++)
{
@ -432,7 +476,4 @@ void ExpandVariables(const std::vector<VarT> &compact,
}
}
template void ExpandVariables(const std::vector<Uniform> &, std::vector<ShaderVariable> *);
template void ExpandVariables(const std::vector<Varying> &, std::vector<ShaderVariable> *);
}

View File

@ -11,6 +11,8 @@
#include "compiler/translator/IntermNode.h"
class TSymbolTable;
namespace sh
{
@ -23,7 +25,8 @@ class CollectVariables : public TIntermTraverser
std::vector<Uniform> *uniforms,
std::vector<Varying> *varyings,
std::vector<InterfaceBlock> *interfaceBlocks,
ShHashFunction64 hashFunction);
ShHashFunction64 hashFunction,
const TSymbolTable &symbolTable);
virtual void visitSymbol(TIntermSymbol *symbol);
virtual bool visitAggregate(Visit, TIntermAggregate *node);
@ -48,13 +51,17 @@ class CollectVariables : public TIntermTraverser
bool mFrontFacingAdded;
bool mFragCoordAdded;
bool mPositionAdded;
bool mPointSizeAdded;
ShHashFunction64 mHashFunction;
const TSymbolTable &mSymbolTable;
};
// Expand struct variables to flattened lists of split variables
template <typename VarT>
void ExpandVariables(const std::vector<VarT> &compact,
std::vector<ShaderVariable> *expanded);
// Expand struct uniforms to flattened lists of split variables
void ExpandUniforms(const std::vector<Uniform> &compact,
std::vector<ShaderVariable> *expanded);
}

View File

@ -26,18 +26,12 @@ static const int GLSL_VERSION_120 = 120;
// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
// are built-in types, entire structures or arrays... are all l-values."
//
// TODO(alokp): The following two cases of invariant decalaration get lost
// during parsing - they do not get carried over to the intermediate tree.
// Handle these cases:
// 1. When a pragma is used to force all output variables to be invariant:
// - #pragma STDGL invariant(all)
// 2. When a previously decalared or built-in variable is marked invariant:
// - invariant gl_Position;
// - varying vec3 color; invariant color;
//
TVersionGLSL::TVersionGLSL(sh::GLenum type)
: mVersion(GLSL_VERSION_110)
TVersionGLSL::TVersionGLSL(sh::GLenum type, const TPragma &pragma)
{
if (pragma.stdgl.invariantAll)
mVersion = GLSL_VERSION_120;
else
mVersion = GLSL_VERSION_110;
}
void TVersionGLSL::visitSymbol(TIntermSymbol *node)

View File

@ -9,6 +9,8 @@
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/Pragma.h"
// Traverses the intermediate tree to return the minimum GLSL version
// required to legally access all built-in features used in the shader.
// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
@ -27,7 +29,7 @@
class TVersionGLSL : public TIntermTraverser
{
public:
TVersionGLSL(sh::GLenum type);
TVersionGLSL(sh::GLenum type, const TPragma &pragma);
// Returns 120 if the following is used the shader:
// - "invariant",

View File

@ -354,6 +354,15 @@ function_call
// Treat it like a built-in unary operator.
//
$$ = context->intermediate.addUnaryMath(op, $1.intermNode, @1);
const TType& returnType = fnCandidate->getReturnType();
if (returnType.getBasicType() == EbtBool) {
// Bool types should not have precision, so we'll override any precision
// that might have been set by addUnaryMath.
$$->setType(returnType);
} else {
// addUnaryMath has set the precision of the node based on the operand.
$$->setTypePreservePrecision(returnType);
}
if ($$ == 0) {
std::stringstream extraInfoStream;
extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString();
@ -362,20 +371,29 @@ function_call
YYERROR;
}
} else {
$$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, op, @1);
aggregate->setType(fnCandidate->getReturnType());
aggregate->setPrecisionFromChildren();
$$ = aggregate;
}
} else {
// This is a real function call
$$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
$$->setType(fnCandidate->getReturnType());
TIntermAggregate *aggregate = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
aggregate->setType(fnCandidate->getReturnType());
// this is how we know whether the given function is a builtIn function or a user defined function
// if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
// if builtIn == true, it's definitely a builtIn function with EOpNull
if (!builtIn)
$$->getAsAggregate()->setUserDefined();
$$->getAsAggregate()->setName(fnCandidate->getMangledName());
aggregate->setUserDefined();
aggregate->setName(fnCandidate->getMangledName());
// This needs to happen after the name is set
if (builtIn)
aggregate->setBuiltInFunctionPrecision();
$$ = aggregate;
TQualifier qual;
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
@ -388,7 +406,6 @@ function_call
}
}
}
$$->setType(fnCandidate->getReturnType());
} else {
// error message was put out by PaFindFunction()
// Put on a dummy node for error recovery
@ -500,6 +517,7 @@ unary_expression
const char* errorOp = "";
switch($1.op) {
case EOpNegative: errorOp = "-"; break;
case EOpPositive: errorOp = "+"; break;
case EOpLogicalNot: errorOp = "!"; break;
default: break;
}
@ -514,7 +532,7 @@ unary_expression
// Grammar Note: No traditional style type casts.
unary_operator
: PLUS { $$.op = EOpNull; }
: PLUS { $$.op = EOpPositive; }
| DASH { $$.op = EOpNegative; }
| BANG { $$.op = EOpLogicalNot; }
;

View File

@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 2.7.1. */
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
/* Bison implementation for Yacc-like parsers in C
@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
#define YYBISON_VERSION "2.7.1"
#define YYBISON_VERSION "2.7.12-4996"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@ -796,31 +796,31 @@ static const yytype_int16 yyrhs[] =
static const yytype_uint16 yyrline[] =
{
0, 206, 206, 207, 210, 234, 237, 242, 247, 252,
257, 263, 266, 269, 272, 275, 285, 298, 306, 406,
409, 417, 420, 426, 430, 437, 443, 452, 460, 463,
473, 476, 486, 496, 517, 518, 519, 524, 525, 533,
544, 545, 553, 564, 568, 569, 579, 589, 599, 612,
613, 623, 636, 640, 644, 648, 649, 662, 663, 676,
677, 690, 691, 708, 709, 722, 723, 724, 725, 726,
730, 733, 744, 752, 760, 787, 793, 804, 808, 812,
816, 823, 879, 882, 889, 897, 918, 939, 949, 977,
982, 992, 997, 1007, 1010, 1013, 1016, 1022, 1029, 1032,
1036, 1040, 1044, 1051, 1055, 1059, 1066, 1070, 1074, 1081,
1090, 1096, 1099, 1105, 1111, 1118, 1127, 1136, 1144, 1147,
1154, 1158, 1165, 1168, 1172, 1176, 1185, 1194, 1202, 1212,
1224, 1227, 1230, 1236, 1243, 1246, 1252, 1255, 1258, 1264,
1267, 1282, 1286, 1290, 1294, 1298, 1302, 1307, 1312, 1317,
1322, 1327, 1332, 1337, 1342, 1347, 1352, 1357, 1362, 1367,
1372, 1377, 1382, 1387, 1392, 1397, 1402, 1407, 1411, 1415,
1419, 1423, 1427, 1431, 1435, 1439, 1443, 1447, 1451, 1455,
1459, 1463, 1467, 1475, 1483, 1487, 1500, 1500, 1503, 1503,
1509, 1512, 1528, 1531, 1540, 1544, 1550, 1557, 1572, 1576,
1580, 1581, 1587, 1588, 1589, 1590, 1591, 1595, 1596, 1596,
1596, 1606, 1607, 1611, 1611, 1612, 1612, 1617, 1620, 1630,
1633, 1639, 1640, 1644, 1652, 1656, 1666, 1671, 1688, 1688,
1693, 1693, 1700, 1700, 1708, 1711, 1717, 1720, 1726, 1730,
1737, 1744, 1751, 1758, 1769, 1778, 1782, 1789, 1792, 1798,
1798
257, 263, 266, 269, 272, 275, 285, 298, 306, 423,
426, 434, 437, 443, 447, 454, 460, 469, 477, 480,
490, 493, 503, 513, 535, 536, 537, 542, 543, 551,
562, 563, 571, 582, 586, 587, 597, 607, 617, 630,
631, 641, 654, 658, 662, 666, 667, 680, 681, 694,
695, 708, 709, 726, 727, 740, 741, 742, 743, 744,
748, 751, 762, 770, 778, 805, 811, 822, 826, 830,
834, 841, 897, 900, 907, 915, 936, 957, 967, 995,
1000, 1010, 1015, 1025, 1028, 1031, 1034, 1040, 1047, 1050,
1054, 1058, 1062, 1069, 1073, 1077, 1084, 1088, 1092, 1099,
1108, 1114, 1117, 1123, 1129, 1136, 1145, 1154, 1162, 1165,
1172, 1176, 1183, 1186, 1190, 1194, 1203, 1212, 1220, 1230,
1242, 1245, 1248, 1254, 1261, 1264, 1270, 1273, 1276, 1282,
1285, 1300, 1304, 1308, 1312, 1316, 1320, 1325, 1330, 1335,
1340, 1345, 1350, 1355, 1360, 1365, 1370, 1375, 1380, 1385,
1390, 1395, 1400, 1405, 1410, 1415, 1420, 1425, 1429, 1433,
1437, 1441, 1445, 1449, 1453, 1457, 1461, 1465, 1469, 1473,
1477, 1481, 1485, 1493, 1501, 1505, 1518, 1518, 1521, 1521,
1527, 1530, 1546, 1549, 1558, 1562, 1568, 1575, 1590, 1594,
1598, 1599, 1605, 1606, 1607, 1608, 1609, 1613, 1614, 1614,
1614, 1624, 1625, 1629, 1629, 1630, 1630, 1635, 1638, 1648,
1651, 1657, 1658, 1662, 1670, 1674, 1684, 1689, 1706, 1706,
1711, 1711, 1718, 1718, 1726, 1729, 1735, 1738, 1744, 1748,
1755, 1762, 1769, 1776, 1787, 1796, 1800, 1807, 1810, 1816,
1816
};
#endif
@ -2736,6 +2736,15 @@ yyreduce:
// Treat it like a built-in unary operator.
//
(yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, (yylsp[(1) - (1)]));
const TType& returnType = fnCandidate->getReturnType();
if (returnType.getBasicType() == EbtBool) {
// Bool types should not have precision, so we'll override any precision
// that might have been set by addUnaryMath.
(yyval.interm.intermTypedNode)->setType(returnType);
} else {
// addUnaryMath has set the precision of the node based on the operand.
(yyval.interm.intermTypedNode)->setTypePreservePrecision(returnType);
}
if ((yyval.interm.intermTypedNode) == 0) {
std::stringstream extraInfoStream;
extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString();
@ -2744,20 +2753,29 @@ yyreduce:
YYERROR;
}
} else {
(yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yylsp[(1) - (1)]));
TIntermAggregate *aggregate = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yylsp[(1) - (1)]));
aggregate->setType(fnCandidate->getReturnType());
aggregate->setPrecisionFromChildren();
(yyval.interm.intermTypedNode) = aggregate;
}
} else {
// This is a real function call
(yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yylsp[(1) - (1)]));
(yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
TIntermAggregate *aggregate = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yylsp[(1) - (1)]));
aggregate->setType(fnCandidate->getReturnType());
// this is how we know whether the given function is a builtIn function or a user defined function
// if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
// if builtIn == true, it's definitely a builtIn function with EOpNull
if (!builtIn)
(yyval.interm.intermTypedNode)->getAsAggregate()->setUserDefined();
(yyval.interm.intermTypedNode)->getAsAggregate()->setName(fnCandidate->getMangledName());
aggregate->setUserDefined();
aggregate->setName(fnCandidate->getMangledName());
// This needs to happen after the name is set
if (builtIn)
aggregate->setBuiltInFunctionPrecision();
(yyval.interm.intermTypedNode) = aggregate;
TQualifier qual;
for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
@ -2770,7 +2788,6 @@ yyreduce:
}
}
}
(yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
} else {
// error message was put out by PaFindFunction()
// Put on a dummy node for error recovery
@ -2919,6 +2936,7 @@ yyreduce:
const char* errorOp = "";
switch((yyvsp[(1) - (2)].interm).op) {
case EOpNegative: errorOp = "-"; break;
case EOpPositive: errorOp = "+"; break;
case EOpLogicalNot: errorOp = "!"; break;
default: break;
}
@ -2933,7 +2951,7 @@ yyreduce:
case 34:
{ (yyval.interm).op = EOpNull; }
{ (yyval.interm).op = EOpPositive; }
break;
case 35:

View File

@ -1,4 +1,4 @@
/* A Bison parser, made by GNU Bison 2.7.1. */
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
/* Bison interface for Yacc-like parsers in C

View File

@ -62,7 +62,9 @@ TString TType::getCompleteString() const
TStringStream stream;
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
stream << getQualifierString() << " " << getPrecisionString() << " ";
stream << getQualifierString() << " ";
if (precision != EbpUndefined)
stream << getPrecisionString() << " ";
if (array)
stream << "array[" << getArraySize() << "] of ";
if (isMatrix())
@ -221,6 +223,7 @@ bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary *node)
switch (node->getOp())
{
case EOpNegative: out << "Negate value"; break;
case EOpPositive: out << "Positive sign"; break;
case EOpVectorLogicalNot:
case EOpLogicalNot: out << "Negate conditional"; break;

View File

@ -9,6 +9,7 @@
#include <limits>
#include "compiler/preprocessor/numeric_lex.h"
#include "compiler/translator/SymbolTable.h"
#include "common/utilities.h"
bool atof_clamp(const char *str, float *value)
@ -281,8 +282,47 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
}
}
GetVariableTraverser::GetVariableTraverser(const TSymbolTable &symbolTable)
: mSymbolTable(symbolTable)
{
}
template void GetVariableTraverser::setTypeSpecificInfo(
const TType &type, const TString& name, InterfaceBlockField *variable);
template void GetVariableTraverser::setTypeSpecificInfo(
const TType &type, const TString& name, ShaderVariable *variable);
template void GetVariableTraverser::setTypeSpecificInfo(
const TType &type, const TString& name, Uniform *variable);
template<>
void GetVariableTraverser::setTypeSpecificInfo(
const TType &type, const TString& name, Varying *variable)
{
ASSERT(variable);
switch (type.getQualifier())
{
case EvqInvariantVaryingIn:
case EvqInvariantVaryingOut:
variable->isInvariant = true;
break;
case EvqVaryingIn:
case EvqVaryingOut:
if (mSymbolTable.isVaryingInvariant(std::string(name.c_str())))
{
variable->isInvariant = true;
}
break;
default:
break;
}
variable->interpolation = GetInterpolationType(type.getQualifier());
}
template <typename VarT>
void GetVariableTraverser::traverse(const TType &type, const TString &name, std::vector<VarT> *output)
void GetVariableTraverser::traverse(const TType &type,
const TString &name,
std::vector<VarT> *output)
{
const TStructure *structure = type.getStruct();
@ -309,15 +349,16 @@ void GetVariableTraverser::traverse(const TType &type, const TString &name, std:
traverse(*field->type(), field->name(), &variable.fields);
}
}
setTypeSpecificInfo(type, name, &variable);
visitVariable(&variable);
ASSERT(output);
output->push_back(variable);
}
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<ShaderVariable> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Uniform> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<Varying> *);
template void GetVariableTraverser::traverse(const TType &, const TString &, std::vector<InterfaceBlockField> *);
}

View File

@ -24,6 +24,8 @@ extern bool atof_clamp(const char *str, float *value);
// Return false if overflow happens.
extern bool atoi_clamp(const char *str, int *value);
class TSymbolTable;
namespace sh
{
@ -38,7 +40,7 @@ TString ArrayString(const TType &type);
class GetVariableTraverser
{
public:
GetVariableTraverser() {}
GetVariableTraverser(const TSymbolTable &symbolTable);
template <typename VarT>
void traverse(const TType &type, const TString &name, std::vector<VarT> *output);
@ -48,6 +50,14 @@ class GetVariableTraverser
virtual void visitVariable(ShaderVariable *newVar) {}
private:
// Helper function called by traverse() to fill specific fields
// for attributes/varyings/uniforms.
template <typename VarT>
void setTypeSpecificInfo(
const TType &type, const TString &name, VarT *variable) {}
const TSymbolTable &mSymbolTable;
DISALLOW_COPY_AND_ASSIGN(GetVariableTraverser);
};

View File

@ -5,8 +5,6 @@
{
'variables':
{
'angle_enable_d3d9%': 1,
'angle_enable_d3d11%': 1,
# This file list is shared with the GN build.
'angle_libegl_sources':
[
@ -40,7 +38,6 @@
'common/utilities.cpp',
'common/utilities.h',
'common/version.h',
'common/win32/NativeWindow.cpp',
'libEGL/Config.cpp',
'libEGL/Config.h',
'libEGL/Display.cpp',
@ -54,6 +51,17 @@
'libEGL/main.h',
'libEGL/resource.h',
],
'angle_libegl_win32_sources':
[
'common/win32/NativeWindow.cpp',
],
'angle_libegl_winrt_sources':
[
'common/winrt/CoreWindowNativeWindow.cpp',
'common/winrt/CoreWindowNativeWindow.h',
'common/winrt/IInspectableNativeWindow.cpp',
'common/winrt/IInspectableNativeWindow.h',
],
},
# Everything below this is duplicated in the GN build. If you change
# anything also change angle/BUILD.gn
@ -99,25 +107,71 @@
'ANGLE_ENABLE_D3D11',
],
}],
['angle_build_winrt==0',
{
'sources':
[
'<@(angle_libegl_win32_sources)',
],
}],
['angle_build_winrt==1',
{
'defines':
[
'NTDDI_VERSION=NTDDI_WINBLUE',
],
'sources':
[
'<@(angle_libegl_winrt_sources)',
],
'msvs_enable_winrt' : '1',
'msvs_requires_importlibrary' : '1',
'msvs_settings':
{
'VCLinkerTool':
{
'EnableCOMDATFolding': '1',
'OptimizeReferences': '1',
}
},
}],
['angle_build_winphone==1',
{
'msvs_enable_winphone' : '1',
}],
],
'includes': [ '../build/common_defines.gypi', ],
'msvs_settings':
{
'VCLinkerTool':
{
'AdditionalDependencies':
'conditions':
[
'd3d9.lib',
['angle_build_winrt==0',
{
'AdditionalDependencies':
[
'd3d9.lib',
],
}],
['angle_build_winrt==1',
{
'AdditionalDependencies':
[
'd3d11.lib',
],
}],
],
},
},
'configurations':
{
'Debug':
'Debug_Base':
{
'defines':
[
'ANGLE_ENABLE_PERF',
'ANGLE_ENABLE_DEBUG_ANNOTATIONS',
],
},
},

Some files were not shown because too many files have changed in this diff Show More