From caf218fa3e254cad6e8de4d3bd8d699623f1c14a Mon Sep 17 00:00:00 2001 From: Ethan Tseng Date: Thu, 17 Dec 2015 12:07:37 +0800 Subject: [PATCH 001/139] Bug 1030936 - [CSP] remove fast-path for certified apps once the C++ backend is activated. r=ckerschb --- dom/security/nsCSPService.cpp | 56 ----------------------------------- 1 file changed, 56 deletions(-) diff --git a/dom/security/nsCSPService.cpp b/dom/security/nsCSPService.cpp index fcc84a090ebc..ecb67f809309 100644 --- a/dom/security/nsCSPService.cpp +++ b/dom/security/nsCSPService.cpp @@ -139,62 +139,6 @@ CSPService::ShouldLoad(uint32_t aContentType, return NS_OK; } - // ----- THIS IS A TEMPORARY FAST PATH FOR CERTIFIED APPS. ----- - // ----- PLEASE REMOVE ONCE bug 925004 LANDS. ----- - - // Cache the app status for this origin. - uint16_t status = nsIPrincipal::APP_STATUS_NOT_INSTALLED; - nsAutoCString sourceOrigin; - if (aRequestPrincipal && aRequestOrigin) { - aRequestOrigin->GetPrePath(sourceOrigin); - if (!mAppStatusCache.Get(sourceOrigin, &status)) { - aRequestPrincipal->GetAppStatus(&status); - mAppStatusCache.Put(sourceOrigin, status); - } - } - - if (status == nsIPrincipal::APP_STATUS_CERTIFIED) { - // The CSP for certified apps is : - // "default-src * data: blob:; script-src 'self'; object-src 'none'; style-src 'self' app://theme.gaiamobile.org:*" - // That means we can optimize for this case by: - // - loading same origin scripts and stylesheets, and stylesheets from the - // theme url space. - // - never loading objects. - // - accepting everything else. - - switch (aContentType) { - case nsIContentPolicy::TYPE_SCRIPT: - case nsIContentPolicy::TYPE_STYLESHEET: - { - // Whitelist the theme resources. - auto themeOrigin = Preferences::GetCString("b2g.theme.origin"); - nsAutoCString contentOrigin; - aContentLocation->GetPrePath(contentOrigin); - - if (!(sourceOrigin.Equals(contentOrigin) || - (themeOrigin && themeOrigin.Equals(contentOrigin)))) { - *aDecision = nsIContentPolicy::REJECT_SERVER; - } - } - break; - - case nsIContentPolicy::TYPE_OBJECT: - *aDecision = nsIContentPolicy::REJECT_SERVER; - break; - - default: - *aDecision = nsIContentPolicy::ACCEPT; - } - - // Only cache and return if we are successful. If not, we want the error - // to be reported, and thus fallback to the slow path. - if (*aDecision == nsIContentPolicy::ACCEPT) { - return NS_OK; - } - } - - // ----- END OF TEMPORARY FAST PATH FOR CERTIFIED APPS. ----- - // query the principal of the document; if no document is passed, then // fall back to using the requestPrincipal (e.g. service workers do not // pass a document). From 86899e610d5345d941a84161c007d769aede7344 Mon Sep 17 00:00:00 2001 From: Aidin Gharibnavaz Date: Tue, 15 Dec 2015 21:05:05 +0330 Subject: [PATCH 002/139] Bug 1224892 - Caching `oscpu' and `buildID' like other attributes related to User Agent. r=smaug --HG-- extra : transplant_source : %7E%FBbs56%E92%40%14%23%D2dY%A1%10%FD%0CV%06 --- dom/webidl/Navigator.webidl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index b98e2080eba7..c4dc1dad6983 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -190,7 +190,7 @@ Navigator implements NavigatorMobileId; // nsIDOMNavigator partial interface Navigator { - [Throws] + [Throws, Constant, Cached] readonly attribute DOMString oscpu; // WebKit/Blink support this; Trident/Presto do not. readonly attribute DOMString vendor; @@ -200,7 +200,7 @@ partial interface Navigator { readonly attribute DOMString productSub; // WebKit/Blink/Trident/Presto support this. readonly attribute boolean cookieEnabled; - [Throws] + [Throws, Constant, Cached] readonly attribute DOMString buildID; [Throws, CheckAnyPermissions="power", UnsafeInPrerendering] readonly attribute MozPowerManager mozPower; From 5a7f90304663ac57afee1b29c7146afe52044018 Mon Sep 17 00:00:00 2001 From: Honza Bambas Date: Fri, 4 Dec 2015 09:55:00 +0100 Subject: [PATCH 003/139] Bug 1229235 - Make RedirectChannelRegistrar thread-safe. r=jduell --- netwerk/base/RedirectChannelRegistrar.cpp | 11 +++++++++++ netwerk/base/RedirectChannelRegistrar.h | 1 + 2 files changed, 12 insertions(+) diff --git a/netwerk/base/RedirectChannelRegistrar.cpp b/netwerk/base/RedirectChannelRegistrar.cpp index c33b6ddf4639..17e26603a915 100644 --- a/netwerk/base/RedirectChannelRegistrar.cpp +++ b/netwerk/base/RedirectChannelRegistrar.cpp @@ -13,6 +13,7 @@ RedirectChannelRegistrar::RedirectChannelRegistrar() : mRealChannels(32) , mParentChannels(32) , mId(1) + , mLock("RedirectChannelRegistrar") { } @@ -20,6 +21,8 @@ NS_IMETHODIMP RedirectChannelRegistrar::RegisterChannel(nsIChannel *channel, uint32_t *_retval) { + MutexAutoLock lock(mLock); + mRealChannels.Put(mId, channel); *_retval = mId; @@ -36,6 +39,8 @@ NS_IMETHODIMP RedirectChannelRegistrar::GetRegisteredChannel(uint32_t id, nsIChannel **_retval) { + MutexAutoLock lock(mLock); + if (!mRealChannels.Get(id, _retval)) return NS_ERROR_NOT_AVAILABLE; @@ -47,6 +52,8 @@ RedirectChannelRegistrar::LinkChannels(uint32_t id, nsIParentChannel *channel, nsIChannel** _retval) { + MutexAutoLock lock(mLock); + if (!mRealChannels.Get(id, _retval)) return NS_ERROR_NOT_AVAILABLE; @@ -58,6 +65,8 @@ NS_IMETHODIMP RedirectChannelRegistrar::GetParentChannel(uint32_t id, nsIParentChannel **_retval) { + MutexAutoLock lock(mLock); + if (!mParentChannels.Get(id, _retval)) return NS_ERROR_NOT_AVAILABLE; @@ -67,6 +76,8 @@ RedirectChannelRegistrar::GetParentChannel(uint32_t id, NS_IMETHODIMP RedirectChannelRegistrar::DeregisterChannels(uint32_t id) { + MutexAutoLock lock(mLock); + mRealChannels.Remove(id); mParentChannels.Remove(id); return NS_OK; diff --git a/netwerk/base/RedirectChannelRegistrar.h b/netwerk/base/RedirectChannelRegistrar.h index 333389d67124..fead16990c45 100644 --- a/netwerk/base/RedirectChannelRegistrar.h +++ b/netwerk/base/RedirectChannelRegistrar.h @@ -34,6 +34,7 @@ protected: ChannelHashtable mRealChannels; ParentChannelHashtable mParentChannels; uint32_t mId; + Mutex mLock; }; } // namespace net From 59274cab048c136a384773fb8418c35d6834b700 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Thu, 3 Dec 2015 12:28:22 +0000 Subject: [PATCH 004/139] Bug 1231109 - Drop FreeBSD checks for unsupported versions. r=jld r=jesup --HG-- extra : transplant_source : P%FC%E3%29%07%05%D4%8DA%A7%89%90%26%B4%D5%E2%60%89%0C%B0 --- ipc/chromium/src/base/platform_thread_posix.cc | 11 +---------- media/mtransport/third_party/nICEr/src/util/mbslen.c | 9 +-------- media/webrtc/trunk/webrtc/base/thread_checker_impl.cc | 10 +--------- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/ipc/chromium/src/base/platform_thread_posix.cc b/ipc/chromium/src/base/platform_thread_posix.cc index eb13b980ef83..be250691a3c3 100644 --- a/ipc/chromium/src/base/platform_thread_posix.cc +++ b/ipc/chromium/src/base/platform_thread_posix.cc @@ -14,9 +14,6 @@ #elif defined(OS_LINUX) #include #include -#elif defined(OS_FREEBSD) && !defined(__GLIBC__) -#include -#include #endif #if !defined(OS_MACOSX) @@ -61,13 +58,7 @@ PlatformThreadId PlatformThread::CurrentId() { #elif defined(OS_DRAGONFLY) return lwp_gettid(); #elif defined(OS_FREEBSD) -# if __FreeBSD_version > 900030 - return pthread_getthreadid_np(); -# else - long lwpid; - thr_self(&lwpid); - return lwpid; -# endif + return pthread_getthreadid_np(); #endif } diff --git a/media/mtransport/third_party/nICEr/src/util/mbslen.c b/media/mtransport/third_party/nICEr/src/util/mbslen.c index 14a45fbb6ea7..308acebc75de 100644 --- a/media/mtransport/third_party/nICEr/src/util/mbslen.c +++ b/media/mtransport/third_party/nICEr/src/util/mbslen.c @@ -43,17 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#if defined(DARWIN) +#if defined(DARWIN) || defined(__FreeBSD__) #define HAVE_XLOCALE #endif -#ifdef __FreeBSD__ -#include -# if __FreeBSD_version > 900505 -# define HAVE_XLOCALE -# endif -#endif - #ifdef HAVE_XLOCALE #include #endif /* HAVE_XLOCALE */ diff --git a/media/webrtc/trunk/webrtc/base/thread_checker_impl.cc b/media/webrtc/trunk/webrtc/base/thread_checker_impl.cc index 95638ea49cfc..7098a51cf6a5 100644 --- a/media/webrtc/trunk/webrtc/base/thread_checker_impl.cc +++ b/media/webrtc/trunk/webrtc/base/thread_checker_impl.cc @@ -21,8 +21,6 @@ #if defined(__NetBSD__) #include #elif defined(__FreeBSD__) -#include -#include #include #endif @@ -46,13 +44,7 @@ PlatformThreadId CurrentThreadId() { #elif defined(__OpenBSD__) ret = reinterpret_cast (pthread_self()); #elif defined(__FreeBSD__) -#if __FreeBSD_version > 900030 - ret = pthread_getthreadid_np(); -#else - long lwpid; - thr_self(&lwpid); - ret = lwpid; -#endif + ret = pthread_getthreadid_np(); #else // Default implementation for nacl and solaris. ret = reinterpret_cast(pthread_self()); From b9ba40cc6b17162b85bf3a761d8434e2c822515f Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Thu, 3 Dec 2015 12:32:52 +0000 Subject: [PATCH 005/139] Bug 1231117 - Use xlocale on DragonFly as well. r=jesup --HG-- extra : transplant_source : %7F%8D%B37%8B%0B%22%99%8F%A5%81%ECS%C5%ED%24%94%21%1F%8B --- media/mtransport/third_party/nICEr/src/util/mbslen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/mtransport/third_party/nICEr/src/util/mbslen.c b/media/mtransport/third_party/nICEr/src/util/mbslen.c index 308acebc75de..3645c95cfdbf 100644 --- a/media/mtransport/third_party/nICEr/src/util/mbslen.c +++ b/media/mtransport/third_party/nICEr/src/util/mbslen.c @@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#if defined(DARWIN) || defined(__FreeBSD__) +#if defined(DARWIN) || defined(__DragonFly__) || defined(__FreeBSD__) #define HAVE_XLOCALE #endif From fa002c319a0990dbcc48763f28d3c3495c60a7fe Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Thu, 3 Dec 2015 12:55:41 +0000 Subject: [PATCH 006/139] Bug 1231123 - Simplify LaunchApp on BSDs by dropping fork/exec version. r=jld --HG-- extra : transplant_source : 2%08%3De%92%DE%D7%A9%AF%F7%A1%13yU%A2Y%3DiAn --- ipc/chromium/src/base/process_util_bsd.cc | 159 +--------------------- 1 file changed, 4 insertions(+), 155 deletions(-) diff --git a/ipc/chromium/src/base/process_util_bsd.cc b/ipc/chromium/src/base/process_util_bsd.cc index e4d233625d64..e10149b1f05e 100644 --- a/ipc/chromium/src/base/process_util_bsd.cc +++ b/ipc/chromium/src/base/process_util_bsd.cc @@ -2,70 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// derived from process_util_linux.cc and process_util_mac.cc +// derived from process_util_mac.cc #include "base/process_util.h" -#include - #include -#include +#include +#include #include #include "base/eintr_wrapper.h" -#include "base/file_util.h" -#include "base/logging.h" -#include "base/string_tokenizer.h" -#include "base/string_util.h" -#include "mozilla/UniquePtr.h" -#if defined(_POSIX_SPAWN) && _POSIX_SPAWN > 0 -#define HAVE_POSIX_SPAWN 1 -#endif - -/* - * On platforms that are not gonk based, we fall back to an arbitrary - * UID. This is generally the UID for user `nobody', albeit it is not - * always the case. - */ - -#if defined(OS_NETBSD) || defined(OS_OPENBSD) -# define CHILD_UNPRIVILEGED_UID 32767 -# define CHILD_UNPRIVILEGED_GID 32767 -#else -# define CHILD_UNPRIVILEGED_UID 65534 -# define CHILD_UNPRIVILEGED_GID 65534 -#endif - -#ifndef __dso_public -# ifdef __exported -# define __dso_public __exported -# else -# define __dso_public __attribute__((__visibility__("default"))) -# endif -#endif - -#ifdef HAVE_POSIX_SPAWN -#include -extern "C" char **environ __dso_public; -#endif - -namespace { - -enum ParsingState { - KEY_NAME, - KEY_VALUE -}; - -static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG"); - -} // namespace +extern "C" char **environ __attribute__((__visibility__("default"))); namespace base { -#ifdef HAVE_POSIX_SPAWN - void FreeEnvVarsArray(char* array[], int length) { for (int i = 0; i < length; i++) { @@ -201,107 +153,4 @@ void SetCurrentProcessPrivileges(ChildPrivileges privs) { } -#else // no posix_spawn, use fork/exec - -bool LaunchApp(const std::vector& argv, - const file_handle_mapping_vector& fds_to_remap, - bool wait, ProcessHandle* process_handle) { - return LaunchApp(argv, fds_to_remap, environment_map(), - wait, process_handle); -} - -bool LaunchApp(const std::vector& argv, - const file_handle_mapping_vector& fds_to_remap, - const environment_map& env_vars_to_set, - bool wait, ProcessHandle* process_handle, - ProcessArchitecture arch) { - return LaunchApp(argv, fds_to_remap, env_vars_to_set, - PRIVILEGES_INHERIT, - wait, process_handle); -} - -bool LaunchApp(const std::vector& argv, - const file_handle_mapping_vector& fds_to_remap, - const environment_map& env_vars_to_set, - ChildPrivileges privs, - bool wait, ProcessHandle* process_handle, - ProcessArchitecture arch) { - mozilla::UniquePtr argv_cstr(new char*[argv.size() + 1]); - // Illegal to allocate memory after fork and before execvp - InjectiveMultimap fd_shuffle1, fd_shuffle2; - fd_shuffle1.reserve(fds_to_remap.size()); - fd_shuffle2.reserve(fds_to_remap.size()); - - pid_t pid = fork(); - if (pid < 0) - return false; - - if (pid == 0) { - for (file_handle_mapping_vector::const_iterator - it = fds_to_remap.begin(); it != fds_to_remap.end(); ++it) { - fd_shuffle1.push_back(InjectionArc(it->first, it->second, false)); - fd_shuffle2.push_back(InjectionArc(it->first, it->second, false)); - } - - if (!ShuffleFileDescriptors(&fd_shuffle1)) - _exit(127); - - CloseSuperfluousFds(fd_shuffle2); - - for (size_t i = 0; i < argv.size(); i++) - argv_cstr[i] = const_cast(argv[i].c_str()); - argv_cstr[argv.size()] = NULL; - - SetCurrentProcessPrivileges(privs); - - for (environment_map::const_iterator it = env_vars_to_set.begin(); - it != env_vars_to_set.end(); ++it) { - if (setenv(it->first.c_str(), it->second.c_str(), 1/*overwrite*/)) - _exit(127); - } - execv(argv_cstr[0], argv_cstr.get()); - // if we get here, we're in serious trouble and should complain loudly - DLOG(ERROR) << "FAILED TO exec() CHILD PROCESS, path: " << argv_cstr[0]; - _exit(127); - } else { - gProcessLog.print("==> process %d launched child process %d\n", - GetCurrentProcId(), pid); - if (wait) - HANDLE_EINTR(waitpid(pid, 0, 0)); - - if (process_handle) - *process_handle = pid; - } - - return true; -} - -bool LaunchApp(const CommandLine& cl, - bool wait, bool start_hidden, - ProcessHandle* process_handle) { - file_handle_mapping_vector no_files; - return LaunchApp(cl.argv(), no_files, wait, process_handle); -} - -void SetCurrentProcessPrivileges(ChildPrivileges privs) { - if (privs == PRIVILEGES_INHERIT) { - return; - } - - gid_t gid = CHILD_UNPRIVILEGED_GID; - uid_t uid = CHILD_UNPRIVILEGED_UID; - if (setgid(gid) != 0) { - DLOG(ERROR) << "FAILED TO setgid() CHILD PROCESS"; - _exit(127); - } - if (setuid(uid) != 0) { - DLOG(ERROR) << "FAILED TO setuid() CHILD PROCESS"; - _exit(127); - } - if (chdir("/") != 0) - gProcessLog.print("==> could not chdir()\n"); -} - -#endif - } // namespace base From 514b142f92e2d8c4aee1d2bcc61d511c435b23bb Mon Sep 17 00:00:00 2001 From: Alfredo Yang Date: Wed, 16 Dec 2015 16:38:00 +0100 Subject: [PATCH 007/139] Bug 1231353 - Release buffers at IDLE state. r=sotaro --- dom/media/platforms/omx/OmxDataDecoder.cpp | 41 ++++++++++++++-------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/dom/media/platforms/omx/OmxDataDecoder.cpp b/dom/media/platforms/omx/OmxDataDecoder.cpp index 2a9bee7c0557..421934a9fe76 100644 --- a/dom/media/platforms/omx/OmxDataDecoder.cpp +++ b/dom/media/platforms/omx/OmxDataDecoder.cpp @@ -226,23 +226,12 @@ OmxDataDecoder::DoAsyncShutdown() mWatchManager.Unwatch(mOmxState, &OmxDataDecoder::OmxStateRunner); mWatchManager.Unwatch(mPortSettingsChanged, &OmxDataDecoder::PortSettingsChanged); - // Do flush so all port can be returned to client. + // Flush to all ports, so all buffers can be returned from component. RefPtr self = this; mOmxLayer->SendCommand(OMX_CommandFlush, OMX_ALL, nullptr) ->Then(mOmxTaskQueue, __func__, [self] () -> RefPtr { - LOG("DoAsyncShutdown: flush complete, collecting buffers..."); - self->CollectBufferPromises(OMX_DirMax) - ->Then(self->mOmxTaskQueue, __func__, - [self] () { - LOG("DoAsyncShutdown: releasing all buffers."); - self->ReleaseBuffers(OMX_DirInput); - self->ReleaseBuffers(OMX_DirOutput); - }, - [self] () { - self->mOmxLayer->Shutdown(); - }); - + LOG("DoAsyncShutdown: flush complete"); return self->mOmxLayer->SendCommand(OMX_CommandStateSet, OMX_StateIdle, nullptr); }, [self] () { @@ -251,8 +240,30 @@ OmxDataDecoder::DoAsyncShutdown() ->CompletionPromise() ->Then(mOmxTaskQueue, __func__, [self] () -> RefPtr { - LOG("DoAsyncShutdown: OMX_StateIdle"); - return self->mOmxLayer->SendCommand(OMX_CommandStateSet, OMX_StateLoaded, nullptr); + RefPtr p = + self->mOmxLayer->SendCommand(OMX_CommandStateSet, OMX_StateLoaded, nullptr); + + LOG("DoAsyncShutdown: collecting buffers..."); + self->CollectBufferPromises(OMX_DirMax) + ->Then(self->mOmxTaskQueue, __func__, + [self] () { + // According to spec 3.1.1.2.2.1: + // OMX_StateLoaded needs to be sent before releasing buffers. + // And state transition from OMX_StateIdle to OMX_StateLoaded + // is completed when all of the buffers have been removed + // from the component. + // Here the buffer promises are not resolved due to displaying + // in layer, it needs to wait before the layer returns the + // buffers. + LOG("DoAsyncShutdown: all buffers collected, releasing buffers..."); + self->ReleaseBuffers(OMX_DirInput); + self->ReleaseBuffers(OMX_DirOutput); + }, + [self] () { + self->mOmxLayer->Shutdown(); + }); + + return p; }, [self] () { self->mOmxLayer->Shutdown(); From ffd963dd3fb816e65fed642d888e621700888d46 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 16 Dec 2015 09:19:00 +0100 Subject: [PATCH 008/139] Bug 1231763 - Extract breakdown parsing from JS::ubi::Census. r=jimb --- .../shared/heapsnapshot/DominatorTree.cpp | 18 +- devtools/shared/heapsnapshot/HeapSnapshot.cpp | 16 +- devtools/shared/heapsnapshot/HeapSnapshot.h | 3 + js/public/UbiNodeCensus.h | 51 ++-- js/src/vm/DebuggerMemory.cpp | 4 +- js/src/vm/UbiNodeCensus.cpp | 267 ++++++++---------- 6 files changed, 169 insertions(+), 190 deletions(-) diff --git a/devtools/shared/heapsnapshot/DominatorTree.cpp b/devtools/shared/heapsnapshot/DominatorTree.cpp index 96f0e68593f2..e53c196cf3e1 100644 --- a/devtools/shared/heapsnapshot/DominatorTree.cpp +++ b/devtools/shared/heapsnapshot/DominatorTree.cpp @@ -4,25 +4,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/devtools/DominatorTree.h" -#include "js/Debug.h" -#include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/dom/DominatorTreeBinding.h" namespace mozilla { namespace devtools { -static MallocSizeOf -getCurrentThreadDebuggerMallocSizeOf() -{ - auto ccrt = CycleCollectedJSRuntime::Get(); - MOZ_ASSERT(ccrt); - auto rt = ccrt->Runtime(); - MOZ_ASSERT(rt); - auto mallocSizeOf = JS::dbg::GetDebuggerMallocSizeOf(rt); - MOZ_ASSERT(mallocSizeOf); - return mallocSizeOf; -} - dom::Nullable DominatorTree::GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv) { @@ -31,7 +17,7 @@ DominatorTree::GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv) if (node.isNothing()) return dom::Nullable(); - auto mallocSizeOf = getCurrentThreadDebuggerMallocSizeOf(); + auto mallocSizeOf = GetCurrentThreadDebuggerMallocSizeOf(); JS::ubi::Node::Size size = 0; if (!mDominatorTree.getRetainedSize(*node, mallocSizeOf, size)) { aRv.Throw(NS_ERROR_OUT_OF_MEMORY); @@ -83,7 +69,7 @@ DominatorTree::GetImmediatelyDominated(uint64_t aNodeId, return; // Get all immediately dominated nodes and their retained sizes. - MallocSizeOf mallocSizeOf = getCurrentThreadDebuggerMallocSizeOf(); + MallocSizeOf mallocSizeOf = GetCurrentThreadDebuggerMallocSizeOf(); Maybe range = mDominatorTree.getDominatedSet(*node); MOZ_ASSERT(range.isSome(), "The node should be known, since we got it from the heap snapshot."); size_t length = range->length(); diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.cpp b/devtools/shared/heapsnapshot/HeapSnapshot.cpp index 854bd3cdc949..9cae51a56ea9 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp +++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp @@ -55,6 +55,18 @@ using ::google::protobuf::io::ZeroCopyInputStream; using JS::ubi::AtomOrTwoByteChars; +MallocSizeOf +GetCurrentThreadDebuggerMallocSizeOf() +{ + auto ccrt = CycleCollectedJSRuntime::Get(); + MOZ_ASSERT(ccrt); + auto rt = ccrt->Runtime(); + MOZ_ASSERT(rt); + auto mallocSizeOf = JS::dbg::GetDebuggerMallocSizeOf(rt); + MOZ_ASSERT(mallocSizeOf); + return mallocSizeOf; +} + /*** Cycle Collection Boilerplate *****************************************************************/ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HeapSnapshot, mParent) @@ -482,7 +494,7 @@ HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options, return; } - JS::ubi::CensusHandler handler(census, rootCount); + JS::ubi::CensusHandler handler(census, rootCount, GetCurrentThreadDebuggerMallocSizeOf()); { JS::AutoCheckCannotGC nogc; @@ -504,7 +516,7 @@ HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options, } } - if (NS_WARN_IF(!handler.report(rval))) { + if (NS_WARN_IF(!handler.report(cx, rval))) { rv.Throw(NS_ERROR_OUT_OF_MEMORY); return; } diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.h b/devtools/shared/heapsnapshot/HeapSnapshot.h index c869c74ae5dc..c8e4557c4790 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.h +++ b/devtools/shared/heapsnapshot/HeapSnapshot.h @@ -221,6 +221,9 @@ WriteHeapGraph(JSContext* cx, ignoreNodeCount, ignoreEdgeCount); } +// Get the mozilla::MallocSizeOf for the current thread's JSRuntime. +MallocSizeOf GetCurrentThreadDebuggerMallocSizeOf(); + } // namespace devtools } // namespace mozilla diff --git a/js/public/UbiNodeCensus.h b/js/public/UbiNodeCensus.h index e881eb188483..891694efa07d 100644 --- a/js/public/UbiNodeCensus.h +++ b/js/public/UbiNodeCensus.h @@ -87,7 +87,7 @@ using CountBasePtr = UniquePtr; // Abstract base class for CountType nodes. struct CountType { - explicit CountType(Census& census) : census(census) { } + explicit CountType() { } virtual ~CountType() { } // Destruct a count tree node that this type instance constructed. @@ -102,14 +102,13 @@ struct CountType { // Implement the 'count' method for counts returned by this CountType // instance's 'newCount' method. - virtual bool count(CountBase& count, const Node& node) = 0; + virtual bool count(CountBase& count, + mozilla::MallocSizeOf mallocSizeOf, + const Node& node) = 0; // Implement the 'report' method for counts returned by this CountType // instance's 'newCount' method. - virtual bool report(CountBase& count, MutableHandleValue report) = 0; - - protected: - Census& census; + virtual bool report(JSContext* cx, CountBase& count, MutableHandleValue report) = 0; }; using CountTypePtr = UniquePtr>; @@ -129,12 +128,16 @@ class CountBase { explicit CountBase(CountType& type) : type(type), total_(0) { } // Categorize and count |node| as appropriate for this count's type. - bool count(const Node& node) { return type.count(*this, node); } + bool count(mozilla::MallocSizeOf mallocSizeOf, const Node& node) { + return type.count(*this, mallocSizeOf, node); + } // Construct a JavaScript object reporting the counts recorded in this // count, and store it in |report|. Return true on success, or false on // failure. - bool report(MutableHandleValue report) { return type.report(*this, report); } + bool report(JSContext* cx, MutableHandleValue report) { + return type.report(cx, *this, report); + } // Down-cast this CountBase to its true type, based on its 'type' member, // and run its destructor. @@ -173,18 +176,6 @@ struct Census { explicit Census(JSContext* cx) : cx(cx), atomsZone(nullptr) { } bool init(); - - // A 'new' work-alike that behaves like TempAllocPolicy: report OOM on this - // census's context, but don't charge the memory allocated to our context's - // GC pressure counters. - template - T* new_(Args&&... args) MOZ_HEAP_ALLOCATOR { - void* memory = js_malloc(sizeof(T)); - if (MOZ_UNLIKELY(!memory)) { - return nullptr; - } - return new(memory) T(mozilla::Forward(args)...); - } }; // A BreadthFirst handler type that conducts a census, using a CountBase to @@ -192,15 +183,17 @@ struct Census { class CensusHandler { Census& census; CountBasePtr& rootCount; + mozilla::MallocSizeOf mallocSizeOf; public: - CensusHandler(Census& census, CountBasePtr& rootCount) + CensusHandler(Census& census, CountBasePtr& rootCount, mozilla::MallocSizeOf mallocSizeOf) : census(census), - rootCount(rootCount) + rootCount(rootCount), + mallocSizeOf(mallocSizeOf) { } - bool report(MutableHandleValue report) { - return rootCount->report(report); + bool report(JSContext* cx, MutableHandleValue report) { + return rootCount->report(cx, report); } // This class needs to retain no per-node data. @@ -213,11 +206,17 @@ class CensusHandler { using CensusTraversal = BreadthFirst; -// Examine the census options supplied by the API consumer, and use that to -// build a CountType tree. +// Examine the census options supplied by the API consumer, and (among other +// things) use that to build a CountType tree. bool ParseCensusOptions(JSContext* cx, Census& census, HandleObject options, CountTypePtr& outResult); +// Parse the breakdown language (as described in +// js/src/doc/Debugger/Debugger.Memory.md) into a CountTypePtr. A null pointer +// is returned on error and is reported to the cx. +CountTypePtr ParseBreakdown(JSContext* cx, HandleValue breakdownValue); + + } // namespace ubi } // namespace JS diff --git a/js/src/vm/DebuggerMemory.cpp b/js/src/vm/DebuggerMemory.cpp index 950c7524a4e4..f763dcc09828 100644 --- a/js/src/vm/DebuggerMemory.cpp +++ b/js/src/vm/DebuggerMemory.cpp @@ -539,7 +539,7 @@ DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) JS::ubi::RootedCount rootCount(cx, rootType->makeCount()); if (!rootCount) return false; - JS::ubi::CensusHandler handler(census, rootCount); + JS::ubi::CensusHandler handler(census, rootCount, cx->runtime()->debuggerMallocSizeOf); Debugger* dbg = memory->getDebugger(); RootedObject dbgObj(cx, dbg->object); @@ -573,7 +573,7 @@ DebuggerMemory::takeCensus(JSContext* cx, unsigned argc, Value* vp) } } - return handler.report(args.rval()); + return handler.report(cx, args.rval()); } diff --git a/js/src/vm/UbiNodeCensus.cpp b/js/src/vm/UbiNodeCensus.cpp index 93bb04b64991..1f9b293cb7f4 100644 --- a/js/src/vm/UbiNodeCensus.cpp +++ b/js/src/vm/UbiNodeCensus.cpp @@ -54,18 +54,17 @@ class SimpleCount : public CountType { bool reportBytes : 1; public: - SimpleCount(Census& census, - UniquePtr& label, - bool reportCount=true, - bool reportBytes=true) - : CountType(census), + explicit SimpleCount(UniquePtr& label, + bool reportCount=true, + bool reportBytes=true) + : CountType(), label(Move(label)), reportCount(reportCount), reportBytes(reportBytes) { } - explicit SimpleCount(Census& census) - : CountType(census), + explicit SimpleCount() + : CountType(), label(nullptr), reportCount(true), reportBytes(true) @@ -76,45 +75,45 @@ class SimpleCount : public CountType { count.~Count(); } - CountBasePtr makeCount() override { return CountBasePtr(census.new_(*this)); } + CountBasePtr makeCount() override { return CountBasePtr(js_new(*this)); } void traceCount(CountBase& countBase, JSTracer* trc) override { } - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; bool -SimpleCount::count(CountBase& countBase, const Node& node) +SimpleCount::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; if (reportBytes) - count.totalBytes_ += node.size(census.cx->runtime()->debuggerMallocSizeOf); + count.totalBytes_ += node.size(mallocSizeOf); return true; } bool -SimpleCount::report(CountBase& countBase, MutableHandleValue report) +SimpleCount::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - RootedPlainObject obj(census.cx, NewBuiltinClassInstance(census.cx)); + RootedPlainObject obj(cx, NewBuiltinClassInstance(cx)); if (!obj) return false; - RootedValue countValue(census.cx, NumberValue(count.total_)); - if (reportCount && !DefineProperty(census.cx, obj, census.cx->names().count, countValue)) + RootedValue countValue(cx, NumberValue(count.total_)); + if (reportCount && !DefineProperty(cx, obj, cx->names().count, countValue)) return false; - RootedValue bytesValue(census.cx, NumberValue(count.totalBytes_)); - if (reportBytes && !DefineProperty(census.cx, obj, census.cx->names().bytes, bytesValue)) + RootedValue bytesValue(cx, NumberValue(count.totalBytes_)); + if (reportBytes && !DefineProperty(cx, obj, cx->names().bytes, bytesValue)) return false; if (label) { - JSString* labelString = JS_NewUCStringCopyZ(census.cx, label.get()); + JSString* labelString = JS_NewUCStringCopyZ(cx, label.get()); if (!labelString) return false; - RootedValue labelValue(census.cx, StringValue(labelString)); - if (!DefineProperty(census.cx, obj, census.cx->names().label, labelValue)) + RootedValue labelValue(cx, StringValue(labelString)); + if (!DefineProperty(cx, obj, cx->names().label, labelValue)) return false; } @@ -155,12 +154,11 @@ class ByCoarseType : public CountType { }; public: - ByCoarseType(Census& census, - CountTypePtr& objects, + ByCoarseType(CountTypePtr& objects, CountTypePtr& scripts, CountTypePtr& strings, CountTypePtr& other) - : CountType(census), + : CountType(), objects(Move(objects)), scripts(Move(scripts)), strings(Move(strings)), @@ -174,8 +172,8 @@ class ByCoarseType : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr @@ -189,11 +187,11 @@ ByCoarseType::makeCount() if (!objectsCount || !scriptsCount || !stringsCount || !otherCount) return CountBasePtr(nullptr); - return CountBasePtr(census.new_(*this, - objectsCount, - scriptsCount, - stringsCount, - otherCount)); + return CountBasePtr(js_new(*this, + objectsCount, + scriptsCount, + stringsCount, + otherCount)); } void @@ -207,20 +205,20 @@ ByCoarseType::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByCoarseType::count(CountBase& countBase, const Node& node) +ByCoarseType::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; switch (node.coarseType()) { case JS::ubi::CoarseType::Object: - return count.objects->count(node); + return count.objects->count(mallocSizeOf, node); case JS::ubi::CoarseType::Script: - return count.scripts->count(node); + return count.scripts->count(mallocSizeOf, node); case JS::ubi::CoarseType::String: - return count.strings->count(node); + return count.strings->count(mallocSizeOf, node); case JS::ubi::CoarseType::Other: - return count.other->count(node); + return count.other->count(mallocSizeOf, node); default: MOZ_CRASH("bad JS::ubi::CoarseType in JS::ubi::ByCoarseType::count"); return false; @@ -228,32 +226,31 @@ ByCoarseType::count(CountBase& countBase, const Node& node) } bool -ByCoarseType::report(CountBase& countBase, MutableHandleValue report) +ByCoarseType::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; RootedPlainObject obj(cx, NewBuiltinClassInstance(cx)); if (!obj) return false; RootedValue objectsReport(cx); - if (!count.objects->report(&objectsReport) || + if (!count.objects->report(cx, &objectsReport) || !DefineProperty(cx, obj, cx->names().objects, objectsReport)) return false; RootedValue scriptsReport(cx); - if (!count.scripts->report(&scriptsReport) || + if (!count.scripts->report(cx, &scriptsReport) || !DefineProperty(cx, obj, cx->names().scripts, scriptsReport)) return false; RootedValue stringsReport(cx); - if (!count.strings->report(&stringsReport) || + if (!count.strings->report(cx, &stringsReport) || !DefineProperty(cx, obj, cx->names().strings, stringsReport)) return false; RootedValue otherReport(cx); - if (!count.other->report(&otherReport) || + if (!count.other->report(cx, &otherReport) || !DefineProperty(cx, obj, cx->names().other, otherReport)) return false; @@ -320,7 +317,7 @@ cStringCountMapToObject(JSContext* cx, CStringCountMap& map) { for (auto& entry : entries) { CountBasePtr& thenCount = entry->value(); RootedValue thenReport(cx); - if (!thenCount->report(&thenReport)) + if (!thenCount->report(cx, &thenReport)) return nullptr; const char* name = entry->key(); @@ -365,10 +362,8 @@ class ByObjectClass : public CountType { CountTypePtr otherType; public: - ByObjectClass(Census& census, - CountTypePtr& classesType, - CountTypePtr& otherType) - : CountType(census), + ByObjectClass(CountTypePtr& classesType, CountTypePtr& otherType) + : CountType(), classesType(Move(classesType)), otherType(Move(otherType)) { } @@ -380,8 +375,8 @@ class ByObjectClass : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr @@ -391,7 +386,7 @@ ByObjectClass::makeCount() if (!otherCount) return nullptr; - UniquePtr count(census.new_(*this, otherCount)); + UniquePtr count(js_new(*this, otherCount)); if (!count || !count->init()) return nullptr; @@ -408,14 +403,14 @@ ByObjectClass::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByObjectClass::count(CountBase& countBase, const Node& node) +ByObjectClass::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; const char* className = node.jsObjectClassName(); if (!className) - return count.other->count(node); + return count.other->count(mallocSizeOf, node); Table::AddPtr p = count.table.lookupForAdd(className); if (!p) { @@ -423,21 +418,20 @@ ByObjectClass::count(CountBase& countBase, const Node& node) if (!classCount || !count.table.add(p, className, Move(classCount))) return false; } - return p->value()->count(node); + return p->value()->count(mallocSizeOf, node); } bool -ByObjectClass::report(CountBase& countBase, MutableHandleValue report) +ByObjectClass::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; RootedPlainObject obj(cx, cStringCountMapToObject(cx, count.table)); if (!obj) return false; RootedValue otherReport(cx); - if (!count.other->report(&otherReport) || + if (!count.other->report(cx, &otherReport) || !DefineProperty(cx, obj, cx->names().other, otherReport)) return false; @@ -466,8 +460,8 @@ class ByUbinodeType : public CountType { CountTypePtr entryType; public: - ByUbinodeType(Census& census, CountTypePtr& entryType) - : CountType(census), + explicit ByUbinodeType(CountTypePtr& entryType) + : CountType(), entryType(Move(entryType)) { } @@ -478,14 +472,14 @@ class ByUbinodeType : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr ByUbinodeType::makeCount() { - UniquePtr count(census.new_(*this)); + UniquePtr count(js_new(*this)); if (!count || !count->init()) return nullptr; @@ -501,7 +495,7 @@ ByUbinodeType::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByUbinodeType::count(CountBase& countBase, const Node& node) +ByUbinodeType::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; @@ -514,14 +508,13 @@ ByUbinodeType::count(CountBase& countBase, const Node& node) if (!typesCount || !count.table.add(p, key, Move(typesCount))) return false; } - return p->value()->count(node); + return p->value()->count(mallocSizeOf, node); } bool -ByUbinodeType::report(CountBase& countBase, MutableHandleValue report) +ByUbinodeType::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; // Build a vector of pointers to entries; sort by total; and then use // that to build the result object. This makes the ordering of entries @@ -541,7 +534,7 @@ ByUbinodeType::report(CountBase& countBase, MutableHandleValue report) Entry& entry = **entryPtr; CountBasePtr& typeCount = entry.value(); RootedValue typeReport(cx); - if (!typeCount->report(&typeReport)) + if (!typeCount->report(cx, &typeReport)) return false; const char16_t* name = entry.key(); @@ -609,8 +602,8 @@ class ByAllocationStack : public CountType { CountTypePtr noStackType; public: - ByAllocationStack(Census& census, CountTypePtr& entryType, CountTypePtr& noStackType) - : CountType(census), + ByAllocationStack(CountTypePtr& entryType, CountTypePtr& noStackType) + : CountType(), entryType(Move(entryType)), noStackType(Move(noStackType)) { } @@ -622,8 +615,8 @@ class ByAllocationStack : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr @@ -633,7 +626,7 @@ ByAllocationStack::makeCount() if (!noStackCount) return nullptr; - UniquePtr count(census.new_(*this, noStackCount)); + UniquePtr count(js_new(*this, noStackCount)); if (!count || !count->init()) return nullptr; return CountBasePtr(count.release()); @@ -657,7 +650,7 @@ ByAllocationStack::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByAllocationStack::count(CountBase& countBase, const Node& node) +ByAllocationStack::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; @@ -673,18 +666,17 @@ ByAllocationStack::count(CountBase& countBase, const Node& node) return false; } MOZ_ASSERT(p); - return p->value()->count(node); + return p->value()->count(mallocSizeOf, node); } // Otherwise, count it in the "no stack" category. - return count.noStack->count(node); + return count.noStack->count(mallocSizeOf, node); } bool -ByAllocationStack::report(CountBase& countBase, MutableHandleValue report) +ByAllocationStack::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; #ifdef DEBUG // Check that nothing rehashes our table while we hold pointers into it. @@ -719,7 +711,7 @@ ByAllocationStack::report(CountBase& countBase, MutableHandleValue report) CountBasePtr& stackCount = entry.value(); RootedValue stackReport(cx); - if (!stackCount->report(&stackReport)) + if (!stackCount->report(cx, &stackReport)) return false; if (!MapObject::set(cx, map, stackVal, stackReport)) @@ -728,7 +720,7 @@ ByAllocationStack::report(CountBase& countBase, MutableHandleValue report) if (count.noStack->total_ > 0) { RootedValue noStackReport(cx); - if (!count.noStack->report(&noStackReport)) + if (!count.noStack->report(cx, &noStackReport)) return false; RootedValue noStack(cx, StringValue(cx->names().noStack)); if (!MapObject::set(cx, map, noStack, noStackReport)) @@ -767,10 +759,8 @@ class ByFilename : public CountType { CountTypePtr noFilenameType; public: - ByFilename(Census& census, - CountTypePtr& thenType, - CountTypePtr& noFilenameType) - : CountType(census), + ByFilename(CountTypePtr& thenType, CountTypePtr& noFilenameType) + : CountType(), thenType(Move(thenType)), noFilenameType(Move(noFilenameType)) { } @@ -782,8 +772,8 @@ class ByFilename : public CountType { CountBasePtr makeCount() override; void traceCount(CountBase& countBase, JSTracer* trc) override; - bool count(CountBase& countBase, const Node& node) override; - bool report(CountBase& countBase, MutableHandleValue report) override; + bool count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) override; + bool report(JSContext* cx, CountBase& countBase, MutableHandleValue report) override; }; CountBasePtr @@ -797,7 +787,7 @@ ByFilename::makeCount() if (!noFilenameCount) return nullptr; - UniquePtr count(census.new_(*this, Move(thenCount), Move(noFilenameCount))); + UniquePtr count(js_new(*this, Move(thenCount), Move(noFilenameCount))); if (!count || !count->init()) return nullptr; @@ -814,14 +804,14 @@ ByFilename::traceCount(CountBase& countBase, JSTracer* trc) } bool -ByFilename::count(CountBase& countBase, const Node& node) +ByFilename::count(CountBase& countBase, mozilla::MallocSizeOf mallocSizeOf, const Node& node) { Count& count = static_cast(countBase); count.total_++; const char* filename = node.scriptFilename(); if (!filename) - return count.noFilename->count(node); + return count.noFilename->count(mallocSizeOf, node); Table::AddPtr p = count.table.lookupForAdd(filename); if (!p) { @@ -829,21 +819,20 @@ ByFilename::count(CountBase& countBase, const Node& node) if (!thenCount || !count.table.add(p, filename, Move(thenCount))) return false; } - return p->value()->count(node); + return p->value()->count(mallocSizeOf, node); } bool -ByFilename::report(CountBase& countBase, MutableHandleValue report) +ByFilename::report(JSContext* cx, CountBase& countBase, MutableHandleValue report) { Count& count = static_cast(countBase); - JSContext* cx = census.cx; RootedPlainObject obj(cx, cStringCountMapToObject(cx, count.table)); if (!obj) return false; RootedValue noFilenameReport(cx); - if (!count.noFilename->report(&noFilenameReport) || + if (!count.noFilename->report(cx, &noFilenameReport) || !DefineProperty(cx, obj, cx->names().noFilename, noFilenameReport)) { return false; @@ -876,11 +865,11 @@ CensusHandler::operator() (BreadthFirst& traversal, Zone* zone = referent.zone(); if (census.targetZones.count() == 0 || census.targetZones.has(zone)) - return rootCount->count(referent); + return rootCount->count(mallocSizeOf, referent); if (zone == census.atomsZone) { traversal.abandonReferent(); - return rootCount->count(referent); + return rootCount->count(mallocSizeOf, referent); } traversal.abandonReferent(); @@ -890,26 +879,21 @@ CensusHandler::operator() (BreadthFirst& traversal, /*** Parsing Breakdowns ***************************************************************************/ -static CountTypePtr ParseBreakdown(Census& census, HandleValue breakdownValue); - static CountTypePtr -ParseChildBreakdown(Census& census, HandleObject breakdown, PropertyName* prop) +ParseChildBreakdown(JSContext* cx, HandleObject breakdown, PropertyName* prop) { - JSContext* cx = census.cx; RootedValue v(cx); if (!GetProperty(cx, breakdown, breakdown, prop, &v)) return nullptr; - return ParseBreakdown(census, v); + return ParseBreakdown(cx, v); } -static CountTypePtr -ParseBreakdown(Census& census, HandleValue breakdownValue) +CountTypePtr +ParseBreakdown(JSContext* cx, HandleValue breakdownValue) { - JSContext* cx = census.cx; - if (breakdownValue.isUndefined()) { // Construct the default type, { by: 'count' } - CountTypePtr simple(census.new_(census)); + CountTypePtr simple(js_new()); return simple; } @@ -967,75 +951,73 @@ ParseBreakdown(Census& census, HandleValue breakdownValue) return nullptr; } - CountTypePtr simple(census.new_(census, - labelUnique, - ToBoolean(countValue), - ToBoolean(bytesValue))); + CountTypePtr simple(js_new(labelUnique, + ToBoolean(countValue), + ToBoolean(bytesValue))); return simple; } if (StringEqualsAscii(by, "objectClass")) { - CountTypePtr thenType(ParseChildBreakdown(census, breakdown, cx->names().then)); + CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then)); if (!thenType) return nullptr; - CountTypePtr otherType(ParseChildBreakdown(census, breakdown, cx->names().other)); + CountTypePtr otherType(ParseChildBreakdown(cx, breakdown, cx->names().other)); if (!otherType) return nullptr; - return CountTypePtr(census.new_(census, thenType, otherType)); + return CountTypePtr(js_new(thenType, otherType)); } if (StringEqualsAscii(by, "coarseType")) { - CountTypePtr objectsType(ParseChildBreakdown(census, breakdown, cx->names().objects)); + CountTypePtr objectsType(ParseChildBreakdown(cx, breakdown, cx->names().objects)); if (!objectsType) return nullptr; - CountTypePtr scriptsType(ParseChildBreakdown(census, breakdown, cx->names().scripts)); + CountTypePtr scriptsType(ParseChildBreakdown(cx, breakdown, cx->names().scripts)); if (!scriptsType) return nullptr; - CountTypePtr stringsType(ParseChildBreakdown(census, breakdown, cx->names().strings)); + CountTypePtr stringsType(ParseChildBreakdown(cx, breakdown, cx->names().strings)); if (!stringsType) return nullptr; - CountTypePtr otherType(ParseChildBreakdown(census, breakdown, cx->names().other)); + CountTypePtr otherType(ParseChildBreakdown(cx, breakdown, cx->names().other)); if (!otherType) return nullptr; - return CountTypePtr(census.new_(census, - objectsType, - scriptsType, - stringsType, - otherType)); + return CountTypePtr(js_new(objectsType, + scriptsType, + stringsType, + otherType)); } if (StringEqualsAscii(by, "internalType")) { - CountTypePtr thenType(ParseChildBreakdown(census, breakdown, cx->names().then)); + CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then)); if (!thenType) return nullptr; - return CountTypePtr(census.new_(census, thenType)); + return CountTypePtr(js_new(thenType)); } if (StringEqualsAscii(by, "allocationStack")) { - CountTypePtr thenType(ParseChildBreakdown(census, breakdown, cx->names().then)); + CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then)); if (!thenType) return nullptr; - CountTypePtr noStackType(ParseChildBreakdown(census, breakdown, cx->names().noStack)); + CountTypePtr noStackType(ParseChildBreakdown(cx, breakdown, cx->names().noStack)); if (!noStackType) return nullptr; - return CountTypePtr(census.new_(census, thenType, noStackType)); + return CountTypePtr(js_new(thenType, noStackType)); } if (StringEqualsAscii(by, "filename")) { - CountTypePtr thenType(ParseChildBreakdown(census, breakdown, cx->names().then)); + CountTypePtr thenType(ParseChildBreakdown(cx, breakdown, cx->names().then)); if (!thenType) return nullptr; - CountTypePtr noFilenameType(ParseChildBreakdown(census, breakdown, cx->names().noFilename)); + CountTypePtr noFilenameType(ParseChildBreakdown(cx, breakdown, cx->names().noFilename)); if (!noFilenameType) return nullptr; - return CountTypePtr(census.new_(census, thenType, noFilenameType)); + return CountTypePtr(js_new(thenType, noFilenameType)); } // We didn't recognize the breakdown type; complain. @@ -1059,25 +1041,22 @@ ParseBreakdown(Census& census, HandleValue breakdownValue) // other: { by: "internalType" } // } static CountTypePtr -GetDefaultBreakdown(Census& census) +GetDefaultBreakdown() { - CountTypePtr byClass(census.new_(census)); - CountTypePtr byClassElse(census.new_(census)); - CountTypePtr objects(census.new_(census, - byClass, - byClassElse)); + CountTypePtr byClass(js_new()); + CountTypePtr byClassElse(js_new()); + CountTypePtr objects(js_new(byClass, byClassElse)); - CountTypePtr scripts(census.new_(census)); - CountTypePtr strings(census.new_(census)); + CountTypePtr scripts(js_new()); + CountTypePtr strings(js_new()); - CountTypePtr byType(census.new_(census)); - CountTypePtr other(census.new_(census, byType)); + CountTypePtr byType(js_new()); + CountTypePtr other(js_new(byType)); - return CountTypePtr(census.new_(census, - objects, - scripts, - strings, - other)); + return CountTypePtr(js_new(objects, + scripts, + strings, + other)); } bool @@ -1088,8 +1067,8 @@ ParseCensusOptions(JSContext* cx, Census& census, HandleObject options, CountTyp return false; outResult = breakdown.isUndefined() - ? GetDefaultBreakdown(census) - : ParseBreakdown(census, breakdown); + ? GetDefaultBreakdown() + : ParseBreakdown(cx, breakdown); return !!outResult; } From cac3ddd6794fb48a3700b7311f8126588bd8a952 Mon Sep 17 00:00:00 2001 From: Wei Wu Date: Wed, 16 Dec 2015 06:54:00 +0100 Subject: [PATCH 009/139] Bug 1232100 - "Check charsWritten in non-debug builds.". r=jcoppeard --- js/src/jsprf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/jsprf.cpp b/js/src/jsprf.cpp index 0d367de047c2..0cdd27ddfb54 100644 --- a/js/src/jsprf.cpp +++ b/js/src/jsprf.cpp @@ -1021,7 +1021,7 @@ JS_vsnprintf(char* out, uint32_t outlen, const char* fmt, va_list ap) (void) dosprintf(&ss, fmt, ap); uint32_t charsWritten = ss.cur - ss.base; - MOZ_ASSERT(charsWritten > 0); + MOZ_RELEASE_ASSERT(charsWritten > 0); // If we didn't append a null then we must have hit the buffer limit. Write // a null terminator now and return a value indicating that we failed. From 92dea2cfcd695c73c4e9676a833deba41ee10ed5 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 16 Dec 2015 08:59:00 +0100 Subject: [PATCH 010/139] Bug 1233096 - Give JS::ubi::RootList its full type name as its concreteTypeName; r=jimb --- js/src/vm/UbiNode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/vm/UbiNode.cpp b/js/src/vm/UbiNode.cpp index 3e682a7a33dc..251c61c98a17 100644 --- a/js/src/vm/UbiNode.cpp +++ b/js/src/vm/UbiNode.cpp @@ -497,7 +497,7 @@ RootList::addRoot(Node node, const char16_t* edgeName) return edges.append(mozilla::Move(Edge(name.release(), node))); } -const char16_t Concrete::concreteTypeName[] = MOZ_UTF16("RootList"); +const char16_t Concrete::concreteTypeName[] = MOZ_UTF16("JS::ubi::RootList"); UniquePtr Concrete::edges(JSRuntime* rt, bool wantNames) const { From 3f33e136b81be07f10cf258db84db75f516a97d4 Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Mon, 7 Dec 2015 22:56:52 -0500 Subject: [PATCH 011/139] Bug 1232907 - Enable ExecutableAllocator randomization on Windows XP. r=jandem --HG-- extra : rebase_source : d93444de433c1dd94f13eb7af50dd20d00cfbfb1 --- js/src/jit/ExecutableAllocatorWin.cpp | 28 ++++----------------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/js/src/jit/ExecutableAllocatorWin.cpp b/js/src/jit/ExecutableAllocatorWin.cpp index fe068b908140..4fa240a2fce7 100644 --- a/js/src/jit/ExecutableAllocatorWin.cpp +++ b/js/src/jit/ExecutableAllocatorWin.cpp @@ -77,22 +77,6 @@ ExecutableAllocator::computeRandomAllocationAddress() return (void*) (base | (rand & mask)); } -static bool -RandomizeIsBrokenImpl() -{ - // We disable everything before Vista, for now. - return !mozilla::IsVistaOrLater(); -} - -static bool -RandomizeIsBroken() -{ - // Use the compiler's intrinsic guards for |static type value = expr| to avoid some potential - // races if runtimes are created from multiple threads. - static int result = RandomizeIsBrokenImpl(); - return !!result; -} - #ifdef JS_CPU_X64 static js::JitExceptionHandler sJitExceptionHandler; @@ -236,15 +220,11 @@ js::jit::DeallocateExecutableMemory(void* addr, size_t bytes, size_t pageSize) ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) { - void* allocation = nullptr; - if (!RandomizeIsBroken()) { - void* randomAddress = computeRandomAllocationAddress(); - allocation = AllocateExecutableMemory(randomAddress, n, initialProtectionFlags(Executable), - "js-jit-code", pageSize); - } + void* randomAddress = computeRandomAllocationAddress(); + unsigned flags = initialProtectionFlags(Executable); + void* allocation = AllocateExecutableMemory(randomAddress, n, flags, "js-jit-code", pageSize); if (!allocation) { - allocation = AllocateExecutableMemory(nullptr, n, initialProtectionFlags(Executable), - "js-jit-code", pageSize); + allocation = AllocateExecutableMemory(nullptr, n, flags, "js-jit-code", pageSize); } ExecutablePool::Allocation alloc = { reinterpret_cast(allocation), n }; return alloc; From 95a1a37ae64a290668e60591820ff158cbc4345d Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Thu, 17 Dec 2015 10:28:33 +0100 Subject: [PATCH 012/139] Backed out changeset 9b7df7c7adc1 (bug 1224892) for m13 test failures --HG-- extra : rebase_source : 267dd2cda5873c38b6ebb9b53075675bbae9969c --- dom/webidl/Navigator.webidl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index c4dc1dad6983..b98e2080eba7 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -190,7 +190,7 @@ Navigator implements NavigatorMobileId; // nsIDOMNavigator partial interface Navigator { - [Throws, Constant, Cached] + [Throws] readonly attribute DOMString oscpu; // WebKit/Blink support this; Trident/Presto do not. readonly attribute DOMString vendor; @@ -200,7 +200,7 @@ partial interface Navigator { readonly attribute DOMString productSub; // WebKit/Blink/Trident/Presto support this. readonly attribute boolean cookieEnabled; - [Throws, Constant, Cached] + [Throws] readonly attribute DOMString buildID; [Throws, CheckAnyPermissions="power", UnsafeInPrerendering] readonly attribute MozPowerManager mozPower; From 49d77e4067aeb665be069abd5eeca1319a8c3a86 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:02:09 +0900 Subject: [PATCH 013/139] Bug 1229057 - Part 1: Move MacroAssembler::addPtr into generic macro assembler. r=nbp --HG-- extra : rebase_source : 0297438cdb0454e831b91dcbe4318e835e38e89d --- js/src/jit/MacroAssembler-inl.h | 9 +++ js/src/jit/MacroAssembler.h | 10 +++ js/src/jit/arm/MacroAssembler-arm-inl.h | 35 ++++++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 29 -------- js/src/jit/arm/MacroAssembler-arm.h | 10 --- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 67 +++++++++++++++++++ js/src/jit/arm64/MacroAssembler-arm64.cpp | 4 +- js/src/jit/arm64/MacroAssembler-arm64.h | 43 +----------- .../MacroAssembler-mips-shared-inl.h | 15 +++++ js/src/jit/mips32/MacroAssembler-mips32-inl.h | 35 ++++++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 29 +------- js/src/jit/mips32/MacroAssembler-mips32.h | 25 +------ js/src/jit/mips64/MacroAssembler-mips64-inl.h | 37 ++++++++++ js/src/jit/mips64/MacroAssembler-mips64.cpp | 31 +-------- js/src/jit/mips64/MacroAssembler-mips64.h | 26 +------ js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x64/MacroAssembler-x64-inl.h | 61 +++++++++++++++++ js/src/jit/x64/MacroAssembler-x64.cpp | 4 +- js/src/jit/x64/MacroAssembler-x64.h | 42 +----------- .../jit/x86-shared/MoveEmitter-x86-shared.cpp | 3 +- js/src/jit/x86/MacroAssembler-x86-inl.h | 37 ++++++++++ js/src/jit/x86/MacroAssembler-x86.cpp | 2 +- js/src/jit/x86/MacroAssembler-x86.h | 21 ------ 23 files changed, 324 insertions(+), 252 deletions(-) diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h index db06fdf8e693..0ff8a4c9233f 100644 --- a/js/src/jit/MacroAssembler-inl.h +++ b/js/src/jit/MacroAssembler-inl.h @@ -313,6 +313,15 @@ MacroAssembler::hasSelfReference() const return selfReferencePatch_.bound(); } +// =============================================================== +// Arithmetic functions + +void +MacroAssembler::addPtr(ImmPtr imm, Register dest) +{ + addPtr(ImmWord(uintptr_t(imm.value)), dest); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 2e329be96688..07a68b9b4eec 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -731,6 +731,16 @@ class MacroAssembler : public MacroAssemblerSpecific // =============================================================== // Arithmetic functions + inline void addPtr(Register src, Register dest) PER_ARCH; + inline void addPtr(Register src1, Register src2, Register dest) DEFINED_ON(arm64); + inline void addPtr(Imm32 imm, Register dest) PER_ARCH; + inline void addPtr(Imm32 imm, Register src, Register dest) DEFINED_ON(arm64); + inline void addPtr(ImmWord imm, Register dest) PER_ARCH; + inline void addPtr(ImmPtr imm, Register dest); + inline void addPtr(Imm32 imm, const Address& dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); + inline void addPtr(Imm32 imm, const AbsoluteAddress& dest) DEFINED_ON(x86, x64); + inline void addPtr(const Address& src, Register dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); + inline void sub32(const Address& src, Register dest) PER_SHARED_ARCH; inline void sub32(Register src, Register dest) PER_SHARED_ARCH; inline void sub32(Imm32 imm, Register dest) PER_SHARED_ARCH; diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 4ae13769493c..9b59ff749ebe 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -138,6 +138,41 @@ MacroAssembler::xorPtr(Imm32 imm, Register dest) // =============================================================== // Arithmetic functions +void +MacroAssembler::addPtr(Register src, Register dest) +{ + ma_add(src, dest); +} + +void +MacroAssembler::addPtr(Imm32 imm, Register dest) +{ + ma_add(imm, dest); +} + +void +MacroAssembler::addPtr(ImmWord imm, Register dest) +{ + addPtr(Imm32(imm.value), dest); +} + +void +MacroAssembler::addPtr(Imm32 imm, const Address& dest) +{ + ScratchRegisterScope scratch(*this); + loadPtr(dest, scratch); + addPtr(imm, scratch); + storePtr(scratch, dest); +} + +void +MacroAssembler::addPtr(const Address& src, Register dest) +{ + ScratchRegisterScope scratch(*this); + load32(src, scratch); + ma_add(scratch, dest, SetCC); +} + void MacroAssembler::add64(Register64 src, Register64 dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 41741528a5b4..796d06457714 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -1968,20 +1968,6 @@ MacroAssemblerARMCompat::add32(Imm32 imm, const Address& dest) store32(scratch, dest); } -void -MacroAssemblerARMCompat::addPtr(Register src, Register dest) -{ - ma_add(src, dest); -} - -void -MacroAssemblerARMCompat::addPtr(const Address& src, Register dest) -{ - ScratchRegisterScope scratch(asMasm()); - load32(src, scratch); - ma_add(scratch, dest, SetCC); -} - void MacroAssemblerARMCompat::move32(Imm32 imm, Register dest) { @@ -2655,21 +2641,6 @@ MacroAssemblerARMCompat::subPtr(Register src, const Address& dest) storePtr(scratch, dest); } -void -MacroAssemblerARMCompat::addPtr(Imm32 imm, const Register dest) -{ - ma_add(imm, dest); -} - -void -MacroAssemblerARMCompat::addPtr(Imm32 imm, const Address& dest) -{ - ScratchRegisterScope scratch(asMasm()); - loadPtr(dest, scratch); - addPtr(imm, scratch); - storePtr(scratch, dest); -} - void MacroAssemblerARMCompat::compareDouble(FloatRegister lhs, FloatRegister rhs) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 23962bbded8e..1f8a6c334a06 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1199,8 +1199,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM j(cond, label); } - void addPtr(Register src, Register dest); - void addPtr(const Address& src, Register dest); void add64(Imm32 imm, Register64 dest) { ma_add(imm, dest.low, SetCC); ma_adc(Imm32(0), dest.high, LeaveCC); @@ -1655,14 +1653,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void subPtr(const Address& addr, const Register dest); void subPtr(Register src, Register dest); void subPtr(Register src, const Address& dest); - void addPtr(Imm32 imm, const Register dest); - void addPtr(Imm32 imm, const Address& dest); - void addPtr(ImmWord imm, const Register dest) { - addPtr(Imm32(imm.value), dest); - } - void addPtr(ImmPtr imm, const Register dest) { - addPtr(ImmWord(uintptr_t(imm.value)), dest); - } void mulBy3(const Register& src, const Register& dest) { as_add(dest, src, lsl(src, 1)); } diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 7550437a4add..04bb8c53480d 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -150,6 +150,59 @@ MacroAssembler::xorPtr(Imm32 imm, Register dest) // =============================================================== // Arithmetic functions +void +MacroAssembler::addPtr(Register src, Register dest) +{ + addPtr(src, dest, dest); +} + +void +MacroAssembler::addPtr(Register src1, Register src2, Register dest) +{ + Add(ARMRegister(dest, 64), ARMRegister(src1, 64), Operand(ARMRegister(src2, 64))); +} + +void +MacroAssembler::addPtr(Imm32 imm, Register dest) +{ + addPtr(imm, dest, dest); +} + +void +MacroAssembler::addPtr(Imm32 imm, Register src, Register dest) +{ + Add(ARMRegister(dest, 64), ARMRegister(src, 64), Operand(imm.value)); +} + +void +MacroAssembler::addPtr(ImmWord imm, Register dest) +{ + Add(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(imm.value)); +} + +void +MacroAssembler::addPtr(Imm32 imm, const Address& dest) +{ + vixl::UseScratchRegisterScope temps(this); + const ARMRegister scratch64 = temps.AcquireX(); + MOZ_ASSERT(scratch64.asUnsized() != dest.base); + + Ldr(scratch64, MemOperand(ARMRegister(dest.base, 64), dest.offset)); + Add(scratch64, scratch64, Operand(imm.value)); + Str(scratch64, MemOperand(ARMRegister(dest.base, 64), dest.offset)); +} + +void +MacroAssembler::addPtr(const Address& src, Register dest) +{ + vixl::UseScratchRegisterScope temps(this); + const ARMRegister scratch64 = temps.AcquireX(); + MOZ_ASSERT(scratch64.asUnsized() != src.base); + + Ldr(scratch64, MemOperand(ARMRegister(src.base, 64), src.offset)); + Add(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(scratch64)); +} + void MacroAssembler::add64(Register64 src, Register64 dest) { @@ -220,6 +273,20 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== +template +void +MacroAssemblerCompat::addToStackPtr(T t) +{ + asMasm().addPtr(t, getStackPointer()); +} + +template +void +MacroAssemblerCompat::addStackPtrTo(T t) +{ + asMasm().addPtr(getStackPointer(), t); +} + template void MacroAssemblerCompat::andToStackPtr(T t) diff --git a/js/src/jit/arm64/MacroAssembler-arm64.cpp b/js/src/jit/arm64/MacroAssembler-arm64.cpp index c7060b57a287..adda0d64c112 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.cpp +++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp @@ -226,7 +226,7 @@ MacroAssemblerCompat::branchPtrInNurseryRange(Condition cond, Register ptr, Regi const Nursery& nursery = GetJitContext()->runtime->gcNursery(); movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp); - addPtr(ptr, temp); + asMasm().addPtr(ptr, temp); branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual, temp, ImmWord(nursery.nurserySize()), label); } @@ -248,7 +248,7 @@ MacroAssemblerCompat::branchValueIsNurseryObject(Condition cond, ValueOperand va Value start = ObjectValue(*reinterpret_cast(nursery.start())); movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), temp); - addPtr(value.valueReg(), temp); + asMasm().addPtr(value.valueReg(), temp); branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual, temp, ImmWord(nursery.nurserySize()), label); } diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 268caa8b2c21..7f7b9c50edbc 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1029,10 +1029,8 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void storeUnalignedFloat32x4(FloatRegister dest, const BaseIndex& addr) { MOZ_CRASH("NYI"); } // StackPointer manipulation. - template - void addToStackPtr(T t) { addPtr(t, getStackPointer()); } - template - void addStackPtrTo(T t) { addPtr(getStackPointer(), t); } + template void addToStackPtr(T t); + template void addStackPtrTo(T t); template void subFromStackPtr(T t) { subPtr(t, getStackPointer()); syncStackPtr(); } @@ -1370,43 +1368,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler Subs(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(ARMRegister(src, 32))); } - void addPtr(Register src, Register dest) { - Add(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(ARMRegister(src, 64))); - } - void addPtr(Register src1, Register src2, Register dest) { - Add(ARMRegister(dest, 64), ARMRegister(src1, 64), Operand(ARMRegister(src2, 64))); - } - - void addPtr(Imm32 imm, Register dest) { - Add(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(imm.value)); - } - void addPtr(Imm32 imm, Register src, Register dest) { - Add(ARMRegister(dest, 64), ARMRegister(src, 64), Operand(imm.value)); - } - - void addPtr(Imm32 imm, const Address& dest) { - vixl::UseScratchRegisterScope temps(this); - const ARMRegister scratch64 = temps.AcquireX(); - MOZ_ASSERT(scratch64.asUnsized() != dest.base); - - Ldr(scratch64, MemOperand(ARMRegister(dest.base, 64), dest.offset)); - Add(scratch64, scratch64, Operand(imm.value)); - Str(scratch64, MemOperand(ARMRegister(dest.base, 64), dest.offset)); - } - void addPtr(ImmWord imm, Register dest) { - Add(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(imm.value)); - } - void addPtr(ImmPtr imm, Register dest) { - Add(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(uint64_t(imm.value))); - } - void addPtr(const Address& src, Register dest) { - vixl::UseScratchRegisterScope temps(this); - const ARMRegister scratch64 = temps.AcquireX(); - MOZ_ASSERT(scratch64.asUnsized() != src.base); - - Ldr(scratch64, MemOperand(ARMRegister(src.base, 64), src.offset)); - Add(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(scratch64)); - } void subPtr(Imm32 imm, Register dest) { Sub(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(imm.value)); } diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index 19ee11aa456d..554971307104 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -78,6 +78,21 @@ MacroAssembler::xor32(Imm32 imm, Register dest) // =============================================================== // Arithmetic instructions +void +MacroAssembler::addPtr(Imm32 imm, const Address& dest) +{ + loadPtr(dest, ScratchRegister); + addPtr(imm, ScratchRegister); + storePtr(ScratchRegister, dest); +} + +void +MacroAssembler::addPtr(const Address& src, Register dest) +{ + loadPtr(src, ScratchRegister); + addPtr(ScratchRegister, dest); +} + void MacroAssembler::sub32(Register src, Register dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index d7fce94fbf20..21ffa9d3f730 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -78,6 +78,24 @@ MacroAssembler::xorPtr(Imm32 imm, Register dest) // =============================================================== // Arithmetic functions +void +MacroAssembler::addPtr(Register src, Register dest) +{ + ma_addu(dest, src); +} + +void +MacroAssembler::addPtr(Imm32 imm, Register dest) +{ + ma_addu(dest, imm); +} + +void +MacroAssembler::addPtr(ImmWord imm, Register dest) +{ + addPtr(Imm32(imm.value), dest); +} + void MacroAssembler::add64(Register64 src, Register64 dest) { @@ -131,6 +149,23 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== +void +MacroAssemblerMIPSCompat::computeEffectiveAddress(const BaseIndex& address, Register dest) +{ + computeScaledAddress(address, dest); + if (address.offset) + asMasm().addPtr(Imm32(address.offset), dest); +} + +void +MacroAssemblerMIPSCompat::retn(Imm32 n) { + // pc <- [sp]; sp += n + loadPtr(Address(StackPointer, 0), ra); + asMasm().addPtr(n, StackPointer); + as_jr(ra); + as_nop(); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 462c1d0a873d..bb9e1171b412 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -833,19 +833,6 @@ MacroAssemblerMIPSCompat::add32(Imm32 imm, const Address& dest) store32(SecondScratchReg, dest); } -void -MacroAssemblerMIPSCompat::addPtr(Register src, Register dest) -{ - ma_addu(dest, src); -} - -void -MacroAssemblerMIPSCompat::addPtr(const Address& src, Register dest) -{ - loadPtr(src, ScratchRegister); - ma_addu(dest, ScratchRegister); -} - void MacroAssemblerMIPSCompat::subPtr(Register src, Register dest) { @@ -1262,20 +1249,6 @@ MacroAssemblerMIPSCompat::subPtr(Register src, const Address& dest) storePtr(SecondScratchReg, dest); } -void -MacroAssemblerMIPSCompat::addPtr(Imm32 imm, const Register dest) -{ - ma_addu(dest, imm); -} - -void -MacroAssemblerMIPSCompat::addPtr(Imm32 imm, const Address& dest) -{ - loadPtr(dest, ScratchRegister); - addPtr(imm, ScratchRegister); - storePtr(ScratchRegister, dest); -} - void MacroAssemblerMIPSCompat::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs, Label* label) @@ -2548,7 +2521,7 @@ MacroAssemblerMIPSCompat::branchPtrInNurseryRange(Condition cond, Register ptr, const Nursery& nursery = GetJitContext()->runtime->gcNursery(); movePtr(ImmWord(-ptrdiff_t(nursery.start())), SecondScratchReg); - addPtr(ptr, SecondScratchReg); + asMasm().addPtr(ptr, SecondScratchReg); branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual, SecondScratchReg, Imm32(nursery.nurserySize()), label); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 319748378f63..a43ec5677d73 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -189,12 +189,7 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS ma_addu(dest, address.base, Imm32(address.offset)); } - void computeEffectiveAddress(const BaseIndex& address, Register dest) { - computeScaledAddress(address, dest); - if (address.offset) { - addPtr(Imm32(address.offset), dest); - } - } + inline void computeEffectiveAddress(const BaseIndex& address, Register dest); void j(Label* dest) { ma_b(dest); @@ -235,13 +230,7 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS as_jr(ra); as_nop(); } - void retn(Imm32 n) { - // pc <- [sp]; sp += n - loadPtr(Address(StackPointer, 0), ra); - addPtr(n, StackPointer); - as_jr(ra); - as_nop(); - } + inline void retn(Imm32 n); void push(Imm32 imm) { ma_li(ScratchRegister, imm); ma_push(ScratchRegister); @@ -1111,9 +1100,7 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS } } - void addPtr(Register src, Register dest); void subPtr(Register src, Register dest); - void addPtr(const Address& src, Register dest); void move32(Imm32 imm, Register dest); void move32(Register src, Register dest); @@ -1258,14 +1245,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void subPtr(Imm32 imm, const Register dest); void subPtr(const Address& addr, const Register dest); void subPtr(Register src, const Address& dest); - void addPtr(Imm32 imm, const Register dest); - void addPtr(Imm32 imm, const Address& dest); - void addPtr(ImmWord imm, const Register dest) { - addPtr(Imm32(imm.value), dest); - } - void addPtr(ImmPtr imm, const Register dest) { - addPtr(ImmWord(uintptr_t(imm.value)), dest); - } void mulBy3(const Register& src, const Register& dest) { as_addu(dest, src, src); as_addu(dest, dest, src); diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index 6f84296df148..db7c9ec0c0b8 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -76,6 +76,25 @@ MacroAssembler::xorPtr(Imm32 imm, Register dest) // =============================================================== // Arithmetic functions +void +MacroAssembler::addPtr(Register src, Register dest) +{ + ma_daddu(dest, src); +} + +void +MacroAssembler::addPtr(Imm32 imm, Register dest) +{ + ma_daddu(dest, imm); +} + +void +MacroAssembler::addPtr(ImmWord imm, Register dest) +{ + movePtr(imm, ScratchRegister); + addPtr(ScratchRegister, dest); +} + void MacroAssembler::add64(Register64 src, Register64 dest) { @@ -118,6 +137,24 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== +void +MacroAssemblerMIPS64Compat::computeEffectiveAddress(const BaseIndex& address, Register dest) +{ + computeScaledAddress(address, dest); + if (address.offset) + asMasm().addPtr(Imm32(address.offset), dest); +} + +void +MacroAssemblerMIPS64Compat::retn(Imm32 n) +{ + // pc <- [sp]; sp += n + loadPtr(Address(StackPointer, 0), ra); + asMasm().addPtr(n, StackPointer); + as_jr(ra); + as_nop(); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 6b30781854ad..40662e32323d 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -918,19 +918,6 @@ MacroAssemblerMIPS64Compat::add32(Imm32 imm, const Address& dest) store32(SecondScratchReg, dest); } -void -MacroAssemblerMIPS64Compat::addPtr(Register src, Register dest) -{ - ma_daddu(dest, src); -} - -void -MacroAssemblerMIPS64Compat::addPtr(const Address& src, Register dest) -{ - loadPtr(src, ScratchRegister); - ma_daddu(dest, ScratchRegister); -} - void MacroAssemblerMIPS64Compat::subPtr(Register src, Register dest) { @@ -1348,20 +1335,6 @@ MacroAssemblerMIPS64Compat::subPtr(Register src, const Address& dest) storePtr(SecondScratchReg, dest); } -void -MacroAssemblerMIPS64Compat::addPtr(Imm32 imm, const Register dest) -{ - ma_daddu(dest, imm); -} - -void -MacroAssemblerMIPS64Compat::addPtr(Imm32 imm, const Address& dest) -{ - loadPtr(dest, ScratchRegister); - addPtr(imm, ScratchRegister); - storePtr(ScratchRegister, dest); -} - void MacroAssemblerMIPS64Compat::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs, Label* label) @@ -2651,7 +2624,7 @@ MacroAssemblerMIPS64Compat::branchPtrInNurseryRange(Condition cond, Register ptr const Nursery& nursery = GetJitContext()->runtime->gcNursery(); movePtr(ImmWord(-ptrdiff_t(nursery.start())), SecondScratchReg); - addPtr(ptr, SecondScratchReg); + asMasm().addPtr(ptr, SecondScratchReg); branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual, SecondScratchReg, Imm32(nursery.nurserySize()), label); } @@ -2667,7 +2640,7 @@ MacroAssemblerMIPS64Compat::branchValueIsNurseryObject(Condition cond, ValueOper Value start = ObjectValue(*reinterpret_cast(nursery.start())); movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), SecondScratchReg); - addPtr(value.valueReg(), SecondScratchReg); + asMasm().addPtr(value.valueReg(), SecondScratchReg); branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual, SecondScratchReg, Imm32(nursery.nurserySize()), label); } diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 44364ffca379..e80cb4f15dae 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -201,12 +201,7 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 ma_daddu(dest, address.base, Imm32(address.offset)); } - void computeEffectiveAddress(const BaseIndex& address, Register dest) { - computeScaledAddress(address, dest); - if (address.offset) { - addPtr(Imm32(address.offset), dest); - } - } + inline void computeEffectiveAddress(const BaseIndex& address, Register dest); void j(Label* dest) { ma_b(dest); @@ -256,13 +251,7 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 as_jr(ra); as_nop(); } - void retn(Imm32 n) { - // pc <- [sp]; sp += n - loadPtr(Address(StackPointer, 0), ra); - addPtr(n, StackPointer); - as_jr(ra); - as_nop(); - } + inline void retn(Imm32 n); void push(Imm32 imm) { ma_li(ScratchRegister, imm); ma_push(ScratchRegister); @@ -1126,9 +1115,7 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 } } - void addPtr(Register src, Register dest); void subPtr(Register src, Register dest); - void addPtr(const Address& src, Register dest); void move32(Imm32 imm, Register dest); void move32(Register src, Register dest); @@ -1269,15 +1256,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void subPtr(Imm32 imm, const Register dest); void subPtr(const Address& addr, const Register dest); void subPtr(Register src, const Address& dest); - void addPtr(Imm32 imm, const Register dest); - void addPtr(Imm32 imm, const Address& dest); - void addPtr(ImmWord imm, const Register dest) { - movePtr(imm, ScratchRegister); - addPtr(ScratchRegister, dest); - } - void addPtr(ImmPtr imm, const Register dest) { - addPtr(ImmWord(uintptr_t(imm.value)), dest); - } void mulBy3(const Register& src, const Register& dest) { as_daddu(dest, src, src); as_daddu(dest, dest, src); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 512ae813d68e..c97449b5f3c1 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -235,7 +235,6 @@ class MacroAssemblerNone : public Assembler template void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); } template void add32(T, S) { MOZ_CRASH(); } - template void addPtr(T, S) { MOZ_CRASH(); } template void add64(T, S) { MOZ_CRASH(); } template void subPtr(T, S) { MOZ_CRASH(); } void neg32(Register) { MOZ_CRASH(); } diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index e606899062ed..f5400ca9e7fb 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -75,6 +75,49 @@ MacroAssembler::xorPtr(Imm32 imm, Register dest) // =============================================================== // Arithmetic functions +void +MacroAssembler::addPtr(Register src, Register dest) +{ + addq(src, dest); +} + +void +MacroAssembler::addPtr(Imm32 imm, Register dest) +{ + addq(imm, dest); +} + +void +MacroAssembler::addPtr(ImmWord imm, Register dest) +{ + ScratchRegisterScope scratch(*this); + MOZ_ASSERT(dest != scratch); + if ((intptr_t)imm.value <= INT32_MAX && (intptr_t)imm.value >= INT32_MIN) { + addq(Imm32((int32_t)imm.value), dest); + } else { + mov(imm, scratch); + addq(scratch, dest); + } +} + +void +MacroAssembler::addPtr(Imm32 imm, const Address& dest) +{ + addq(imm, Operand(dest)); +} + +void +MacroAssembler::addPtr(Imm32 imm, const AbsoluteAddress& dest) +{ + addq(imm, Operand(dest)); +} + +void +MacroAssembler::addPtr(const Address& src, Register dest) +{ + addq(Operand(src), dest); +} + void MacroAssembler::add64(Register64 src, Register64 dest) { @@ -117,6 +160,24 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== +void +MacroAssemblerX64::inc64(AbsoluteAddress dest) +{ + if (X86Encoding::IsAddressImmediate(dest.addr)) { + asMasm().addPtr(Imm32(1), dest); + } else { + ScratchRegisterScope scratch(asMasm()); + mov(ImmPtr(dest.addr), scratch); + asMasm().addPtr(Imm32(1), Address(scratch, 0)); + } +} + +void +MacroAssemblerX64::incrementInt32Value(const Address& addr) +{ + asMasm().addPtr(Imm32(1), addr); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/x64/MacroAssembler-x64.cpp b/js/src/jit/x64/MacroAssembler-x64.cpp index ca88dcac95eb..c72b6b35dd51 100644 --- a/js/src/jit/x64/MacroAssembler-x64.cpp +++ b/js/src/jit/x64/MacroAssembler-x64.cpp @@ -265,7 +265,7 @@ MacroAssemblerX64::branchPtrInNurseryRange(Condition cond, Register ptr, Registe const Nursery& nursery = GetJitContext()->runtime->gcNursery(); movePtr(ImmWord(-ptrdiff_t(nursery.start())), scratch); - addPtr(ptr, scratch); + asMasm().addPtr(ptr, scratch); branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual, scratch, Imm32(nursery.nurserySize()), label); } @@ -287,7 +287,7 @@ MacroAssemblerX64::branchValueIsNurseryObject(Condition cond, ValueOperand value ScratchRegisterScope scratch(asMasm()); movePtr(ImmWord(-ptrdiff_t(start.asRawBits())), scratch); - addPtr(value.valueReg(), scratch); + asMasm().addPtr(value.valueReg(), scratch); branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual, scratch, Imm32(nursery.nurserySize()), label); } diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 7daccb75926e..ef699cf5289e 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -543,34 +543,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared // Common interface. ///////////////////////////////////////////////////////////////// - void addPtr(Register src, Register dest) { - addq(src, dest); - } - void addPtr(Imm32 imm, Register dest) { - addq(imm, dest); - } - void addPtr(Imm32 imm, const Address& dest) { - addq(imm, Operand(dest)); - } - void addPtr(Imm32 imm, const Operand& dest) { - addq(imm, dest); - } - void addPtr(ImmWord imm, Register dest) { - ScratchRegisterScope scratch(asMasm()); - MOZ_ASSERT(dest != scratch); - if ((intptr_t)imm.value <= INT32_MAX && (intptr_t)imm.value >= INT32_MIN) { - addq(Imm32((int32_t)imm.value), dest); - } else { - mov(imm, scratch); - addq(scratch, dest); - } - } - void addPtr(ImmPtr imm, Register dest) { - addPtr(ImmWord(uintptr_t(imm.value)), dest); - } - void addPtr(const Address& src, Register dest) { - addq(Operand(src), dest); - } void add64(Imm32 imm, Register64 dest) { addq(imm, dest.reg); } @@ -1351,19 +1323,9 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared vmulsd(Operand(ScratchReg, 0), dest, dest); } - void inc64(AbsoluteAddress dest) { - if (X86Encoding::IsAddressImmediate(dest.addr)) { - addPtr(Imm32(1), Operand(dest)); - } else { - ScratchRegisterScope scratch(asMasm()); - mov(ImmPtr(dest.addr), scratch); - addPtr(Imm32(1), Address(scratch, 0)); - } - } + inline void inc64(AbsoluteAddress dest); - void incrementInt32Value(const Address& addr) { - addPtr(Imm32(1), addr); - } + inline void incrementInt32Value(const Address& addr); // If source is a double, load it into dest. If source is int32, // convert it to double. Else, branch to failure. diff --git a/js/src/jit/x86-shared/MoveEmitter-x86-shared.cpp b/js/src/jit/x86-shared/MoveEmitter-x86-shared.cpp index c0714b2bad19..0ecb50815cc8 100644 --- a/js/src/jit/x86-shared/MoveEmitter-x86-shared.cpp +++ b/js/src/jit/x86-shared/MoveEmitter-x86-shared.cpp @@ -440,7 +440,8 @@ MoveEmitterX86::emitGeneralMove(const MoveOperand& from, const MoveOperand& to, // this clobbers FLAGS! masm.Push(from.base()); masm.Pop(toPopOperand(to)); - masm.addPtr(Imm32(from.disp()), toOperand(to)); + MOZ_ASSERT(to.isMemoryOrEffectiveAddress()); + masm.addPtr(Imm32(from.disp()), toAddress(to)); } } } diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index 75b8a74720ac..ce9f600b4c0f 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -16,6 +16,7 @@ namespace jit { //{{{ check_macroassembler_style // =============================================================== +// Logical functions void MacroAssembler::andPtr(Register src, Register dest) @@ -77,6 +78,42 @@ MacroAssembler::xorPtr(Imm32 imm, Register dest) // =============================================================== // Arithmetic functions +void +MacroAssembler::addPtr(Register src, Register dest) +{ + addl(src, dest); +} + +void +MacroAssembler::addPtr(Imm32 imm, Register dest) +{ + addl(imm, dest); +} + +void +MacroAssembler::addPtr(ImmWord imm, Register dest) +{ + addl(Imm32(imm.value), dest); +} + +void +MacroAssembler::addPtr(Imm32 imm, const Address& dest) +{ + addl(imm, Operand(dest)); +} + +void +MacroAssembler::addPtr(Imm32 imm, const AbsoluteAddress& dest) +{ + addl(imm, Operand(dest)); +} + +void +MacroAssembler::addPtr(const Address& src, Register dest) +{ + addl(Operand(src), dest); +} + void MacroAssembler::add64(Register64 src, Register64 dest) { diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index 86196998f0a4..55dcecda1680 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -355,7 +355,7 @@ MacroAssemblerX86::branchPtrInNurseryRange(Condition cond, Register ptr, Registe const Nursery& nursery = GetJitContext()->runtime->gcNursery(); movePtr(ImmWord(-ptrdiff_t(nursery.start())), temp); - addPtr(ptr, temp); + asMasm().addPtr(ptr, temp); branchPtr(cond == Assembler::Equal ? Assembler::Below : Assembler::AboveOrEqual, temp, Imm32(nursery.nurserySize()), label); } diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 0c41692bdac2..0be0fb6c1b8d 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -566,27 +566,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared // Common interface. ///////////////////////////////////////////////////////////////// - void addPtr(Register src, Register dest) { - add32(src, dest); - } - void addPtr(Imm32 imm, Register dest) { - add32(imm, dest); - } - void addPtr(ImmWord imm, Register dest) { - add32(Imm32(imm.value), dest); - } - void addPtr(ImmPtr imm, Register dest) { - addPtr(ImmWord(uintptr_t(imm.value)), dest); - } - void addPtr(Imm32 imm, const Address& dest) { - add32(imm, Operand(dest)); - } - void addPtr(Imm32 imm, const Operand& dest) { - add32(imm, dest); - } - void addPtr(const Address& src, Register dest) { - addl(Operand(src), dest); - } void add64(Imm32 imm, Register64 dest) { addl(imm, dest.low); adcl(Imm32(0), dest.high); From c49ef4f3bbac47113744d791a696d49692f96d87 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Thu, 17 Dec 2015 01:01:16 +0900 Subject: [PATCH 014/139] Bug 1229057 - Part 1 followup: Move addToStackPtr and dependent things to -inl.h. r=nbp --HG-- extra : rebase_source : 65c850df986c0ab856102f19a239f75273a2a124 --- js/src/jit/BaselineCompiler.cpp | 1 + js/src/jit/BaselineFrameInfo-inl.h | 41 ++++++++++++++++++++++++++++++ js/src/jit/BaselineFrameInfo.cpp | 3 +++ js/src/jit/BaselineFrameInfo.h | 22 ++-------------- js/src/jit/BaselineJIT.cpp | 1 + js/src/jit/MacroAssembler-inl.h | 16 ++++++++++++ js/src/jit/MacroAssembler.h | 6 ++--- 7 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 js/src/jit/BaselineFrameInfo-inl.h diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 4bd759987b3a..be68916253bc 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -26,6 +26,7 @@ #include "jsscriptinlines.h" +#include "jit/BaselineFrameInfo-inl.h" #include "jit/MacroAssembler-inl.h" #include "vm/Interpreter-inl.h" #include "vm/NativeObject-inl.h" diff --git a/js/src/jit/BaselineFrameInfo-inl.h b/js/src/jit/BaselineFrameInfo-inl.h new file mode 100644 index 000000000000..69987090457f --- /dev/null +++ b/js/src/jit/BaselineFrameInfo-inl.h @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef jit_BaselineFrameInfo_inl_h +#define jit_BaselineFrameInfo_inl_h + +namespace js { +namespace jit { + +void +FrameInfo::pop(StackAdjustment adjust) +{ + spIndex--; + StackValue* popped = &stack[spIndex]; + + if (adjust == AdjustStack && popped->kind() == StackValue::Stack) + masm.addToStackPtr(Imm32(sizeof(Value))); + // Assert when anything uses this value. + popped->reset(); +} + +void +FrameInfo::popn(uint32_t n, StackAdjustment adjust) +{ + uint32_t poppedStack = 0; + for (uint32_t i = 0; i < n; i++) { + if (peek(-1)->kind() == StackValue::Stack) + poppedStack++; + pop(DontAdjustStack); + } + if (adjust == AdjustStack && poppedStack > 0) + masm.addToStackPtr(Imm32(sizeof(Value) * poppedStack)); +} + +} // namespace jit +} // namespace js + +#endif /* jit_BaselineFrameInfo_inl_h */ diff --git a/js/src/jit/BaselineFrameInfo.cpp b/js/src/jit/BaselineFrameInfo.cpp index e285656a96f7..5f4cf8ee3c1b 100644 --- a/js/src/jit/BaselineFrameInfo.cpp +++ b/js/src/jit/BaselineFrameInfo.cpp @@ -10,6 +10,9 @@ # include "jit/BytecodeAnalysis.h" #endif +#include "jit/BaselineFrameInfo-inl.h" +#include "jit/MacroAssembler-inl.h" + using namespace js; using namespace js::jit; diff --git a/js/src/jit/BaselineFrameInfo.h b/js/src/jit/BaselineFrameInfo.h index 2866d372ba24..18af6d6ab0b6 100644 --- a/js/src/jit/BaselineFrameInfo.h +++ b/js/src/jit/BaselineFrameInfo.h @@ -223,26 +223,8 @@ class FrameInfo return const_cast(&stack[spIndex + index]); } - inline void pop(StackAdjustment adjust = AdjustStack) { - spIndex--; - StackValue* popped = &stack[spIndex]; - - if (adjust == AdjustStack && popped->kind() == StackValue::Stack) - masm.addToStackPtr(Imm32(sizeof(Value))); - - // Assert when anything uses this value. - popped->reset(); - } - inline void popn(uint32_t n, StackAdjustment adjust = AdjustStack) { - uint32_t poppedStack = 0; - for (uint32_t i = 0; i < n; i++) { - if (peek(-1)->kind() == StackValue::Stack) - poppedStack++; - pop(DontAdjustStack); - } - if (adjust == AdjustStack && poppedStack > 0) - masm.addToStackPtr(Imm32(sizeof(Value) * poppedStack)); - } + inline void pop(StackAdjustment adjust = AdjustStack); + inline void popn(uint32_t n, StackAdjustment adjust = AdjustStack); inline void push(const Value& val) { StackValue* sv = rawPush(); sv->setConstant(val); diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index cc1b66bbba28..5df070e44c52 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -23,6 +23,7 @@ #include "jsscriptinlines.h" #include "jit/JitFrames-inl.h" +#include "jit/MacroAssembler-inl.h" #include "vm/Stack-inl.h" using namespace js; diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h index 0ff8a4c9233f..06a89dc841c6 100644 --- a/js/src/jit/MacroAssembler-inl.h +++ b/js/src/jit/MacroAssembler-inl.h @@ -341,6 +341,22 @@ MacroAssembler::branchFunctionKind(Condition cond, JSFunction::FunctionKind kind branch32(cond, scratch, Imm32(bit), label); } +#ifndef JS_CODEGEN_ARM64 + +template void +MacroAssembler::addToStackPtr(T t) +{ + addPtr(t, getStackPointer()); +} + +template void +MacroAssembler::addStackPtrTo(T t) +{ + addPtr(getStackPointer(), t); +} + +#endif // !JS_CODEGEN_ARM64 + } // namespace jit } // namespace js diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 07a68b9b4eec..2ec0d5f01e34 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -1264,10 +1264,8 @@ class MacroAssembler : public MacroAssemblerSpecific // StackPointer manipulation functions. // On ARM64, the StackPointer is implemented as two synchronized registers. // Code shared across platforms must use these functions to be valid. - template - void addToStackPtr(T t) { addPtr(t, getStackPointer()); } - template - void addStackPtrTo(T t) { addPtr(getStackPointer(), t); } + template inline void addToStackPtr(T t); + template inline void addStackPtrTo(T t); template void subFromStackPtr(T t) { subPtr(t, getStackPointer()); } From 14d68e5bc7709cd49650bcf2701ca20705556105 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:02:17 +0900 Subject: [PATCH 015/139] Bug 1229057 - Part 2: Move MacroAssembler::add32 into generic macro assembler. r=nbp --HG-- extra : rebase_source : a543ea5547d2a40b834bf5cf8bd3aaee5e1177fe --- js/src/jit/MacroAssembler-inl.h | 9 +++++ js/src/jit/MacroAssembler.h | 12 +++---- js/src/jit/arm/MacroAssembler-arm-inl.h | 35 +++++++++++++++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 21 ----------- js/src/jit/arm/MacroAssembler-arm.h | 13 ++----- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 24 +++++++++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 16 --------- .../MacroAssembler-mips-shared-inl.h | 20 +++++++++++ js/src/jit/mips32/MacroAssembler-mips32-inl.h | 6 ++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 21 ----------- js/src/jit/mips32/MacroAssembler-mips32.h | 7 +--- js/src/jit/mips64/MacroAssembler-mips64-inl.h | 6 ++++ js/src/jit/mips64/MacroAssembler-mips64.cpp | 21 ----------- js/src/jit/mips64/MacroAssembler-mips64.h | 7 +--- js/src/jit/none/MacroAssembler-none.h | 1 - .../MacroAssembler-x86-shared-inl.h | 24 +++++++++++++ .../x86-shared/MacroAssembler-x86-shared.h | 14 +------- 17 files changed, 135 insertions(+), 122 deletions(-) diff --git a/js/src/jit/MacroAssembler-inl.h b/js/src/jit/MacroAssembler-inl.h index 06a89dc841c6..0c50b1d7470d 100644 --- a/js/src/jit/MacroAssembler-inl.h +++ b/js/src/jit/MacroAssembler-inl.h @@ -357,6 +357,15 @@ MacroAssembler::addStackPtrTo(T t) #endif // !JS_CODEGEN_ARM64 +void +MacroAssembler::bumpKey(Int32Key* key, int diff) +{ + if (key->isRegister()) + add32(Imm32(diff), key->reg()); + else + key->bumpConstant(diff); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 2ec0d5f01e34..2236e2511092 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -731,6 +731,11 @@ class MacroAssembler : public MacroAssemblerSpecific // =============================================================== // Arithmetic functions + inline void add32(Register src, Register dest) PER_SHARED_ARCH; + inline void add32(Imm32 imm, Register dest) PER_SHARED_ARCH; + inline void add32(Imm32 imm, const Address& dest) PER_SHARED_ARCH; + inline void add32(Imm32 imm, const AbsoluteAddress& dest) DEFINED_ON(x86_shared); + inline void addPtr(Register src, Register dest) PER_ARCH; inline void addPtr(Register src1, Register src2, Register dest) DEFINED_ON(arm64); inline void addPtr(Imm32 imm, Register dest) PER_ARCH; @@ -1012,12 +1017,7 @@ class MacroAssembler : public MacroAssemblerSpecific void branchIfNotInterpretedConstructor(Register fun, Register scratch, Label* label); - void bumpKey(Int32Key* key, int diff) { - if (key->isRegister()) - add32(Imm32(diff), key->reg()); - else - key->bumpConstant(diff); - } + inline void bumpKey(Int32Key* key, int diff); void storeKey(const Int32Key& key, const Address& dest) { if (key.isRegister()) diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 9b59ff749ebe..1c72e34a3522 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -138,6 +138,27 @@ MacroAssembler::xorPtr(Imm32 imm, Register dest) // =============================================================== // Arithmetic functions +void +MacroAssembler::add32(Register src, Register dest) +{ + ma_add(src, dest, SetCC); +} + +void +MacroAssembler::add32(Imm32 imm, Register dest) +{ + ma_add(imm, dest, SetCC); +} + +void +MacroAssembler::add32(Imm32 imm, const Address& dest) +{ + ScratchRegisterScope scratch(*this); + load32(dest, scratch); + ma_add(imm, scratch, SetCC); + store32(scratch, dest); +} + void MacroAssembler::addPtr(Register src, Register dest) { @@ -240,6 +261,20 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== +template +void +MacroAssemblerARMCompat::branchAdd32(Condition cond, T src, Register dest, Label* label) +{ + asMasm().add32(src, dest); + j(cond, label); +} + +void +MacroAssemblerARMCompat::incrementInt32Value(const Address& addr) +{ + asMasm().add32(Imm32(1), ToPayload(addr)); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 796d06457714..29a73cfd144d 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -1947,27 +1947,6 @@ MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic) // Exists for MIPS compatibility. } -void -MacroAssemblerARMCompat::add32(Register src, Register dest) -{ - ma_add(src, dest, SetCC); -} - -void -MacroAssemblerARMCompat::add32(Imm32 imm, Register dest) -{ - ma_add(imm, dest, SetCC); -} - -void -MacroAssemblerARMCompat::add32(Imm32 imm, const Address& dest) -{ - ScratchRegisterScope scratch(asMasm()); - load32(dest, scratch); - ma_add(imm, scratch, SetCC); - store32(scratch, dest); -} - void MacroAssemblerARMCompat::move32(Imm32 imm, Register dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 1f8a6c334a06..581e053504b6 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1185,14 +1185,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM // Common interface. ///////////////////////////////////////////////////////////////// public: - void add32(Register src, Register dest); - void add32(Imm32 imm, Register dest); - void add32(Imm32 imm, const Address& dest); - template - void branchAdd32(Condition cond, T src, Register dest, Label* label) { - add32(src, dest); - j(cond, label); - } + template inline void branchAdd32(Condition cond, T src, Register dest, Label* label); template void branchSub32(Condition cond, T src, Register dest, Label* label) { ma_sub(src, dest, SetCC); @@ -1629,9 +1622,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_mov(Imm32(0), reg, LeaveCC, Signed); } - void incrementInt32Value(const Address& addr) { - add32(Imm32(1), ToPayload(addr)); - } + inline void incrementInt32Value(const Address& addr); void cmp32(Register lhs, Imm32 rhs); void cmp32(Register lhs, Register rhs); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 04bb8c53480d..569e507f034e 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -150,6 +150,30 @@ MacroAssembler::xorPtr(Imm32 imm, Register dest) // =============================================================== // Arithmetic functions +void +MacroAssembler::add32(Register src, Register dest) +{ + Add(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(ARMRegister(src, 32))); +} + +void +MacroAssembler::add32(Imm32 imm, Register dest) +{ + Add(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(imm.value)); +} + +void +MacroAssembler::add32(Imm32 imm, const Address& dest) +{ + vixl::UseScratchRegisterScope temps(this); + const ARMRegister scratch32 = temps.AcquireW(); + MOZ_ASSERT(scratch32.asUnsized() != dest.base); + + Ldr(scratch32, MemOperand(ARMRegister(dest.base, 64), dest.offset)); + Add(scratch32, scratch32, Operand(imm.value)); + Str(scratch32, MemOperand(ARMRegister(dest.base, 64), dest.offset)); +} + void MacroAssembler::addPtr(Register src, Register dest) { diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 7f7b9c50edbc..4493a925f98a 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1326,22 +1326,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler doBaseIndex(ARMRegister(dest, 32), src, vixl::LDRH_w); } - void add32(Register src, Register dest) { - Add(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(ARMRegister(src, 32))); - } - void add32(Imm32 imm, Register dest) { - Add(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(imm.value)); - } - void add32(Imm32 imm, const Address& dest) { - vixl::UseScratchRegisterScope temps(this); - const ARMRegister scratch32 = temps.AcquireW(); - MOZ_ASSERT(scratch32.asUnsized() != dest.base); - - Ldr(scratch32, MemOperand(ARMRegister(dest.base, 64), dest.offset)); - Add(scratch32, scratch32, Operand(imm.value)); - Str(scratch32, MemOperand(ARMRegister(dest.base, 64), dest.offset)); - } - void adds32(Register src, Register dest) { Adds(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(ARMRegister(src, 32))); } diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index 554971307104..4b7d03bdad30 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -78,6 +78,26 @@ MacroAssembler::xor32(Imm32 imm, Register dest) // =============================================================== // Arithmetic instructions +void +MacroAssembler::add32(Register src, Register dest) +{ + as_addu(dest, dest, src); +} + +void +MacroAssembler::add32(Imm32 imm, Register dest) +{ + ma_addu(dest, dest, imm); +} + +void +MacroAssembler::add32(Imm32 imm, const Address& dest) +{ + load32(dest, SecondScratchReg); + ma_addu(SecondScratchReg, imm); + store32(SecondScratchReg, dest); +} + void MacroAssembler::addPtr(Imm32 imm, const Address& dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 21ffa9d3f730..0ebbb814c61d 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -149,6 +149,12 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== +void +MacroAssemblerMIPSCompat::incrementInt32Value(const Address& addr) +{ + asMasm().add32(Imm32(1), ToPayload(addr)); +} + void MacroAssemblerMIPSCompat::computeEffectiveAddress(const BaseIndex& address, Register dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index bb9e1171b412..30180e5c074c 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -812,27 +812,6 @@ MacroAssemblerMIPSCompat::buildOOLFakeExitFrame(void* fakeReturnAddr) return true; } -void -MacroAssemblerMIPSCompat::add32(Register src, Register dest) -{ - as_addu(dest, dest, src); -} - -void -MacroAssemblerMIPSCompat::add32(Imm32 imm, Register dest) -{ - ma_addu(dest, dest, imm); -} - -void - -MacroAssemblerMIPSCompat::add32(Imm32 imm, const Address& dest) -{ - load32(dest, SecondScratchReg); - ma_addu(SecondScratchReg, imm); - store32(SecondScratchReg, dest); -} - void MacroAssemblerMIPSCompat::subPtr(Register src, Register dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index a43ec5677d73..36dafb386f6f 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -1061,18 +1061,13 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS Register temp, Register valueTemp, Register offsetTemp, Register maskTemp, AnyRegister output); - void add32(Register src, Register dest); - void add32(Imm32 imm, Register dest); - void add32(Imm32 imm, const Address& dest); void add64(Imm32 imm, Register64 dest) { as_addiu(dest.low, dest.low, imm.value); as_sltiu(ScratchRegister, dest.low, imm.value); as_addu(dest.high, dest.high, ScratchRegister); } - void incrementInt32Value(const Address& addr) { - add32(Imm32(1), ToPayload(addr)); - } + inline void incrementInt32Value(const Address& addr); template void branchAdd32(Condition cond, T src, Register dest, Label* overflow) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index db7c9ec0c0b8..5e4dfc4a64e3 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -137,6 +137,12 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== +void +MacroAssemblerMIPS64Compat::incrementInt32Value(const Address& addr) +{ + asMasm().add32(Imm32(1), addr); +} + void MacroAssemblerMIPS64Compat::computeEffectiveAddress(const BaseIndex& address, Register dest) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 40662e32323d..fd315bfd6b29 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -897,27 +897,6 @@ MacroAssemblerMIPS64Compat::buildOOLFakeExitFrame(void* fakeReturnAddr) return true; } -void -MacroAssemblerMIPS64Compat::add32(Register src, Register dest) -{ - as_addu(dest, dest, src); -} - -void -MacroAssemblerMIPS64Compat::add32(Imm32 imm, Register dest) -{ - ma_addu(dest, dest, imm); -} - -void - -MacroAssemblerMIPS64Compat::add32(Imm32 imm, const Address& dest) -{ - load32(dest, SecondScratchReg); - ma_addu(SecondScratchReg, imm); - store32(SecondScratchReg, dest); -} - void MacroAssemblerMIPS64Compat::subPtr(Register src, Register dest) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index e80cb4f15dae..549b4065695b 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -1078,16 +1078,11 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 Register temp, Register valueTemp, Register offsetTemp, Register maskTemp, AnyRegister output); - void add32(Register src, Register dest); - void add32(Imm32 imm, Register dest); - void add32(Imm32 imm, const Address& dest); void add64(Imm32 imm, Register64 dest) { ma_daddu(dest.reg, imm); } - void incrementInt32Value(const Address& addr) { - add32(Imm32(1), addr); - } + inline void incrementInt32Value(const Address& addr); template void branchAdd32(Condition cond, T src, Register dest, Label* overflow) { diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index c97449b5f3c1..4442baa25d45 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -234,7 +234,6 @@ class MacroAssemblerNone : public Assembler template void cmpPtrSet(Condition, T, S, Register) { MOZ_CRASH(); } template void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); } - template void add32(T, S) { MOZ_CRASH(); } template void add64(T, S) { MOZ_CRASH(); } template void subPtr(T, S) { MOZ_CRASH(); } void neg32(Register) { MOZ_CRASH(); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index d7332ae4b502..28067958c578 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -79,6 +79,30 @@ MacroAssembler::xor32(Imm32 imm, Register dest) // =============================================================== // Arithmetic instructions +void +MacroAssembler::add32(Register src, Register dest) +{ + addl(src, dest); +} + +void +MacroAssembler::add32(Imm32 imm, Register dest) +{ + addl(imm, dest); +} + +void +MacroAssembler::add32(Imm32 imm, const Address& dest) +{ + addl(imm, Operand(dest)); +} + +void +MacroAssembler::add32(Imm32 imm, const AbsoluteAddress& dest) +{ + addl(imm, Operand(dest)); +} + void MacroAssembler::sub32(Register src, Register dest) { diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index 6b889daac869..ac5f1bd15092 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -208,21 +208,9 @@ class MacroAssemblerX86Shared : public Assembler CodeOffset cmp32WithPatch(Register lhs, Imm32 rhs) { return cmplWithPatch(rhs, lhs); } - void add32(Register src, Register dest) { - addl(src, dest); - } - void add32(Imm32 imm, Register dest) { - addl(imm, dest); - } - void add32(Imm32 imm, const Operand& dest) { - addl(imm, dest); - } - void add32(Imm32 imm, const Address& dest) { - addl(imm, Operand(dest)); - } template void branchAdd32(Condition cond, T src, Register dest, Label* label) { - add32(src, dest); + addl(src, dest); j(cond, label); } template From d6e2f44a5423b82063d54725acfcf4f2fcd2c1ec Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:02:24 +0900 Subject: [PATCH 016/139] Bug 1229057 - Part 3: Move MacroAssembler::add64 into generic macro assembler. r=nbp --HG-- extra : rebase_source : d410daad40366767d5bdab36cc5696806f6e7c52 --- js/src/jit/MacroAssembler.h | 5 +++-- js/src/jit/arm/MacroAssembler-arm-inl.h | 7 +++++++ js/src/jit/arm/MacroAssembler-arm.h | 4 ---- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 6 ++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 3 --- js/src/jit/mips32/MacroAssembler-mips32-inl.h | 8 ++++++++ js/src/jit/mips32/MacroAssembler-mips32.h | 6 ------ js/src/jit/mips64/MacroAssembler-mips64-inl.h | 6 ++++++ js/src/jit/mips64/MacroAssembler-mips64.h | 4 ---- js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x64/MacroAssembler-x64-inl.h | 6 ++++++ js/src/jit/x64/MacroAssembler-x64.h | 3 --- js/src/jit/x86/MacroAssembler-x86-inl.h | 7 +++++++ js/src/jit/x86/MacroAssembler-x86.h | 4 ---- 14 files changed, 43 insertions(+), 27 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 2236e2511092..41d894605c08 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -746,12 +746,13 @@ class MacroAssembler : public MacroAssemblerSpecific inline void addPtr(Imm32 imm, const AbsoluteAddress& dest) DEFINED_ON(x86, x64); inline void addPtr(const Address& src, Register dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); + inline void add64(Register64 src, Register64 dest) PER_ARCH; + inline void add64(Imm32 imm, Register64 dest) PER_ARCH; + inline void sub32(const Address& src, Register dest) PER_SHARED_ARCH; inline void sub32(Register src, Register dest) PER_SHARED_ARCH; inline void sub32(Imm32 imm, Register dest) PER_SHARED_ARCH; - inline void add64(Register64 src, Register64 dest) PER_ARCH; - // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 1c72e34a3522..f5ed90df05a5 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -201,6 +201,13 @@ MacroAssembler::add64(Register64 src, Register64 dest) ma_adc(src.high, dest.high); } +void +MacroAssembler::add64(Imm32 imm, Register64 dest) +{ + ma_add(imm, dest.low, SetCC); + ma_adc(Imm32(0), dest.high, LeaveCC); +} + void MacroAssembler::sub32(Register src, Register dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 581e053504b6..374bbd239d18 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1192,10 +1192,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM j(cond, label); } - void add64(Imm32 imm, Register64 dest) { - ma_add(imm, dest.low, SetCC); - ma_adc(Imm32(0), dest.high, LeaveCC); - } void not32(Register reg); void move32(Imm32 imm, Register dest); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 569e507f034e..46cfb0b42770 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -233,6 +233,12 @@ MacroAssembler::add64(Register64 src, Register64 dest) addPtr(src.reg, dest.reg); } +void +MacroAssembler::add64(Imm32 imm, Register64 dest) +{ + Add(ARMRegister(dest.reg, 64), ARMRegister(dest.reg, 64), Operand(imm.value)); +} + void MacroAssembler::sub32(Imm32 imm, Register dest) { diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 4493a925f98a..cbb8f5c90e9b 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1341,9 +1341,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler Adds(scratch32, scratch32, Operand(imm.value)); Str(scratch32, MemOperand(ARMRegister(dest.base, 64), dest.offset)); } - void add64(Imm32 imm, Register64 dest) { - Add(ARMRegister(dest.reg, 64), ARMRegister(dest.reg, 64), Operand(imm.value)); - } void subs32(Imm32 imm, Register dest) { Subs(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(imm.value)); diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 0ebbb814c61d..3fa3931dd1ed 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -105,6 +105,14 @@ MacroAssembler::add64(Register64 src, Register64 dest) as_addu(dest.high, dest.high, ScratchRegister); } +void +MacroAssembler::add64(Imm32 imm, Register64 dest) +{ + as_addiu(dest.low, dest.low, imm.value); + as_sltiu(ScratchRegister, dest.low, imm.value); + as_addu(dest.high, dest.high, ScratchRegister); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 36dafb386f6f..fc7ba0517f3d 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -1061,12 +1061,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS Register temp, Register valueTemp, Register offsetTemp, Register maskTemp, AnyRegister output); - void add64(Imm32 imm, Register64 dest) { - as_addiu(dest.low, dest.low, imm.value); - as_sltiu(ScratchRegister, dest.low, imm.value); - as_addu(dest.high, dest.high, ScratchRegister); - } - inline void incrementInt32Value(const Address& addr); template diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index 5e4dfc4a64e3..8971d107de82 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -101,6 +101,12 @@ MacroAssembler::add64(Register64 src, Register64 dest) addPtr(src.reg, dest.reg); } +void +MacroAssembler::add64(Imm32 imm, Register64 dest) +{ + ma_daddu(dest.reg, imm); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 549b4065695b..d11f1ab36b8e 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -1078,10 +1078,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 Register temp, Register valueTemp, Register offsetTemp, Register maskTemp, AnyRegister output); - void add64(Imm32 imm, Register64 dest) { - ma_daddu(dest.reg, imm); - } - inline void incrementInt32Value(const Address& addr); template diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 4442baa25d45..b5c1b82eb54b 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -234,7 +234,6 @@ class MacroAssemblerNone : public Assembler template void cmpPtrSet(Condition, T, S, Register) { MOZ_CRASH(); } template void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); } - template void add64(T, S) { MOZ_CRASH(); } template void subPtr(T, S) { MOZ_CRASH(); } void neg32(Register) { MOZ_CRASH(); } void mulBy3(Register, Register) { MOZ_CRASH(); } diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index f5400ca9e7fb..8a7457a52640 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -124,6 +124,12 @@ MacroAssembler::add64(Register64 src, Register64 dest) addq(src.reg, dest.reg); } +void +MacroAssembler::add64(Imm32 imm, Register64 dest) +{ + addq(imm, dest.reg); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index ef699cf5289e..452f685820fd 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -543,9 +543,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared // Common interface. ///////////////////////////////////////////////////////////////// - void add64(Imm32 imm, Register64 dest) { - addq(imm, dest.reg); - } void subPtr(Imm32 imm, Register dest) { subq(imm, dest); } diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index ce9f600b4c0f..8390726f4649 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -121,6 +121,13 @@ MacroAssembler::add64(Register64 src, Register64 dest) adcl(src.high, dest.high); } +void +MacroAssembler::add64(Imm32 imm, Register64 dest) +{ + addl(imm, dest.low); + adcl(Imm32(0), dest.high); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 0be0fb6c1b8d..925009e700c2 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -566,10 +566,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared // Common interface. ///////////////////////////////////////////////////////////////// - void add64(Imm32 imm, Register64 dest) { - addl(imm, dest.low); - adcl(Imm32(0), dest.high); - } void subPtr(Imm32 imm, Register dest) { subl(imm, dest); } From 8a004143359834b761ad4c164835ad0950cd0152 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:02:36 +0900 Subject: [PATCH 017/139] Bug 1229057 - Part 4: Move MacroAssembler::addFloat32 into generic macro assembler. r=h4writer --HG-- extra : rebase_source : c5dcc3de127084f6964ec37f40ff741152e68837 --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h | 6 ++++++ js/src/jit/x86-shared/MacroAssembler-x86-shared.h | 3 --- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 41d894605c08..a69951100bc6 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -749,6 +749,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void add64(Register64 src, Register64 dest) PER_ARCH; inline void add64(Imm32 imm, Register64 dest) PER_ARCH; + inline void addFloat32(FloatRegister src, FloatRegister dest) DEFINED_ON(x86_shared); + inline void sub32(const Address& src, Register dest) PER_SHARED_ARCH; inline void sub32(Register src, Register dest) PER_SHARED_ARCH; inline void sub32(Imm32 imm, Register dest) PER_SHARED_ARCH; diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index 28067958c578..9d3c899802b1 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -103,6 +103,12 @@ MacroAssembler::add32(Imm32 imm, const AbsoluteAddress& dest) addl(imm, Operand(dest)); } +void +MacroAssembler::addFloat32(FloatRegister src, FloatRegister dest) +{ + vaddss(src, dest, dest); +} + void MacroAssembler::sub32(Register src, Register dest) { diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index ac5f1bd15092..fa191d794fba 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -934,9 +934,6 @@ class MacroAssemblerX86Shared : public Assembler void divDouble(FloatRegister src, FloatRegister dest) { vdivsd(src, dest, dest); } - void addFloat32(FloatRegister src, FloatRegister dest) { - vaddss(src, dest, dest); - } void convertFloat32ToDouble(FloatRegister src, FloatRegister dest) { vcvtss2sd(src, dest, dest); } From 28b6ffeed183869a2c2016b1d027f35cf17f0d05 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:02:44 +0900 Subject: [PATCH 018/139] Bug 1229057 - Part 5: Remove unused MacroAssemblerX86::addConstantFloat32. r=h4writer --HG-- extra : rebase_source : a707c3916e94131315e6782b35334bed7c0fb10c --- js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x86/MacroAssembler-x86.cpp | 10 ---------- js/src/jit/x86/MacroAssembler-x86.h | 1 - 3 files changed, 12 deletions(-) diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index b5c1b82eb54b..b85fe747f115 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -412,7 +412,6 @@ class MacroAssemblerNone : public Assembler void loadConstantDouble(double, FloatRegister) { MOZ_CRASH(); } void addConstantDouble(double, FloatRegister) { MOZ_CRASH(); } void loadConstantFloat32(float, FloatRegister) { MOZ_CRASH(); } - void addConstantFloat32(float, FloatRegister) { MOZ_CRASH(); } Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); } Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); } void branchTestInt32Truthy(bool, ValueOperand, Label*) { MOZ_CRASH(); } diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index 55dcecda1680..79e594a2308e 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -124,16 +124,6 @@ MacroAssemblerX86::loadConstantFloat32(float f, FloatRegister dest) propagateOOM(flt->uses.append(CodeOffset(masm.size()))); } -void -MacroAssemblerX86::addConstantFloat32(float f, FloatRegister dest) -{ - Float* flt = getFloat(f); - if (!flt) - return; - masm.vaddss_mr(nullptr, dest.encoding(), dest.encoding()); - propagateOOM(flt->uses.append(CodeOffset(masm.size()))); -} - void MacroAssemblerX86::loadConstantInt32x4(const SimdConstant& v, FloatRegister dest) { diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 925009e700c2..7f80a1626150 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -988,7 +988,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void loadConstantDouble(double d, FloatRegister dest); void addConstantDouble(double d, FloatRegister dest); void loadConstantFloat32(float f, FloatRegister dest); - void addConstantFloat32(float f, FloatRegister dest); void loadConstantInt32x4(const SimdConstant& v, FloatRegister dest); void loadConstantFloat32x4(const SimdConstant& v, FloatRegister dest); From d3eeca5f43a8ee5be9dda5568e7879ae2bc44789 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:02:52 +0900 Subject: [PATCH 019/139] Bug 1229057 - Part 6: Move MacroAssembler::addDouble into generic macro assembler. r=jandem --HG-- extra : rebase_source : b2ba8eb7e1b98be1fc979fc815e7724309a90cd8 --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 8 +------- js/src/jit/arm/MacroAssembler-arm.h | 1 - js/src/jit/arm64/MacroAssembler-arm64-inl.h | 6 ++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 3 --- js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h | 6 ++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 8 +------- js/src/jit/mips32/MacroAssembler-mips32.h | 1 - js/src/jit/mips64/MacroAssembler-mips64.cpp | 8 +------- js/src/jit/mips64/MacroAssembler-mips64.h | 1 - js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h | 6 ++++++ js/src/jit/x86-shared/MacroAssembler-x86-shared.h | 3 --- js/src/jit/x86/MacroAssembler-x86.cpp | 2 +- 15 files changed, 30 insertions(+), 32 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index a69951100bc6..9b6b83007dcf 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -751,6 +751,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void addFloat32(FloatRegister src, FloatRegister dest) DEFINED_ON(x86_shared); + inline void addDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; + inline void sub32(const Address& src, Register dest) PER_SHARED_ARCH; inline void sub32(Register src, Register dest) PER_SHARED_ARCH; inline void sub32(Imm32 imm, Register dest) PER_SHARED_ARCH; diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index f5ed90df05a5..b9bfa00486f6 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -208,6 +208,12 @@ MacroAssembler::add64(Imm32 imm, Register64 dest) ma_adc(Imm32(0), dest.high, LeaveCC); } +void +MacroAssembler::addDouble(FloatRegister src, FloatRegister dest) +{ + ma_vadd(dest, src, dest); +} + void MacroAssembler::sub32(Register src, Register dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 29a73cfd144d..feddcde8497b 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -99,7 +99,7 @@ MacroAssemblerARMCompat::convertUInt64ToDouble(Register64 src, Register temp, Fl loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg); mulDouble(ScratchDoubleReg, dest); convertUInt32ToDouble(src.low, ScratchDoubleReg); - addDouble(ScratchDoubleReg, dest); + asMasm().addDouble(ScratchDoubleReg, dest); } void @@ -246,12 +246,6 @@ MacroAssemblerARM::convertInt32ToFloat32(const Address& src, FloatRegister dest) as_vcvt(dest, VFPRegister(scratch).sintOverlay()); } -void -MacroAssemblerARM::addDouble(FloatRegister src, FloatRegister dest) -{ - ma_vadd(dest, src, dest); -} - void MacroAssemblerARM::subDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 374bbd239d18..b49687c4ec2a 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -97,7 +97,6 @@ class MacroAssemblerARM : public Assembler void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void addDouble(FloatRegister src, FloatRegister dest); void subDouble(FloatRegister src, FloatRegister dest); void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 46cfb0b42770..9af9a8c6b343 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -239,6 +239,12 @@ MacroAssembler::add64(Imm32 imm, Register64 dest) Add(ARMRegister(dest.reg, 64), ARMRegister(dest.reg, 64), Operand(imm.value)); } +void +MacroAssembler::addDouble(FloatRegister src, FloatRegister dest) +{ + fadd(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); +} + void MacroAssembler::sub32(Imm32 imm, Register dest) { diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index cbb8f5c90e9b..9aca396876f6 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1238,9 +1238,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void negateFloat(FloatRegister reg) { fneg(ARMFPRegister(reg, 32), ARMFPRegister(reg, 32)); } - void addDouble(FloatRegister src, FloatRegister dest) { - fadd(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); - } void subDouble(FloatRegister src, FloatRegister dest) { fsub(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); } diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index 4b7d03bdad30..e1e98afe8117 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -113,6 +113,12 @@ MacroAssembler::addPtr(const Address& src, Register dest) addPtr(ScratchRegister, dest); } +void +MacroAssembler::addDouble(FloatRegister src, FloatRegister dest) +{ + as_addd(dest, dest, src); +} + void MacroAssembler::sub32(Register src, Register dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 30180e5c074c..289a0be02ff1 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -131,7 +131,7 @@ MacroAssemblerMIPSCompat::convertUInt64ToDouble(Register64 src, Register temp, F loadConstantDouble(TO_DOUBLE_HIGH_SCALE, ScratchDoubleReg); mulDouble(ScratchDoubleReg, dest); convertUInt32ToDouble(src.low, ScratchDoubleReg); - addDouble(ScratchDoubleReg, dest); + asMasm().addDouble(ScratchDoubleReg, dest); } void @@ -263,12 +263,6 @@ MacroAssemblerMIPSCompat::convertInt32ToFloat32(const Address& src, FloatRegiste as_cvtsw(dest, dest); } -void -MacroAssemblerMIPSCompat::addDouble(FloatRegister src, FloatRegister dest) -{ - as_addd(dest, dest, src); -} - void MacroAssemblerMIPSCompat::subDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index fc7ba0517f3d..aa64ff6cc2ba 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -175,7 +175,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void addDouble(FloatRegister src, FloatRegister dest); void subDouble(FloatRegister src, FloatRegister dest); void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index fd315bfd6b29..80cd0a8e56a4 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -88,7 +88,7 @@ MacroAssemblerMIPS64Compat::convertUInt64ToDouble(Register64 src, Register temp, ma_or(ScratchRegister, SecondScratchReg); as_dmtc1(ScratchRegister, dest); as_cvtdl(dest, dest); - addDouble(dest, dest); + asMasm().addDouble(dest, dest); ma_b(&done, ShortJump); bind(&positive); @@ -227,12 +227,6 @@ MacroAssemblerMIPS64Compat::convertInt32ToFloat32(const Address& src, FloatRegis as_cvtsw(dest, dest); } -void -MacroAssemblerMIPS64Compat::addDouble(FloatRegister src, FloatRegister dest) -{ - as_addd(dest, dest, src); -} - void MacroAssemblerMIPS64Compat::subDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index d11f1ab36b8e..2433c9477a00 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -185,7 +185,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void addDouble(FloatRegister src, FloatRegister dest); void subDouble(FloatRegister src, FloatRegister dest); void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index b85fe747f115..72ba4b6b24bc 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -240,7 +240,6 @@ class MacroAssemblerNone : public Assembler void mul64(Imm64, const Register64&) { MOZ_CRASH(); } void negateDouble(FloatRegister) { MOZ_CRASH(); } - void addDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } void subDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } void mulDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } void divDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index 9d3c899802b1..7a1792abb37d 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -109,6 +109,12 @@ MacroAssembler::addFloat32(FloatRegister src, FloatRegister dest) vaddss(src, dest, dest); } +void +MacroAssembler::addDouble(FloatRegister src, FloatRegister dest) +{ + vaddsd(src, dest, dest); +} + void MacroAssembler::sub32(Register src, Register dest) { diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index fa191d794fba..3ac1a01688d6 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -922,9 +922,6 @@ class MacroAssemblerX86Shared : public Assembler // XOR the float in a float register with -0.0. vxorps(scratch, reg, reg); // s ^ 0x80000000 } - void addDouble(FloatRegister src, FloatRegister dest) { - vaddsd(src, dest, dest); - } void subDouble(FloatRegister src, FloatRegister dest) { vsubsd(src, dest, dest); } diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index 79e594a2308e..92f5e0597cff 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -42,7 +42,7 @@ MacroAssemblerX86::convertUInt64ToDouble(Register64 src, Register temp, FloatReg loadDouble(Address(temp, 0), ScratchDoubleReg); mulDouble(ScratchDoubleReg, dest); convertUInt32ToDouble(src.low, ScratchDoubleReg); - addDouble(ScratchDoubleReg, dest); + asMasm().addDouble(ScratchDoubleReg, dest); return; } From eb5bd433fbd5a18ac684f519f98f5eb5265ed2fd Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:02:59 +0900 Subject: [PATCH 020/139] Bug 1229057 - Part 7: Move MacroAssembler::addConstantDouble into generic macro assembler. r=jandem --HG-- extra : rebase_source : c15b6f9a6256e08367faf6809cf2d8e01299828e --- js/src/jit/MacroAssembler.h | 1 + js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x86/MacroAssembler-x86-inl.h | 33 +++++++++++++++++++++++++ js/src/jit/x86/MacroAssembler-x86.cpp | 10 -------- js/src/jit/x86/MacroAssembler-x86.h | 18 ++------------ 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 9b6b83007dcf..eaee225575f2 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -752,6 +752,7 @@ class MacroAssembler : public MacroAssemblerSpecific inline void addFloat32(FloatRegister src, FloatRegister dest) DEFINED_ON(x86_shared); inline void addDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; + inline void addConstantDouble(double d, FloatRegister dest) DEFINED_ON(x86); inline void sub32(const Address& src, Register dest) PER_SHARED_ARCH; inline void sub32(Register src, Register dest) PER_SHARED_ARCH; diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 72ba4b6b24bc..1e639903fa58 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -409,7 +409,6 @@ class MacroAssemblerNone : public Assembler void int32ValueToFloat32(ValueOperand, FloatRegister) { MOZ_CRASH(); } void loadConstantDouble(double, FloatRegister) { MOZ_CRASH(); } - void addConstantDouble(double, FloatRegister) { MOZ_CRASH(); } void loadConstantFloat32(float, FloatRegister) { MOZ_CRASH(); } Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); } Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); } diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index 8390726f4649..c4246efbf6c3 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -128,6 +128,16 @@ MacroAssembler::add64(Imm32 imm, Register64 dest) adcl(Imm32(0), dest.high); } +void +MacroAssembler::addConstantDouble(double d, FloatRegister dest) +{ + Double* dbl = getDouble(d); + if (!dbl) + return; + masm.vaddsd_mr(nullptr, dest.encoding(), dest.encoding()); + propagateOOM(dbl->uses.append(CodeOffset(masm.size()))); +} + // =============================================================== // Shift functions @@ -166,6 +176,29 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== +// Note: this function clobbers the source register. +void +MacroAssemblerX86::convertUInt32ToDouble(Register src, FloatRegister dest) +{ + // src is [0, 2^32-1] + subl(Imm32(0x80000000), src); + + // Now src is [-2^31, 2^31-1] - int range, but not the same value. + convertInt32ToDouble(src, dest); + + // dest is now a double with the int range. + // correct the double value by adding 0x80000000. + asMasm().addConstantDouble(2147483648.0, dest); +} + +// Note: this function clobbers the source register. +void +MacroAssemblerX86::convertUInt32ToFloat32(Register src, FloatRegister dest) +{ + convertUInt32ToDouble(src, dest); + convertDoubleToFloat32(dest, dest); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index 92f5e0597cff..c1e1f1b4d167 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -102,16 +102,6 @@ MacroAssemblerX86::loadConstantDouble(double d, FloatRegister dest) propagateOOM(dbl->uses.append(CodeOffset(masm.size()))); } -void -MacroAssemblerX86::addConstantDouble(double d, FloatRegister dest) -{ - Double* dbl = getDouble(d); - if (!dbl) - return; - masm.vaddsd_mr(nullptr, dest.encoding(), dest.encoding()); - propagateOOM(dbl->uses.append(CodeOffset(masm.size()))); -} - void MacroAssemblerX86::loadConstantFloat32(float f, FloatRegister dest) { diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 7f80a1626150..3ac987446685 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -986,7 +986,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared } void loadConstantDouble(double d, FloatRegister dest); - void addConstantDouble(double d, FloatRegister dest); void loadConstantFloat32(float f, FloatRegister dest); void loadConstantInt32x4(const SimdConstant& v, FloatRegister dest); void loadConstantFloat32x4(const SimdConstant& v, FloatRegister dest); @@ -1072,23 +1071,10 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared } // Note: this function clobbers the source register. - void convertUInt32ToDouble(Register src, FloatRegister dest) { - // src is [0, 2^32-1] - subl(Imm32(0x80000000), src); - - // Now src is [-2^31, 2^31-1] - int range, but not the same value. - convertInt32ToDouble(src, dest); - - // dest is now a double with the int range. - // correct the double value by adding 0x80000000. - addConstantDouble(2147483648.0, dest); - } + inline void convertUInt32ToDouble(Register src, FloatRegister dest); // Note: this function clobbers the source register. - void convertUInt32ToFloat32(Register src, FloatRegister dest) { - convertUInt32ToDouble(src, dest); - convertDoubleToFloat32(dest, dest); - } + inline void convertUInt32ToFloat32(Register src, FloatRegister dest); void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); From 53d753e8f1ad5a512b7e11174dda3a8ccbcd2707 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:03:07 +0900 Subject: [PATCH 021/139] Bug 1229057 - Part 8: Move MacroAssembler::subPtr into generic macro assembler. r=lth --HG-- extra : rebase_source : 0116bcf03087f7c210812af15a63b7d407c813f5 --- js/src/jit/MacroAssembler.h | 5 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 36 ++++++++++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 29 ----------- js/src/jit/arm/MacroAssembler-arm.h | 9 +--- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 49 +++++++++++++++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 29 +---------- .../MacroAssembler-mips-shared-inl.h | 15 ++++++ js/src/jit/mips32/MacroAssembler-mips32-inl.h | 19 +++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 37 ++------------ js/src/jit/mips32/MacroAssembler-mips32.h | 10 +--- js/src/jit/mips64/MacroAssembler-mips64-inl.h | 19 +++++++ js/src/jit/mips64/MacroAssembler-mips64.cpp | 35 ++----------- js/src/jit/mips64/MacroAssembler-mips64.h | 10 +--- js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x64/MacroAssembler-x64-inl.h | 24 +++++++++ js/src/jit/x64/MacroAssembler-x64.h | 14 +----- js/src/jit/x86/MacroAssembler-x86-inl.h | 24 +++++++++ js/src/jit/x86/MacroAssembler-x86.h | 14 +----- 18 files changed, 207 insertions(+), 172 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index eaee225575f2..01f475e18a81 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -758,6 +758,11 @@ class MacroAssembler : public MacroAssemblerSpecific inline void sub32(Register src, Register dest) PER_SHARED_ARCH; inline void sub32(Imm32 imm, Register dest) PER_SHARED_ARCH; + inline void subPtr(Register src, Register dest) PER_ARCH; + inline void subPtr(Register src, const Address& dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); + inline void subPtr(Imm32 imm, Register dest) PER_ARCH; + inline void subPtr(const Address& addr, Register dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index b9bfa00486f6..0e702bd53a35 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -234,6 +234,35 @@ MacroAssembler::sub32(const Address& src, Register dest) ma_sub(scratch, dest, SetCC); } +void +MacroAssembler::subPtr(Register src, Register dest) +{ + ma_sub(src, dest); +} + +void +MacroAssembler::subPtr(Register src, const Address& dest) +{ + ScratchRegisterScope scratch(*this); + loadPtr(dest, scratch); + ma_sub(src, scratch); + storePtr(scratch, dest); +} + +void +MacroAssembler::subPtr(Imm32 imm, Register dest) +{ + ma_sub(imm, dest); +} + +void +MacroAssembler::subPtr(const Address& addr, Register dest) +{ + ScratchRegisterScope scratch(*this); + loadPtr(addr, scratch); + ma_sub(scratch, dest); +} + // =============================================================== // Shift functions @@ -288,6 +317,13 @@ MacroAssemblerARMCompat::incrementInt32Value(const Address& addr) asMasm().add32(Imm32(1), ToPayload(addr)); } +void +MacroAssemblerARMCompat::decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) +{ + asMasm().subPtr(imm, lhs); + branch32(cond, lhs, Imm32(0), label); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index feddcde8497b..08c259f911cb 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -2585,35 +2585,6 @@ MacroAssemblerARMCompat::setStackArg(Register reg, uint32_t arg) } -void -MacroAssemblerARMCompat::subPtr(Imm32 imm, const Register dest) -{ - ma_sub(imm, dest); -} - -void -MacroAssemblerARMCompat::subPtr(const Address& addr, const Register dest) -{ - ScratchRegisterScope scratch(asMasm()); - loadPtr(addr, scratch); - ma_sub(scratch, dest); -} - -void -MacroAssemblerARMCompat::subPtr(Register src, Register dest) -{ - ma_sub(src, dest); -} - -void -MacroAssemblerARMCompat::subPtr(Register src, const Address& dest) -{ - ScratchRegisterScope scratch(asMasm()); - loadPtr(dest, scratch); - ma_sub(src, scratch); - storePtr(scratch, dest); -} - void MacroAssemblerARMCompat::compareDouble(FloatRegister lhs, FloatRegister rhs) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index b49687c4ec2a..2dba6dadf581 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -981,10 +981,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void branchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) { branch32(cond, lhs, imm, label); } - void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) { - subPtr(imm, lhs); - branch32(cond, lhs, Imm32(0), label); - } + inline void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label); void branchTest64(Condition cond, Register64 lhs, Register64 rhs, Register temp, Label* label); void moveValue(const Value& val, Register type, Register data); @@ -1635,10 +1632,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void cmpPtr(const Address& lhs, ImmGCPtr rhs); void cmpPtr(const Address& lhs, Imm32 rhs); - void subPtr(Imm32 imm, const Register dest); - void subPtr(const Address& addr, const Register dest); - void subPtr(Register src, Register dest); - void subPtr(Register src, const Address& dest); void mulBy3(const Register& src, const Register& dest) { as_add(dest, src, lsl(src, 1)); } diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 9af9a8c6b343..2ca8c381006c 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -267,6 +267,41 @@ MacroAssembler::sub32(const Address& src, Register dest) Sub(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(scratch32)); } +void +MacroAssembler::subPtr(Register src, Register dest) +{ + Sub(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(ARMRegister(src, 64))); +} + +void +MacroAssembler::subPtr(Register src, const Address& dest) +{ + vixl::UseScratchRegisterScope temps(this); + const ARMRegister scratch64 = temps.AcquireX(); + MOZ_ASSERT(scratch64.asUnsized() != dest.base); + + Ldr(scratch64, MemOperand(ARMRegister(dest.base, 64), dest.offset)); + Sub(scratch64, scratch64, Operand(ARMRegister(src, 64))); + Str(scratch64, MemOperand(ARMRegister(dest.base, 64), dest.offset)); +} + +void +MacroAssembler::subPtr(Imm32 imm, Register dest) +{ + Sub(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(imm.value)); +} + +void +MacroAssembler::subPtr(const Address& addr, Register dest) +{ + vixl::UseScratchRegisterScope temps(this); + const ARMRegister scratch64 = temps.AcquireX(); + MOZ_ASSERT(scratch64.asUnsized() != addr.base); + + Ldr(scratch64, MemOperand(ARMRegister(addr.base, 64), addr.offset)); + Sub(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(scratch64)); +} + // =============================================================== // Shift functions @@ -323,6 +358,20 @@ MacroAssemblerCompat::addStackPtrTo(T t) asMasm().addPtr(getStackPointer(), t); } +template +void +MacroAssemblerCompat::subFromStackPtr(T t) +{ + asMasm().subPtr(t, getStackPointer()); syncStackPtr(); +} + +template +void +MacroAssemblerCompat::subStackPtrFrom(T t) +{ + asMasm().subPtr(getStackPointer(), t); +} + template void MacroAssemblerCompat::andToStackPtr(T t) diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 9aca396876f6..2537d684b761 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1032,10 +1032,8 @@ class MacroAssemblerCompat : public vixl::MacroAssembler template void addToStackPtr(T t); template void addStackPtrTo(T t); - template - void subFromStackPtr(T t) { subPtr(t, getStackPointer()); syncStackPtr(); } - template - void subStackPtrFrom(T t) { subPtr(getStackPointer(), t); } + template inline void subFromStackPtr(T t); + template inline void subStackPtrFrom(T t); template void andToStackPtr(T t); template void andStackPtrTo(T t); @@ -1346,29 +1344,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler Subs(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(ARMRegister(src, 32))); } - void subPtr(Imm32 imm, Register dest) { - Sub(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(imm.value)); - } - void subPtr(Register src, Register dest) { - Sub(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(ARMRegister(src, 64))); - } - void subPtr(const Address& addr, Register dest) { - vixl::UseScratchRegisterScope temps(this); - const ARMRegister scratch64 = temps.AcquireX(); - MOZ_ASSERT(scratch64.asUnsized() != addr.base); - - Ldr(scratch64, MemOperand(ARMRegister(addr.base, 64), addr.offset)); - Sub(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(scratch64)); - } - void subPtr(Register src, const Address& dest) { - vixl::UseScratchRegisterScope temps(this); - const ARMRegister scratch64 = temps.AcquireX(); - MOZ_ASSERT(scratch64.asUnsized() != dest.base); - - Ldr(scratch64, MemOperand(ARMRegister(dest.base, 64), dest.offset)); - Sub(scratch64, scratch64, Operand(ARMRegister(src, 64))); - Str(scratch64, MemOperand(ARMRegister(dest.base, 64), dest.offset)); - } void mul32(Register src1, Register src2, Register dest, Label* onOver, Label* onZero) { Smull(ARMRegister(dest, 64), ARMRegister(src1, 32), ARMRegister(src2, 32)); if (onOver) { diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index e1e98afe8117..48b96a8e0261 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -138,6 +138,21 @@ MacroAssembler::sub32(const Address& src, Register dest) as_subu(dest, dest, SecondScratchReg); } +void +MacroAssembler::subPtr(Register src, const Address& dest) +{ + loadPtr(dest, SecondScratchReg); + subPtr(src, SecondScratchReg); + storePtr(SecondScratchReg, dest); +} + +void +MacroAssembler::subPtr(const Address& addr, Register dest) +{ + loadPtr(addr, SecondScratchReg); + subPtr(SecondScratchReg, dest); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 3fa3931dd1ed..3ea88f84b060 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -113,6 +113,18 @@ MacroAssembler::add64(Imm32 imm, Register64 dest) as_addu(dest.high, dest.high, ScratchRegister); } +void +MacroAssembler::subPtr(Register src, Register dest) +{ + as_subu(dest, dest, src); +} + +void +MacroAssembler::subPtr(Imm32 imm, Register dest) +{ + ma_subu(dest, dest, imm); +} + // =============================================================== // Shift functions @@ -180,6 +192,13 @@ MacroAssemblerMIPSCompat::retn(Imm32 n) { as_nop(); } +void +MacroAssemblerMIPSCompat::decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) +{ + asMasm().subPtr(imm, lhs); + branchPtr(cond, lhs, Imm32(0), label); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 289a0be02ff1..230d11a19657 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -806,12 +806,6 @@ MacroAssemblerMIPSCompat::buildOOLFakeExitFrame(void* fakeReturnAddr) return true; } -void -MacroAssemblerMIPSCompat::subPtr(Register src, Register dest) -{ - as_subu(dest, dest, src); -} - void MacroAssemblerMIPSCompat::move32(Imm32 imm, Register dest) { @@ -1201,27 +1195,6 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) bind(&done); } -void -MacroAssemblerMIPSCompat::subPtr(Imm32 imm, const Register dest) -{ - ma_subu(dest, dest, imm); -} - -void -MacroAssemblerMIPSCompat::subPtr(const Address& addr, const Register dest) -{ - loadPtr(addr, SecondScratchReg); - subPtr(SecondScratchReg, dest); -} - -void -MacroAssemblerMIPSCompat::subPtr(Register src, const Address& dest) -{ - loadPtr(dest, SecondScratchReg); - subPtr(src, SecondScratchReg); - storePtr(SecondScratchReg, dest); -} - void MacroAssemblerMIPSCompat::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs, Label* label) @@ -2121,7 +2094,7 @@ void MacroAssemblerMIPSCompat::pushValue(ValueOperand val) { // Allocate stack slots for type and payload. One for each. - subPtr(Imm32(sizeof(Value)), StackPointer); + asMasm().subPtr(Imm32(sizeof(Value)), StackPointer); // Store type and payload. storeValue(val, Address(StackPointer, 0)); } @@ -2239,7 +2212,7 @@ void MacroAssemblerMIPSCompat::alignStackPointer() { movePtr(StackPointer, SecondScratchReg); - subPtr(Imm32(sizeof(uintptr_t)), StackPointer); + asMasm().subPtr(Imm32(sizeof(uintptr_t)), StackPointer); asMasm().andPtr(Imm32(~(ABIStackAlignment - 1)), StackPointer); storePtr(SecondScratchReg, Address(StackPointer, 0)); } @@ -2275,7 +2248,7 @@ MacroAssemblerMIPSCompat::handleFailureWithHandlerTail(void* handler) { // Reserve space for exception information. int size = (sizeof(ResumeFromException) + ABIStackAlignment) & ~(ABIStackAlignment - 1); - subPtr(Imm32(size), StackPointer); + asMasm().subPtr(Imm32(size), StackPointer); ma_move(a0, StackPointer); // Use a0 since it is a first function argument // Call the handler. @@ -2593,7 +2566,7 @@ void MacroAssembler::reserveStack(uint32_t amount) { if (amount) - subPtr(Imm32(amount), StackPointer); + asMasm().subPtr(Imm32(amount), StackPointer); adjustFrame(amount); } @@ -2609,7 +2582,7 @@ MacroAssembler::setupUnalignedABICall(Register scratch) ma_move(scratch, StackPointer); // Force sp to be aligned - subPtr(Imm32(sizeof(uintptr_t)), StackPointer); + asMasm().subPtr(Imm32(sizeof(uintptr_t)), StackPointer); ma_and(StackPointer, StackPointer, Imm32(~(ABIStackAlignment - 1))); storePtr(scratch, Address(StackPointer, 0)); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index aa64ff6cc2ba..af9cdc1d47b5 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -554,10 +554,7 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void branchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) { ma_b(lhs, imm, label, cond); } - void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) { - subPtr(imm, lhs); - branchPtr(cond, lhs, Imm32(0), label); - } + inline void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label); // higher level tag testing code Operand ToPayload(Operand base); @@ -1088,8 +1085,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS } } - void subPtr(Register src, Register dest); - void move32(Imm32 imm, Register dest); void move32(Register src, Register dest); void move64(Register64 src, Register64 dest) { @@ -1230,9 +1225,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void clampIntToUint8(Register reg); - void subPtr(Imm32 imm, const Register dest); - void subPtr(const Address& addr, const Register dest); - void subPtr(Register src, const Address& dest); void mulBy3(const Register& src, const Register& dest) { as_addu(dest, src, src); as_addu(dest, dest, src); diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index 8971d107de82..e4bf6b7dfc7f 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -107,6 +107,18 @@ MacroAssembler::add64(Imm32 imm, Register64 dest) ma_daddu(dest.reg, imm); } +void +MacroAssembler::subPtr(Register src, Register dest) +{ + as_dsubu(dest, dest, src); +} + +void +MacroAssembler::subPtr(Imm32 imm, Register dest) +{ + ma_dsubu(dest, dest, imm); +} + // =============================================================== // Shift functions @@ -167,6 +179,13 @@ MacroAssemblerMIPS64Compat::retn(Imm32 n) as_nop(); } +void +MacroAssemblerMIPS64Compat::decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) +{ + asMasm().subPtr(imm, lhs); + branchPtr(cond, lhs, Imm32(0), label); +} + } // namespace jit } // namespace js diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 80cd0a8e56a4..0d7522701ea8 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -891,12 +891,6 @@ MacroAssemblerMIPS64Compat::buildOOLFakeExitFrame(void* fakeReturnAddr) return true; } -void -MacroAssemblerMIPS64Compat::subPtr(Register src, Register dest) -{ - as_dsubu(dest, dest, src); -} - void MacroAssemblerMIPS64Compat::move32(Imm32 imm, Register dest) { @@ -1287,27 +1281,6 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) bind(&done); } -void -MacroAssemblerMIPS64Compat::subPtr(Imm32 imm, const Register dest) -{ - ma_dsubu(dest, dest, imm); -} - -void -MacroAssemblerMIPS64Compat::subPtr(const Address& addr, const Register dest) -{ - loadPtr(addr, SecondScratchReg); - subPtr(SecondScratchReg, dest); -} - -void -MacroAssemblerMIPS64Compat::subPtr(Register src, const Address& dest) -{ - loadPtr(dest, SecondScratchReg); - subPtr(src, SecondScratchReg); - storePtr(SecondScratchReg, dest); -} - void MacroAssemblerMIPS64Compat::branchDouble(DoubleCondition cond, FloatRegister lhs, FloatRegister rhs, Label* label) @@ -2270,7 +2243,7 @@ void MacroAssemblerMIPS64Compat::pushValue(ValueOperand val) { // Allocate stack slots for Value. One for each. - subPtr(Imm32(sizeof(Value)), StackPointer); + asMasm().subPtr(Imm32(sizeof(Value)), StackPointer); // Store Value storeValue(val, Address(StackPointer, 0)); } @@ -2378,7 +2351,7 @@ MacroAssemblerMIPS64Compat::handleFailureWithHandlerTail(void* handler) { // Reserve space for exception information. int size = (sizeof(ResumeFromException) + ABIStackAlignment) & ~(ABIStackAlignment - 1); - subPtr(Imm32(size), StackPointer); + asMasm().subPtr(Imm32(size), StackPointer); ma_move(a0, StackPointer); // Use a0 since it is a first function argument // Call the handler. @@ -2681,7 +2654,7 @@ void MacroAssembler::reserveStack(uint32_t amount) { if (amount) - subPtr(Imm32(amount), StackPointer); + asMasm().subPtr(Imm32(amount), StackPointer); adjustFrame(amount); } @@ -2697,7 +2670,7 @@ MacroAssembler::setupUnalignedABICall(Register scratch) ma_move(scratch, StackPointer); // Force sp to be aligned - subPtr(Imm32(sizeof(uintptr_t)), StackPointer); + asMasm().subPtr(Imm32(sizeof(uintptr_t)), StackPointer); ma_and(StackPointer, StackPointer, Imm32(~(ABIStackAlignment - 1))); storePtr(scratch, Address(StackPointer, 0)); } diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 2433c9477a00..1602a3c65a20 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -598,10 +598,7 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void branchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) { ma_b(lhs, imm, label, cond); } - void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) { - subPtr(imm, lhs); - branchPtr(cond, lhs, Imm32(0), label); - } + inline void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label); // higher level tag testing code Address ToPayload(Address value) { @@ -1105,8 +1102,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 } } - void subPtr(Register src, Register dest); - void move32(Imm32 imm, Register dest); void move32(Register src, Register dest); void move64(Register64 src, Register64 dest) { @@ -1243,9 +1238,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void clampIntToUint8(Register reg); - void subPtr(Imm32 imm, const Register dest); - void subPtr(const Address& addr, const Register dest); - void subPtr(Register src, const Address& dest); void mulBy3(const Register& src, const Register& dest) { as_daddu(dest, src, src); as_daddu(dest, dest, src); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 1e639903fa58..5601da7a9a31 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -234,7 +234,6 @@ class MacroAssemblerNone : public Assembler template void cmpPtrSet(Condition, T, S, Register) { MOZ_CRASH(); } template void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); } - template void subPtr(T, S) { MOZ_CRASH(); } void neg32(Register) { MOZ_CRASH(); } void mulBy3(Register, Register) { MOZ_CRASH(); } void mul64(Imm64, const Register64&) { MOZ_CRASH(); } diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index 8a7457a52640..912dcfdc899a 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -130,6 +130,30 @@ MacroAssembler::add64(Imm32 imm, Register64 dest) addq(imm, dest.reg); } +void +MacroAssembler::subPtr(Register src, Register dest) +{ + subq(src, dest); +} + +void +MacroAssembler::subPtr(Register src, const Address& dest) +{ + subq(src, Operand(dest)); +} + +void +MacroAssembler::subPtr(Imm32 imm, Register dest) +{ + subq(imm, dest); +} + +void +MacroAssembler::subPtr(const Address& addr, Register dest) +{ + subq(Operand(addr), dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 452f685820fd..2356daa38621 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -543,18 +543,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared // Common interface. ///////////////////////////////////////////////////////////////// - void subPtr(Imm32 imm, Register dest) { - subq(imm, dest); - } - void subPtr(Register src, Register dest) { - subq(src, dest); - } - void subPtr(const Address& addr, Register dest) { - subq(Operand(addr), dest); - } - void subPtr(Register src, const Address& dest) { - subq(src, Operand(dest)); - } void mulBy3(const Register& src, const Register& dest) { lea(Operand(src, src, TimesTwo), dest); } @@ -673,7 +661,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared j(cond, label); } void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) { - subPtr(imm, lhs); + subq(imm, lhs); j(cond, label); } diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index c4246efbf6c3..2524528762d3 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -138,6 +138,30 @@ MacroAssembler::addConstantDouble(double d, FloatRegister dest) propagateOOM(dbl->uses.append(CodeOffset(masm.size()))); } +void +MacroAssembler::subPtr(Register src, Register dest) +{ + subl(src, dest); +} + +void +MacroAssembler::subPtr(Register src, const Address& dest) +{ + subl(src, Operand(dest)); +} + +void +MacroAssembler::subPtr(Imm32 imm, Register dest) +{ + subl(imm, dest); +} + +void +MacroAssembler::subPtr(const Address& addr, Register dest) +{ + subl(Operand(addr), dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 3ac987446685..13a1cebba32e 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -566,18 +566,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared // Common interface. ///////////////////////////////////////////////////////////////// - void subPtr(Imm32 imm, Register dest) { - subl(imm, dest); - } - void subPtr(Register src, Register dest) { - subl(src, dest); - } - void subPtr(const Address& addr, Register dest) { - subl(Operand(addr), dest); - } - void subPtr(Register src, const Address& dest) { - subl(src, Operand(dest)); - } void mulBy3(const Register& src, const Register& dest) { lea(Operand(src, src, TimesTwo), dest); } @@ -698,7 +686,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared j(cond, label); } void decBranchPtr(Condition cond, Register lhs, Imm32 imm, Label* label) { - subPtr(imm, lhs); + subl(imm, lhs); j(cond, label); } From 7c3d6d6c520aa4d064f24d82ece82b211986406c Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:03:15 +0900 Subject: [PATCH 022/139] Bug 1229057 - Part 9: Move MacroAssembler::subDouble into generic macro assembler. r=lth --HG-- extra : rebase_source : f2009ac9265ffc56dad9dee5cc89b895443ff1a1 --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 6 ------ js/src/jit/arm/MacroAssembler-arm.h | 1 - js/src/jit/arm64/MacroAssembler-arm64-inl.h | 6 ++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 3 --- js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h | 6 ++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 6 ------ js/src/jit/mips32/MacroAssembler-mips32.h | 1 - js/src/jit/mips64/MacroAssembler-mips64.cpp | 6 ------ js/src/jit/mips64/MacroAssembler-mips64.h | 1 - js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h | 6 ++++++ js/src/jit/x86-shared/MacroAssembler-x86-shared.h | 3 --- 14 files changed, 26 insertions(+), 28 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 01f475e18a81..71ea8ec3286c 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -763,6 +763,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void subPtr(Imm32 imm, Register dest) PER_ARCH; inline void subPtr(const Address& addr, Register dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); + inline void subDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 0e702bd53a35..e006aaecf75e 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -263,6 +263,12 @@ MacroAssembler::subPtr(const Address& addr, Register dest) ma_sub(scratch, dest); } +void +MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) +{ + ma_vsub(dest, src, dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 08c259f911cb..f078276359e7 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -246,12 +246,6 @@ MacroAssemblerARM::convertInt32ToFloat32(const Address& src, FloatRegister dest) as_vcvt(dest, VFPRegister(scratch).sintOverlay()); } -void -MacroAssemblerARM::subDouble(FloatRegister src, FloatRegister dest) -{ - ma_vsub(dest, src, dest); -} - void MacroAssemblerARM::mulDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 2dba6dadf581..d4ee6a08c2a7 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -97,7 +97,6 @@ class MacroAssemblerARM : public Assembler void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void subDouble(FloatRegister src, FloatRegister dest); void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 2ca8c381006c..2ed3e721bb4b 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -302,6 +302,12 @@ MacroAssembler::subPtr(const Address& addr, Register dest) Sub(ARMRegister(dest, 64), ARMRegister(dest, 64), Operand(scratch64)); } +void +MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) +{ + fsub(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 2537d684b761..a9426d856f66 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1236,9 +1236,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void negateFloat(FloatRegister reg) { fneg(ARMFPRegister(reg, 32), ARMFPRegister(reg, 32)); } - void subDouble(FloatRegister src, FloatRegister dest) { - fsub(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); - } void mulDouble(FloatRegister src, FloatRegister dest) { fmul(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); } diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index 48b96a8e0261..23a822ab4b7e 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -153,6 +153,12 @@ MacroAssembler::subPtr(const Address& addr, Register dest) subPtr(SecondScratchReg, dest); } +void +MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) +{ + as_subd(dest, dest, src); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 230d11a19657..39b3c394d5b3 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -263,12 +263,6 @@ MacroAssemblerMIPSCompat::convertInt32ToFloat32(const Address& src, FloatRegiste as_cvtsw(dest, dest); } -void -MacroAssemblerMIPSCompat::subDouble(FloatRegister src, FloatRegister dest) -{ - as_subd(dest, dest, src); -} - void MacroAssemblerMIPSCompat::mulDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index af9cdc1d47b5..ad66614878c6 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -175,7 +175,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void subDouble(FloatRegister src, FloatRegister dest); void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 0d7522701ea8..bc284bbe75d9 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -227,12 +227,6 @@ MacroAssemblerMIPS64Compat::convertInt32ToFloat32(const Address& src, FloatRegis as_cvtsw(dest, dest); } -void -MacroAssemblerMIPS64Compat::subDouble(FloatRegister src, FloatRegister dest) -{ - as_subd(dest, dest, src); -} - void MacroAssemblerMIPS64Compat::mulDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 1602a3c65a20..c768f2a054c2 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -185,7 +185,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void subDouble(FloatRegister src, FloatRegister dest); void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 5601da7a9a31..2a69c243d3d0 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -239,7 +239,6 @@ class MacroAssemblerNone : public Assembler void mul64(Imm64, const Register64&) { MOZ_CRASH(); } void negateDouble(FloatRegister) { MOZ_CRASH(); } - void subDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } void mulDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } void divDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index 7a1792abb37d..947d52a4724a 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -133,6 +133,12 @@ MacroAssembler::sub32(const Address& src, Register dest) subl(Operand(src), dest); } +void +MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) +{ + vsubsd(src, dest, dest); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index 3ac1a01688d6..0c79045339a1 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -922,9 +922,6 @@ class MacroAssemblerX86Shared : public Assembler // XOR the float in a float register with -0.0. vxorps(scratch, reg, reg); // s ^ 0x80000000 } - void subDouble(FloatRegister src, FloatRegister dest) { - vsubsd(src, dest, dest); - } void mulDouble(FloatRegister src, FloatRegister dest) { vmulsd(src, dest, dest); } From 486d8c3228eec7f06df0294cf4b4975d3b5033b3 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:03:23 +0900 Subject: [PATCH 023/139] Bug 1229057 - Part 10: Move MacroAssembler::mul32 into generic macro assembler. r=sstangl --HG-- extra : rebase_source : 12a6771d89bb0d212164ab6ba25833e412121753 --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm64/MacroAssembler-arm64-inl.h | 15 +++++++++++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 13 ------------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 71ea8ec3286c..7a47eaa6c69c 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -765,6 +765,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void subDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; + inline void mul32(Register src1, Register src2, Register dest, Label* onOver, Label* onZero) DEFINED_ON(arm64); + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 2ed3e721bb4b..481c69f8b94b 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -308,6 +308,21 @@ MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) fsub(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); } +void +MacroAssembler::mul32(Register src1, Register src2, Register dest, Label* onOver, Label* onZero) +{ + Smull(ARMRegister(dest, 64), ARMRegister(src1, 32), ARMRegister(src2, 32)); + if (onOver) { + Cmp(ARMRegister(dest, 64), Operand(ARMRegister(dest, 32), vixl::SXTW)); + B(onOver, NotEqual); + } + if (onZero) + Cbz(ARMRegister(dest, 32), onZero); + + // Clear upper 32 bits. + Mov(ARMRegister(dest, 32), ARMRegister(dest, 32)); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index a9426d856f66..207e12c0d0d6 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1341,19 +1341,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler Subs(ARMRegister(dest, 32), ARMRegister(dest, 32), Operand(ARMRegister(src, 32))); } - void mul32(Register src1, Register src2, Register dest, Label* onOver, Label* onZero) { - Smull(ARMRegister(dest, 64), ARMRegister(src1, 32), ARMRegister(src2, 32)); - if (onOver) { - Cmp(ARMRegister(dest, 64), Operand(ARMRegister(dest, 32), vixl::SXTW)); - B(onOver, NotEqual); - } - if (onZero) - Cbz(ARMRegister(dest, 32), onZero); - - // Clear upper 32 bits. - Mov(ARMRegister(dest, 32), ARMRegister(dest, 32)); - } - void ret() { pop(lr); abiret(); From b91e6d55e4a79c54ebaf6e71c25c36fb70e3da16 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:03:32 +0900 Subject: [PATCH 024/139] Bug 1229057 - Part 11: Move MacroAssembler::mul64 into generic macro assembler. r=sstangl --HG-- extra : rebase_source : 54c38c572711f46f433eccd1ef6327bf1ff45acd --- js/src/jit/MacroAssembler.h | 2 + js/src/jit/arm/MacroAssembler-arm-inl.h | 29 ++++++++++++ js/src/jit/arm/MacroAssembler-arm.h | 26 ----------- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 10 +++++ js/src/jit/arm64/MacroAssembler-arm64.h | 8 ---- js/src/jit/mips32/MacroAssembler-mips32-inl.h | 45 +++++++++++++++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 45 ------------------- js/src/jit/mips32/MacroAssembler-mips32.h | 2 - js/src/jit/mips64/MacroAssembler-mips64-inl.h | 9 ++++ js/src/jit/mips64/MacroAssembler-mips64.h | 7 --- js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x64/MacroAssembler-x64-inl.h | 7 +++ js/src/jit/x64/MacroAssembler-x64.h | 4 -- js/src/jit/x86/MacroAssembler-x86-inl.h | 35 +++++++++++++++ js/src/jit/x86/MacroAssembler-x86.h | 32 ------------- 15 files changed, 137 insertions(+), 125 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 7a47eaa6c69c..77d47c84d4d6 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -767,6 +767,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void mul32(Register src1, Register src2, Register dest, Label* onOver, Label* onZero) DEFINED_ON(arm64); + inline void mul64(Imm64 imm, const Register64& dest) PER_ARCH; + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index e006aaecf75e..a82a91268c8c 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -269,6 +269,35 @@ MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) ma_vsub(dest, src, dest); } +void +MacroAssembler::mul64(Imm64 imm, const Register64& dest) +{ + // LOW32 = LOW(LOW(dest) * LOW(imm)); + // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits] + // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] + // + HIGH(LOW(dest) * LOW(imm)) [carry] + + // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); + ma_mov(Imm32(imm.value & 0xFFFFFFFFL), ScratchRegister); + as_mul(dest.high, dest.high, ScratchRegister); + + // high:low = LOW(dest) * LOW(imm); + as_umull(secondScratchReg_, ScratchRegister, dest.low, ScratchRegister); + + // HIGH(dest) += high; + as_add(dest.high, dest.high, O2Reg(secondScratchReg_)); + + // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); + if (((imm.value >> 32) & 0xFFFFFFFFL) == 5) + as_add(secondScratchReg_, dest.low, lsl(dest.low, 2)); + else + MOZ_CRASH("Not supported imm"); + as_add(dest.high, dest.high, O2Reg(secondScratchReg_)); + + // LOW(dest) = low; + ma_mov(ScratchRegister, dest.low); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index d4ee6a08c2a7..475cf12c095d 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1634,32 +1634,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void mulBy3(const Register& src, const Register& dest) { as_add(dest, src, lsl(src, 1)); } - void mul64(Imm64 imm, const Register64& dest) { - // LOW32 = LOW(LOW(dest) * LOW(imm)); - // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits] - // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] - // + HIGH(LOW(dest) * LOW(imm)) [carry] - - // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); - ma_mov(Imm32(imm.value & 0xFFFFFFFFL), ScratchRegister); - as_mul(dest.high, dest.high, ScratchRegister); - - // high:low = LOW(dest) * LOW(imm); - as_umull(secondScratchReg_, ScratchRegister, dest.low, ScratchRegister); - - // HIGH(dest) += high; - as_add(dest.high, dest.high, O2Reg(secondScratchReg_)); - - // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); - if (((imm.value >> 32) & 0xFFFFFFFFL) == 5) - as_add(secondScratchReg_, dest.low, lsl(dest.low, 2)); - else - MOZ_CRASH("Not supported imm"); - as_add(dest.high, dest.high, O2Reg(secondScratchReg_)); - - // LOW(dest) = low; - ma_mov(ScratchRegister, dest.low); - } void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 481c69f8b94b..ccf6b2109cbc 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -323,6 +323,16 @@ MacroAssembler::mul32(Register src1, Register src2, Register dest, Label* onOver Mov(ARMRegister(dest, 32), ARMRegister(dest, 32)); } +void +MacroAssembler::mul64(Imm64 imm, const Register64& dest) +{ + vixl::UseScratchRegisterScope temps(this); + const ARMRegister scratch64 = temps.AcquireX(); + MOZ_ASSERT(dest.reg != scratch64.asUnsized()); + mov(ImmWord(imm.value), scratch64.asUnsized()); + Mul(ARMRegister(dest.reg, 64), ARMRegister(dest.reg, 64), scratch64); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 207e12c0d0d6..ee136a2982ee 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -2849,14 +2849,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler Add(xdest, xsrc, Operand(xsrc, vixl::LSL, 1)); } - void mul64(Imm64 imm, const Register64& dest) { - vixl::UseScratchRegisterScope temps(this); - const ARMRegister scratch64 = temps.AcquireX(); - MOZ_ASSERT(dest.reg != scratch64.asUnsized()); - mov(ImmWord(imm.value), scratch64.asUnsized()); - Mul(ARMRegister(dest.reg, 64), ARMRegister(dest.reg, 64), scratch64); - } - void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest) { Ucvtf(ARMFPRegister(dest, 64), ARMRegister(src.reg, 64)); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 3ea88f84b060..448255b4dea2 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -125,6 +125,51 @@ MacroAssembler::subPtr(Imm32 imm, Register dest) ma_subu(dest, dest, imm); } +void +MacroAssembler::mul64(Imm64 imm, const Register64& dest) +{ + // LOW32 = LOW(LOW(dest) * LOW(imm)); + // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits] + // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] + // + HIGH(LOW(dest) * LOW(imm)) [carry] + + // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); + ma_li(ScratchRegister, Imm32(imm.value & LOW_32_MASK)); + as_multu(dest.high, ScratchRegister); + as_mflo(dest.high); + + // mfhi:mflo = LOW(dest) * LOW(imm); + as_multu(dest.low, ScratchRegister); + + // HIGH(dest) += mfhi; + as_mfhi(ScratchRegister); + as_addu(dest.high, dest.high, ScratchRegister); + + if (((imm.value >> 32) & LOW_32_MASK) == 5) { + // Optimized case for Math.random(). + + // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); + as_sll(ScratchRegister, dest.low, 2); + as_addu(ScratchRegister, ScratchRegister, dest.low); + as_addu(dest.high, dest.high, ScratchRegister); + + // LOW(dest) = mflo; + as_mflo(dest.low); + } else { + // tmp = mflo + as_mflo(SecondScratchReg); + + // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); + ma_li(ScratchRegister, Imm32((imm.value >> 32) & LOW_32_MASK)); + as_multu(dest.low, ScratchRegister); + as_mflo(ScratchRegister); + as_addu(dest.high, dest.high, ScratchRegister); + + // LOW(dest) = tmp; + ma_move(dest.low, SecondScratchReg); + } +} + // =============================================================== // Shift functions diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 39b3c394d5b3..880e420eae2a 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -77,51 +77,6 @@ MacroAssemblerMIPSCompat::convertUInt32ToDouble(Register src, FloatRegister dest as_addd(dest, dest, SecondScratchDoubleReg); } -void -MacroAssemblerMIPSCompat::mul64(Imm64 imm, const Register64& dest) -{ - // LOW32 = LOW(LOW(dest) * LOW(imm)); - // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits] - // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] - // + HIGH(LOW(dest) * LOW(imm)) [carry] - - // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); - ma_li(ScratchRegister, Imm32(imm.value & LOW_32_MASK)); - as_multu(dest.high, ScratchRegister); - as_mflo(dest.high); - - // mfhi:mflo = LOW(dest) * LOW(imm); - as_multu(dest.low, ScratchRegister); - - // HIGH(dest) += mfhi; - as_mfhi(ScratchRegister); - as_addu(dest.high, dest.high, ScratchRegister); - - if (((imm.value >> 32) & LOW_32_MASK) == 5) { - // Optimized case for Math.random(). - - // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); - as_sll(ScratchRegister, dest.low, 2); - as_addu(ScratchRegister, ScratchRegister, dest.low); - as_addu(dest.high, dest.high, ScratchRegister); - - // LOW(dest) = mflo; - as_mflo(dest.low); - } else { - // tmp = mflo - as_mflo(SecondScratchReg); - - // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); - ma_li(ScratchRegister, Imm32((imm.value >> 32) & LOW_32_MASK)); - as_multu(dest.low, ScratchRegister); - as_mflo(ScratchRegister); - as_addu(dest.high, dest.high, ScratchRegister); - - // LOW(dest) = tmp; - ma_move(dest.low, SecondScratchReg); - } -} - static const double TO_DOUBLE_HIGH_SCALE = 0x100000000; void diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index ad66614878c6..ea98b791a2a5 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -1229,8 +1229,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS as_addu(dest, dest, src); } - void mul64(Imm64 imm, const Register64& dest); - void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { movePtr(imm, ScratchRegister); diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index e4bf6b7dfc7f..4d8736431747 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -119,6 +119,15 @@ MacroAssembler::subPtr(Imm32 imm, Register dest) ma_dsubu(dest, dest, imm); } +void +MacroAssembler::mul64(Imm64 imm, const Register64& dest) +{ + MOZ_ASSERT(dest.reg != ScratchRegister); + mov(ImmWord(imm.value), ScratchRegister); + as_dmultu(dest.reg, ScratchRegister); + as_mflo(dest.reg); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index c768f2a054c2..a7acebfe8d0b 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -1242,13 +1242,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 as_daddu(dest, dest, src); } - void mul64(Imm64 imm, const Register64& dest) { - MOZ_ASSERT(dest.reg != ScratchRegister); - mov(ImmWord(imm.value), ScratchRegister); - as_dmultu(dest.reg, ScratchRegister); - as_mflo(dest.reg); - } - void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { movePtr(imm, ScratchRegister); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 2a69c243d3d0..d4198fb2ce9a 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -236,7 +236,6 @@ class MacroAssemblerNone : public Assembler void neg32(Register) { MOZ_CRASH(); } void mulBy3(Register, Register) { MOZ_CRASH(); } - void mul64(Imm64, const Register64&) { MOZ_CRASH(); } void negateDouble(FloatRegister) { MOZ_CRASH(); } void mulDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index 912dcfdc899a..e7d61bd23558 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -154,6 +154,13 @@ MacroAssembler::subPtr(const Address& addr, Register dest) subq(Operand(addr), dest); } +void +MacroAssembler::mul64(Imm64 imm, const Register64& dest) +{ + movq(ImmWord(uintptr_t(imm.value)), ScratchReg); + imulq(ScratchReg, dest.reg); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 2356daa38621..5e2f6cb47753 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -546,10 +546,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared void mulBy3(const Register& src, const Register& dest) { lea(Operand(src, src, TimesTwo), dest); } - void mul64(Imm64 imm, const Register64& dest) { - movq(ImmWord(uintptr_t(imm.value)), ScratchReg); - imulq(ScratchReg, dest.reg); - } void branch32(Condition cond, AbsoluteAddress lhs, Imm32 rhs, Label* label) { if (X86Encoding::IsAddressImmediate(lhs.addr)) { diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index 2524528762d3..aff8a65e371f 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -162,6 +162,41 @@ MacroAssembler::subPtr(const Address& addr, Register dest) subl(Operand(addr), dest); } +// Note: this function clobbers eax and edx. +void +MacroAssembler::mul64(Imm64 imm, const Register64& dest) +{ + // LOW32 = LOW(LOW(dest) * LOW(imm)); + // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits] + // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] + // + HIGH(LOW(dest) * LOW(imm)) [carry] + + MOZ_ASSERT(dest.low != eax && dest.low != edx); + MOZ_ASSERT(dest.high != eax && dest.high != edx); + + // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); + movl(Imm32(imm.value & 0xFFFFFFFFL), edx); + imull(edx, dest.high); + + // edx:eax = LOW(dest) * LOW(imm); + movl(Imm32(imm.value & 0xFFFFFFFFL), edx); + movl(dest.low, eax); + mull(edx); + + // HIGH(dest) += edx; + addl(edx, dest.high); + + // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); + if (((imm.value >> 32) & 0xFFFFFFFFL) == 5) + leal(Operand(dest.low, dest.low, TimesFour), edx); + else + MOZ_CRASH("Unsupported imm"); + addl(edx, dest.high); + + // LOW(dest) = eax; + movl(eax, dest.low); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 13a1cebba32e..530afa248566 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -569,38 +569,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void mulBy3(const Register& src, const Register& dest) { lea(Operand(src, src, TimesTwo), dest); } - // Note: this function clobbers eax and edx. - void mul64(Imm64 imm, const Register64& dest) { - // LOW32 = LOW(LOW(dest) * LOW(imm)); - // HIGH32 = LOW(HIGH(dest) * LOW(imm)) [multiply imm into upper bits] - // + LOW(LOW(dest) * HIGH(imm)) [multiply dest into upper bits] - // + HIGH(LOW(dest) * LOW(imm)) [carry] - - MOZ_ASSERT(dest.low != eax && dest.low != edx); - MOZ_ASSERT(dest.high != eax && dest.high != edx); - - // HIGH(dest) = LOW(HIGH(dest) * LOW(imm)); - movl(Imm32(imm.value & 0xFFFFFFFFL), edx); - imull(edx, dest.high); - - // edx:eax = LOW(dest) * LOW(imm); - movl(Imm32(imm.value & 0xFFFFFFFFL), edx); - movl(dest.low, eax); - mull(edx); - - // HIGH(dest) += edx; - addl(edx, dest.high); - - // HIGH(dest) += LOW(LOW(dest) * HIGH(imm)); - if (((imm.value >> 32) & 0xFFFFFFFFL) == 5) - leal(Operand(dest.low, dest.low, TimesFour), edx); - else - MOZ_CRASH("Unsupported imm"); - addl(edx, dest.high); - - // LOW(dest) = eax; - movl(eax, dest.low); - } void branch32(Condition cond, AbsoluteAddress lhs, Imm32 rhs, Label* label) { cmp32(Operand(lhs), rhs); From 0d717c30e50fd2a893b74206274908693d9cc350 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:03:40 +0900 Subject: [PATCH 025/139] Bug 1229057 - Part 12: Move MacroAssembler::mulBy3 into generic macro assembler. r=sstangl --HG-- extra : rebase_source : ec480129a2cafedbca2dd777cad53d67bd4d29fd --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.h | 4 ---- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 8 ++++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 6 ------ js/src/jit/mips32/MacroAssembler-mips32-inl.h | 7 +++++++ js/src/jit/mips32/MacroAssembler-mips32.h | 5 ----- js/src/jit/mips64/MacroAssembler-mips64-inl.h | 7 +++++++ js/src/jit/mips64/MacroAssembler-mips64.h | 5 ----- js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x64/MacroAssembler-x64-inl.h | 6 ++++++ js/src/jit/x64/MacroAssembler-x64.h | 4 ---- js/src/jit/x86/MacroAssembler-x86-inl.h | 6 ++++++ js/src/jit/x86/MacroAssembler-x86.h | 4 ---- 14 files changed, 42 insertions(+), 29 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 77d47c84d4d6..fd8cf7dc9922 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -769,6 +769,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void mul64(Imm64 imm, const Register64& dest) PER_ARCH; + inline void mulBy3(Register src, Register dest) PER_ARCH; + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index a82a91268c8c..7927ee62111c 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -298,6 +298,12 @@ MacroAssembler::mul64(Imm64 imm, const Register64& dest) ma_mov(ScratchRegister, dest.low); } +void +MacroAssembler::mulBy3(Register src, Register dest) +{ + as_add(dest, src, lsl(src, 1)); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 475cf12c095d..b8f8ddddf8fe 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1631,10 +1631,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void cmpPtr(const Address& lhs, ImmGCPtr rhs); void cmpPtr(const Address& lhs, Imm32 rhs); - void mulBy3(const Register& src, const Register& dest) { - as_add(dest, src, lsl(src, 1)); - } - void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { movePtr(imm, ScratchRegister); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index ccf6b2109cbc..63467a51dbea 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -333,6 +333,14 @@ MacroAssembler::mul64(Imm64 imm, const Register64& dest) Mul(ARMRegister(dest.reg, 64), ARMRegister(dest.reg, 64), scratch64); } +void +MacroAssembler::mulBy3(Register src, Register dest) +{ + ARMRegister xdest(dest, 64); + ARMRegister xsrc(src, 64); + Add(xdest, xsrc, Operand(xsrc, vixl::LSL, 1)); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index ee136a2982ee..323da40c60f4 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -2843,12 +2843,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler vixl::MacroAssembler::Ret(vixl::lr); } - void mulBy3(Register src, Register dest) { - ARMRegister xdest(dest, 64); - ARMRegister xsrc(src, 64); - Add(xdest, xsrc, Operand(xsrc, vixl::LSL, 1)); - } - void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest) { Ucvtf(ARMFPRegister(dest, 64), ARMRegister(src.reg, 64)); } diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 448255b4dea2..858fd6e0b637 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -170,6 +170,13 @@ MacroAssembler::mul64(Imm64 imm, const Register64& dest) } } +void +MacroAssembler::mulBy3(Register src, Register dest) +{ + as_addu(dest, src, src); + as_addu(dest, dest, src); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index ea98b791a2a5..2db5ccb564e2 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -1224,11 +1224,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void clampIntToUint8(Register reg); - void mulBy3(const Register& src, const Register& dest) { - as_addu(dest, src, src); - as_addu(dest, dest, src); - } - void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { movePtr(imm, ScratchRegister); diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index 4d8736431747..b8ca7af4d246 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -128,6 +128,13 @@ MacroAssembler::mul64(Imm64 imm, const Register64& dest) as_mflo(dest.reg); } +void +MacroAssembler::mulBy3(Register src, Register dest) +{ + as_daddu(dest, src, src); + as_daddu(dest, dest, src); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index a7acebfe8d0b..989a4a8b2598 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -1237,11 +1237,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void clampIntToUint8(Register reg); - void mulBy3(const Register& src, const Register& dest) { - as_daddu(dest, src, src); - as_daddu(dest, dest, src); - } - void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { movePtr(imm, ScratchRegister); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index d4198fb2ce9a..cb18a1179a3f 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -235,7 +235,6 @@ class MacroAssemblerNone : public Assembler template void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); } void neg32(Register) { MOZ_CRASH(); } - void mulBy3(Register, Register) { MOZ_CRASH(); } void negateDouble(FloatRegister) { MOZ_CRASH(); } void mulDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index e7d61bd23558..dfdedf471470 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -161,6 +161,12 @@ MacroAssembler::mul64(Imm64 imm, const Register64& dest) imulq(ScratchReg, dest.reg); } +void +MacroAssembler::mulBy3(Register src, Register dest) +{ + lea(Operand(src, src, TimesTwo), dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 5e2f6cb47753..62f3543aa4e5 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -543,10 +543,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared // Common interface. ///////////////////////////////////////////////////////////////// - void mulBy3(const Register& src, const Register& dest) { - lea(Operand(src, src, TimesTwo), dest); - } - void branch32(Condition cond, AbsoluteAddress lhs, Imm32 rhs, Label* label) { if (X86Encoding::IsAddressImmediate(lhs.addr)) { branch32(cond, Operand(lhs), rhs, label); diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index aff8a65e371f..69116a9c0d86 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -197,6 +197,12 @@ MacroAssembler::mul64(Imm64 imm, const Register64& dest) movl(eax, dest.low); } +void +MacroAssembler::mulBy3(Register src, Register dest) +{ + lea(Operand(src, src, TimesTwo), dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 530afa248566..049127df5e2e 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -566,10 +566,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared // Common interface. ///////////////////////////////////////////////////////////////// - void mulBy3(const Register& src, const Register& dest) { - lea(Operand(src, src, TimesTwo), dest); - } - void branch32(Condition cond, AbsoluteAddress lhs, Imm32 rhs, Label* label) { cmp32(Operand(lhs), rhs); j(cond, label); From d58395b6bd0dd379b98deb4164505aada6f8449a Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:03:49 +0900 Subject: [PATCH 026/139] Bug 1229057 - Part 13: Move MacroAssembler::mulDoublePtr into generic macro assembler. r=djvj --HG-- extra : rebase_source : 309611e6bcfe3b2d3408e72285f70af4010b1c1c --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 8 ++++++++ js/src/jit/arm/MacroAssembler-arm.h | 5 ----- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 12 ++++++++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 9 --------- .../jit/mips-shared/MacroAssembler-mips-shared-inl.h | 8 ++++++++ js/src/jit/mips32/MacroAssembler-mips32.h | 5 ----- js/src/jit/mips64/MacroAssembler-mips64.h | 5 ----- js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x64/MacroAssembler-x64-inl.h | 7 +++++++ js/src/jit/x64/MacroAssembler-x64.h | 5 ----- js/src/jit/x86/MacroAssembler-x86-inl.h | 7 +++++++ js/src/jit/x86/MacroAssembler-x86.h | 5 ----- 13 files changed, 44 insertions(+), 35 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index fd8cf7dc9922..f483187506c7 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -771,6 +771,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void mulBy3(Register src, Register dest) PER_ARCH; + inline void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 7927ee62111c..0e1445cf5d29 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -304,6 +304,14 @@ MacroAssembler::mulBy3(Register src, Register dest) as_add(dest, src, lsl(src, 1)); } +void +MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) +{ + movePtr(imm, ScratchRegister); + loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg); + mulDouble(ScratchDoubleReg, dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index b8f8ddddf8fe..521cf84b6764 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -1632,11 +1632,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void cmpPtr(const Address& lhs, Imm32 rhs); void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); - void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { - movePtr(imm, ScratchRegister); - loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg); - mulDouble(ScratchDoubleReg, dest); - } void setStackArg(Register reg, uint32_t arg); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 63467a51dbea..c8d63bff7d68 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -341,6 +341,18 @@ MacroAssembler::mulBy3(Register src, Register dest) Add(xdest, xsrc, Operand(xsrc, vixl::LSL, 1)); } +void +MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) +{ + vixl::UseScratchRegisterScope temps(this); + const Register scratch = temps.AcquireX().asUnsized(); + MOZ_ASSERT(temp != scratch); + movePtr(imm, scratch); + const ARMFPRegister scratchDouble = temps.AcquireD(); + Ldr(scratchDouble, MemOperand(Address(scratch, 0))); + fmul(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), scratchDouble); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 323da40c60f4..620547357277 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -2846,15 +2846,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest) { Ucvtf(ARMFPRegister(dest, 64), ARMRegister(src.reg, 64)); } - void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { - vixl::UseScratchRegisterScope temps(this); - const Register scratch = temps.AcquireX().asUnsized(); - MOZ_ASSERT(temp != scratch); - movePtr(imm, scratch); - const ARMFPRegister scratchDouble = temps.AcquireD(); - Ldr(scratchDouble, MemOperand(Address(scratch, 0))); - fmul(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), scratchDouble); - } template void branchAdd32(Condition cond, T src, Register dest, Label* label) { diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index 23a822ab4b7e..74da3bf0e1f3 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -159,6 +159,14 @@ MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) as_subd(dest, dest, src); } +void +MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) +{ + movePtr(imm, ScratchRegister); + loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg); + mulDouble(ScratchDoubleReg, dest); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 2db5ccb564e2..5a678bcbac3e 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -1225,11 +1225,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void clampIntToUint8(Register reg); void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); - void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { - movePtr(imm, ScratchRegister); - loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg); - mulDouble(ScratchDoubleReg, dest); - } void breakpoint(); diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 989a4a8b2598..8f3e56d5b1c4 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -1238,11 +1238,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void clampIntToUint8(Register reg); void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); - void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { - movePtr(imm, ScratchRegister); - loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg); - mulDouble(ScratchDoubleReg, dest); - } void breakpoint(); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index cb18a1179a3f..f8e82d5d37ef 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -394,7 +394,6 @@ class MacroAssemblerNone : public Assembler template void convertInt32ToDouble(T, FloatRegister) { MOZ_CRASH(); } void convertFloat32ToDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } void convertUInt64ToDouble(Register64, Register, FloatRegister) { MOZ_CRASH(); } - void mulDoublePtr(ImmPtr, Register, FloatRegister) { MOZ_CRASH(); } void branchTruncateDouble(FloatRegister, Register, Label*) { MOZ_CRASH(); } void branchTruncateFloat32(FloatRegister, Register, Label*) { MOZ_CRASH(); } diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index dfdedf471470..4c0fbafe86ca 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -167,6 +167,13 @@ MacroAssembler::mulBy3(Register src, Register dest) lea(Operand(src, src, TimesTwo), dest); } +void +MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) +{ + movq(imm, ScratchReg); + vmulsd(Operand(ScratchReg, 0), dest, dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 62f3543aa4e5..b3ad21684685 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -1295,11 +1295,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared vcvtsi2sdq(src.reg, dest); } - void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { - movq(imm, ScratchReg); - vmulsd(Operand(ScratchReg, 0), dest, dest); - } - inline void inc64(AbsoluteAddress dest); inline void incrementInt32Value(const Address& addr); diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index 69116a9c0d86..dd368e0b49d1 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -203,6 +203,13 @@ MacroAssembler::mulBy3(Register src, Register dest) lea(Operand(src, src, TimesTwo), dest); } +void +MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) +{ + movl(imm, temp); + vmulsd(Operand(temp, 0), dest, dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 049127df5e2e..6a09c4099407 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -1030,11 +1030,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); - void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { - movl(imm, temp); - vmulsd(Operand(temp, 0), dest, dest); - } - void inc64(AbsoluteAddress dest) { addl(Imm32(1), Operand(dest)); Label noOverflow; From b9e06d6cc8729aab62d5beddfab668541812807e Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:03:57 +0900 Subject: [PATCH 027/139] Bug 1229057 - Part 14: Move MacroAssembler::mulDouble into generic macro assembler. r=djvj --HG-- extra : rebase_source : 19af54b46245cf94a4010cfc08ed532965b56e3a --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 8 +------- js/src/jit/arm/MacroAssembler-arm.h | 1 - js/src/jit/arm64/MacroAssembler-arm64-inl.h | 6 ++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 3 --- js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h | 6 ++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 8 +------- js/src/jit/mips32/MacroAssembler-mips32.h | 1 - js/src/jit/mips64/MacroAssembler-mips64.cpp | 6 ------ js/src/jit/mips64/MacroAssembler-mips64.h | 1 - js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h | 6 ++++++ js/src/jit/x86-shared/MacroAssembler-x86-shared.h | 3 --- js/src/jit/x86/MacroAssembler-x86.cpp | 2 +- 15 files changed, 29 insertions(+), 31 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index f483187506c7..dfc228784eac 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -771,6 +771,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void mulBy3(Register src, Register dest) PER_ARCH; + inline void mulDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; + inline void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); // =============================================================== diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 0e1445cf5d29..4579be07dcdf 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -304,6 +304,12 @@ MacroAssembler::mulBy3(Register src, Register dest) as_add(dest, src, lsl(src, 1)); } +void +MacroAssembler::mulDouble(FloatRegister src, FloatRegister dest) +{ + ma_vmul(dest, src, dest); +} + void MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index f078276359e7..46d5e3e92149 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -97,7 +97,7 @@ MacroAssemblerARMCompat::convertUInt64ToDouble(Register64 src, Register temp, Fl convertUInt32ToDouble(src.high, dest); movePtr(ImmPtr(&TO_DOUBLE_HIGH_SCALE), ScratchRegister); loadDouble(Address(ScratchRegister, 0), ScratchDoubleReg); - mulDouble(ScratchDoubleReg, dest); + asMasm().mulDouble(ScratchDoubleReg, dest); convertUInt32ToDouble(src.low, ScratchDoubleReg); asMasm().addDouble(ScratchDoubleReg, dest); } @@ -246,12 +246,6 @@ MacroAssemblerARM::convertInt32ToFloat32(const Address& src, FloatRegister dest) as_vcvt(dest, VFPRegister(scratch).sintOverlay()); } -void -MacroAssemblerARM::mulDouble(FloatRegister src, FloatRegister dest) -{ - ma_vmul(dest, src, dest); -} - void MacroAssemblerARM::divDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 521cf84b6764..7b2048f31649 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -97,7 +97,6 @@ class MacroAssemblerARM : public Assembler void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); void negateDouble(FloatRegister reg); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index c8d63bff7d68..ba4f592904ae 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -341,6 +341,12 @@ MacroAssembler::mulBy3(Register src, Register dest) Add(xdest, xsrc, Operand(xsrc, vixl::LSL, 1)); } +void +MacroAssembler::mulDouble(FloatRegister src, FloatRegister dest) +{ + fmul(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); +} + void MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 620547357277..fb67a622e081 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1236,9 +1236,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void negateFloat(FloatRegister reg) { fneg(ARMFPRegister(reg, 32), ARMFPRegister(reg, 32)); } - void mulDouble(FloatRegister src, FloatRegister dest) { - fmul(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); - } void divDouble(FloatRegister src, FloatRegister dest) { fdiv(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); } diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index 74da3bf0e1f3..63a1a2592d72 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -159,6 +159,12 @@ MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) as_subd(dest, dest, src); } +void +MacroAssembler::mulDouble(FloatRegister src, FloatRegister dest) +{ + as_muld(dest, dest, src); +} + void MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 880e420eae2a..5c01603ce5d2 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -84,7 +84,7 @@ MacroAssemblerMIPSCompat::convertUInt64ToDouble(Register64 src, Register temp, F { convertUInt32ToDouble(src.high, dest); loadConstantDouble(TO_DOUBLE_HIGH_SCALE, ScratchDoubleReg); - mulDouble(ScratchDoubleReg, dest); + asMasm().mulDouble(ScratchDoubleReg, dest); convertUInt32ToDouble(src.low, ScratchDoubleReg); asMasm().addDouble(ScratchDoubleReg, dest); } @@ -218,12 +218,6 @@ MacroAssemblerMIPSCompat::convertInt32ToFloat32(const Address& src, FloatRegiste as_cvtsw(dest, dest); } -void -MacroAssemblerMIPSCompat::mulDouble(FloatRegister src, FloatRegister dest) -{ - as_muld(dest, dest, src); -} - void MacroAssemblerMIPSCompat::divDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 5a678bcbac3e..27b7c38ce886 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -175,7 +175,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); void negateDouble(FloatRegister reg); diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index bc284bbe75d9..eb591c0086e9 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -227,12 +227,6 @@ MacroAssemblerMIPS64Compat::convertInt32ToFloat32(const Address& src, FloatRegis as_cvtsw(dest, dest); } -void -MacroAssemblerMIPS64Compat::mulDouble(FloatRegister src, FloatRegister dest) -{ - as_muld(dest, dest, src); -} - void MacroAssemblerMIPS64Compat::divDouble(FloatRegister src, FloatRegister dest) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 8f3e56d5b1c4..accb2fab6f0b 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -185,7 +185,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void mulDouble(FloatRegister src, FloatRegister dest); void divDouble(FloatRegister src, FloatRegister dest); void negateDouble(FloatRegister reg); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index f8e82d5d37ef..731068452f33 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -237,7 +237,6 @@ class MacroAssemblerNone : public Assembler void neg32(Register) { MOZ_CRASH(); } void negateDouble(FloatRegister) { MOZ_CRASH(); } - void mulDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } void divDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } template void branch32(Condition, T, S, Label*) { MOZ_CRASH(); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index 947d52a4724a..6be35d9cea57 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -139,6 +139,12 @@ MacroAssembler::subDouble(FloatRegister src, FloatRegister dest) vsubsd(src, dest, dest); } +void +MacroAssembler::mulDouble(FloatRegister src, FloatRegister dest) +{ + vmulsd(src, dest, dest); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index 0c79045339a1..3d96eef0e432 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -922,9 +922,6 @@ class MacroAssemblerX86Shared : public Assembler // XOR the float in a float register with -0.0. vxorps(scratch, reg, reg); // s ^ 0x80000000 } - void mulDouble(FloatRegister src, FloatRegister dest) { - vmulsd(src, dest, dest); - } void divDouble(FloatRegister src, FloatRegister dest) { vdivsd(src, dest, dest); } diff --git a/js/src/jit/x86/MacroAssembler-x86.cpp b/js/src/jit/x86/MacroAssembler-x86.cpp index c1e1f1b4d167..30712c286001 100644 --- a/js/src/jit/x86/MacroAssembler-x86.cpp +++ b/js/src/jit/x86/MacroAssembler-x86.cpp @@ -40,7 +40,7 @@ MacroAssemblerX86::convertUInt64ToDouble(Register64 src, Register temp, FloatReg convertUInt32ToDouble(src.high, dest); movePtr(ImmPtr(&TO_DOUBLE_HIGH_SCALE), temp); loadDouble(Address(temp, 0), ScratchDoubleReg); - mulDouble(ScratchDoubleReg, dest); + asMasm().mulDouble(ScratchDoubleReg, dest); convertUInt32ToDouble(src.low, ScratchDoubleReg); asMasm().addDouble(ScratchDoubleReg, dest); return; From 58e28820dedb56066897553436a2a18daf6e8569 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:04:05 +0900 Subject: [PATCH 028/139] Bug 1229057 - Part 15: Move MacroAssembler::divDouble into generic macro assembler. r=djvj --HG-- extra : rebase_source : de9fdc30c8d22fa89a51acfdf3b3608d50e6d096 --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 6 ------ js/src/jit/arm/MacroAssembler-arm.h | 2 -- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 6 ++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 3 --- js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h | 6 ++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 6 ------ js/src/jit/mips32/MacroAssembler-mips32.h | 2 -- js/src/jit/mips64/MacroAssembler-mips64.cpp | 6 ------ js/src/jit/mips64/MacroAssembler-mips64.h | 2 -- js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h | 6 ++++++ js/src/jit/x86-shared/MacroAssembler-x86-shared.h | 3 --- 14 files changed, 26 insertions(+), 31 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index dfc228784eac..3ba37039c030 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -775,6 +775,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) DEFINED_ON(mips_shared, arm, arm64, x86, x64); + inline void divDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 4579be07dcdf..ebfebd759950 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -318,6 +318,12 @@ MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) mulDouble(ScratchDoubleReg, dest); } +void +MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) +{ + ma_vdiv(dest, src, dest); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 46d5e3e92149..95ef5d721335 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -246,12 +246,6 @@ MacroAssemblerARM::convertInt32ToFloat32(const Address& src, FloatRegister dest) as_vcvt(dest, VFPRegister(scratch).sintOverlay()); } -void -MacroAssemblerARM::divDouble(FloatRegister src, FloatRegister dest) -{ - ma_vdiv(dest, src, dest); -} - void MacroAssemblerARM::negateDouble(FloatRegister reg) { diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 7b2048f31649..e7f2ac843507 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -97,8 +97,6 @@ class MacroAssemblerARM : public Assembler void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void divDouble(FloatRegister src, FloatRegister dest); - void negateDouble(FloatRegister reg); void inc64(AbsoluteAddress dest); diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index ba4f592904ae..2e3f9bef8696 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -359,6 +359,12 @@ MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) fmul(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), scratchDouble); } +void +MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) +{ + fdiv(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index fb67a622e081..a6a2459b99be 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1236,9 +1236,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void negateFloat(FloatRegister reg) { fneg(ARMFPRegister(reg, 32), ARMFPRegister(reg, 32)); } - void divDouble(FloatRegister src, FloatRegister dest) { - fdiv(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); - } void moveFloat32(FloatRegister src, FloatRegister dest) { fmov(ARMFPRegister(dest, 32), ARMFPRegister(src, 32)); diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index 63a1a2592d72..93b8de90bdf6 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -173,6 +173,12 @@ MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) mulDouble(ScratchDoubleReg, dest); } +void +MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) +{ + as_divd(dest, dest, src); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 5c01603ce5d2..5cb936c2be2a 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -218,12 +218,6 @@ MacroAssemblerMIPSCompat::convertInt32ToFloat32(const Address& src, FloatRegiste as_cvtsw(dest, dest); } -void -MacroAssemblerMIPSCompat::divDouble(FloatRegister src, FloatRegister dest) -{ - as_divd(dest, dest, src); -} - void MacroAssemblerMIPSCompat::negateDouble(FloatRegister reg) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 27b7c38ce886..56fd0403d887 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -175,8 +175,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void divDouble(FloatRegister src, FloatRegister dest); - void negateDouble(FloatRegister reg); void inc64(AbsoluteAddress dest); diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index eb591c0086e9..605939aca57d 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -227,12 +227,6 @@ MacroAssemblerMIPS64Compat::convertInt32ToFloat32(const Address& src, FloatRegis as_cvtsw(dest, dest); } -void -MacroAssemblerMIPS64Compat::divDouble(FloatRegister src, FloatRegister dest) -{ - as_divd(dest, dest, src); -} - void MacroAssemblerMIPS64Compat::negateDouble(FloatRegister reg) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index accb2fab6f0b..5baba186fbda 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -185,8 +185,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void divDouble(FloatRegister src, FloatRegister dest); - void negateDouble(FloatRegister reg); void inc64(AbsoluteAddress dest); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 731068452f33..ccb8cdbac2b2 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -237,7 +237,6 @@ class MacroAssemblerNone : public Assembler void neg32(Register) { MOZ_CRASH(); } void negateDouble(FloatRegister) { MOZ_CRASH(); } - void divDouble(FloatRegister, FloatRegister) { MOZ_CRASH(); } template void branch32(Condition, T, S, Label*) { MOZ_CRASH(); } template void branchTest32(Condition, T, S, Label*) { MOZ_CRASH(); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index 6be35d9cea57..017b4d051bd3 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -145,6 +145,12 @@ MacroAssembler::mulDouble(FloatRegister src, FloatRegister dest) vmulsd(src, dest, dest); } +void +MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) +{ + vdivsd(src, dest, dest); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index 3d96eef0e432..55a52b144862 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -922,9 +922,6 @@ class MacroAssemblerX86Shared : public Assembler // XOR the float in a float register with -0.0. vxorps(scratch, reg, reg); // s ^ 0x80000000 } - void divDouble(FloatRegister src, FloatRegister dest) { - vdivsd(src, dest, dest); - } void convertFloat32ToDouble(FloatRegister src, FloatRegister dest) { vcvtss2sd(src, dest, dest); } From 2610c3416c848065042437f8c05bfd3b663bb39e Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:04:14 +0900 Subject: [PATCH 029/139] Bug 1229057 - Part 16: Move MacroAssembler::inc64 into generic macro assembler. r=bhackett --HG-- extra : rebase_source : 7a42f9371196a5c89baeb048565795fdff4341ee --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 17 +++++++++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 17 ------------- js/src/jit/arm/MacroAssembler-arm.h | 1 - js/src/jit/arm64/MacroAssembler-arm64-inl.h | 13 ++++++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 10 -------- js/src/jit/mips32/MacroAssembler-mips32-inl.h | 18 ++++++++++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 18 -------------- js/src/jit/mips32/MacroAssembler-mips32.h | 1 - js/src/jit/mips64/MacroAssembler-mips64-inl.h | 9 +++++++ js/src/jit/mips64/MacroAssembler-mips64.cpp | 9 ------- js/src/jit/mips64/MacroAssembler-mips64.h | 1 - js/src/jit/none/MacroAssembler-none.h | 1 - js/src/jit/x64/MacroAssembler-x64-inl.h | 24 +++++++++---------- js/src/jit/x64/MacroAssembler-x64.h | 2 -- js/src/jit/x86/MacroAssembler-x86-inl.h | 10 ++++++++ js/src/jit/x86/MacroAssembler-x86.h | 8 ------- 17 files changed, 81 insertions(+), 80 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 3ba37039c030..cd9cf3d95722 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -777,6 +777,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void divDouble(FloatRegister src, FloatRegister dest) PER_SHARED_ARCH; + inline void inc64(AbsoluteAddress dest) PER_ARCH; + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index ebfebd759950..75825cf429ca 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -324,6 +324,23 @@ MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) ma_vdiv(dest, src, dest); } +void +MacroAssembler::inc64(AbsoluteAddress dest) +{ + ScratchRegisterScope scratch(*this); + + ma_strd(r0, r1, EDtrAddr(sp, EDtrOffImm(-8)), PreIndex); + + ma_mov(Imm32((int32_t)dest.addr), scratch); + ma_ldrd(EDtrAddr(scratch, EDtrOffImm(0)), r0, r1); + + ma_add(Imm32(1), r0, SetCC); + ma_adc(Imm32(0), r1, LeaveCC); + + ma_strd(r0, r1, EDtrAddr(scratch, EDtrOffImm(0))); + ma_ldrd(EDtrAddr(sp, EDtrOffImm(8)), r0, r1, PostIndex); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 95ef5d721335..010759d1a981 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -252,23 +252,6 @@ MacroAssemblerARM::negateDouble(FloatRegister reg) ma_vneg(reg, reg); } -void -MacroAssemblerARM::inc64(AbsoluteAddress dest) -{ - ScratchRegisterScope scratch(asMasm()); - - ma_strd(r0, r1, EDtrAddr(sp, EDtrOffImm(-8)), PreIndex); - - ma_mov(Imm32((int32_t)dest.addr), scratch); - ma_ldrd(EDtrAddr(scratch, EDtrOffImm(0)), r0, r1); - - ma_add(Imm32(1), r0, SetCC); - ma_adc(Imm32(0), r1, LeaveCC); - - ma_strd(r0, r1, EDtrAddr(scratch, EDtrOffImm(0))); - ma_ldrd(EDtrAddr(sp, EDtrOffImm(8)), r0, r1, PostIndex); -} - bool MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, SBit s, Condition c) diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index e7f2ac843507..6d39e1fd692e 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -98,7 +98,6 @@ class MacroAssemblerARM : public Assembler void convertInt32ToFloat32(const Address& src, FloatRegister dest); void negateDouble(FloatRegister reg); - void inc64(AbsoluteAddress dest); // Somewhat direct wrappers for the low-level assembler funcitons // bitops. Attempt to encode a virtual alu instruction using two real diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 2e3f9bef8696..27dbfc412169 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -365,6 +365,19 @@ MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) fdiv(ARMFPRegister(dest, 64), ARMFPRegister(dest, 64), ARMFPRegister(src, 64)); } +void +MacroAssembler::inc64(AbsoluteAddress dest) +{ + vixl::UseScratchRegisterScope temps(this); + const ARMRegister scratchAddr64 = temps.AcquireX(); + const ARMRegister scratch64 = temps.AcquireX(); + + Mov(scratchAddr64, uint64_t(dest.addr)); + Ldr(scratch64, MemOperand(scratchAddr64, 0)); + Add(scratch64, scratch64, Operand(1)); + Str(scratch64, MemOperand(scratchAddr64, 0)); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index a6a2459b99be..91bdef1d0c7d 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -2880,16 +2880,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler Add(scratch32, scratch32, Operand(1)); store32(scratch32.asUnsized(), addr); } - void inc64(AbsoluteAddress dest) { - vixl::UseScratchRegisterScope temps(this); - const ARMRegister scratchAddr64 = temps.AcquireX(); - const ARMRegister scratch64 = temps.AcquireX(); - - Mov(scratchAddr64, uint64_t(dest.addr)); - Ldr(scratch64, MemOperand(scratchAddr64, 0)); - Add(scratch64, scratch64, Operand(1)); - Str(scratch64, MemOperand(scratchAddr64, 0)); - } void BoundsCheck(Register ptrReg, Label* onFail, vixl::CPURegister zeroMe = vixl::NoReg) { // use tst rather than Tst to *ensure* that a single instrution is generated. diff --git a/js/src/jit/mips32/MacroAssembler-mips32-inl.h b/js/src/jit/mips32/MacroAssembler-mips32-inl.h index 858fd6e0b637..9dab27f7d5d4 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32-inl.h +++ b/js/src/jit/mips32/MacroAssembler-mips32-inl.h @@ -177,6 +177,24 @@ MacroAssembler::mulBy3(Register src, Register dest) as_addu(dest, dest, src); } +void +MacroAssembler::inc64(AbsoluteAddress dest) +{ + ma_li(ScratchRegister, Imm32((int32_t)dest.addr)); + as_lw(SecondScratchReg, ScratchRegister, 0); + + as_addiu(SecondScratchReg, SecondScratchReg, 1); + as_sw(SecondScratchReg, ScratchRegister, 0); + + as_sltiu(SecondScratchReg, SecondScratchReg, 1); + as_lw(ScratchRegister, ScratchRegister, 4); + + as_addu(SecondScratchReg, ScratchRegister, SecondScratchReg); + + ma_li(ScratchRegister, Imm32((int32_t)dest.addr)); + as_sw(SecondScratchReg, ScratchRegister, 4); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 5cb936c2be2a..94d52ee1be14 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -224,24 +224,6 @@ MacroAssemblerMIPSCompat::negateDouble(FloatRegister reg) as_negd(reg, reg); } -void -MacroAssemblerMIPSCompat::inc64(AbsoluteAddress dest) -{ - ma_li(ScratchRegister, Imm32((int32_t)dest.addr)); - as_lw(SecondScratchReg, ScratchRegister, 0); - - as_addiu(SecondScratchReg, SecondScratchReg, 1); - as_sw(SecondScratchReg, ScratchRegister, 0); - - as_sltiu(SecondScratchReg, SecondScratchReg, 1); - as_lw(ScratchRegister, ScratchRegister, 4); - - as_addu(SecondScratchReg, ScratchRegister, SecondScratchReg); - - ma_li(ScratchRegister, Imm32((int32_t)dest.addr)); - as_sw(SecondScratchReg, ScratchRegister, 4); -} - void MacroAssemblerMIPS::ma_li(Register dest, CodeOffset* label) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 56fd0403d887..f317fbabe367 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -176,7 +176,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void convertInt32ToFloat32(const Address& src, FloatRegister dest); void negateDouble(FloatRegister reg); - void inc64(AbsoluteAddress dest); void computeScaledAddress(const BaseIndex& address, Register dest); diff --git a/js/src/jit/mips64/MacroAssembler-mips64-inl.h b/js/src/jit/mips64/MacroAssembler-mips64-inl.h index b8ca7af4d246..10f4a785d4c3 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64-inl.h +++ b/js/src/jit/mips64/MacroAssembler-mips64-inl.h @@ -135,6 +135,15 @@ MacroAssembler::mulBy3(Register src, Register dest) as_daddu(dest, dest, src); } +void +MacroAssembler::inc64(AbsoluteAddress dest) +{ + ma_li(ScratchRegister, ImmWord(uintptr_t(dest.addr))); + as_ld(SecondScratchReg, ScratchRegister, 0); + as_daddiu(SecondScratchReg, SecondScratchReg, 1); + as_sd(SecondScratchReg, ScratchRegister, 0); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index 605939aca57d..eac2053efc62 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -233,15 +233,6 @@ MacroAssemblerMIPS64Compat::negateDouble(FloatRegister reg) as_negd(reg, reg); } -void -MacroAssemblerMIPS64Compat::inc64(AbsoluteAddress dest) -{ - ma_li(ScratchRegister, ImmWord(uintptr_t(dest.addr))); - as_ld(SecondScratchReg, ScratchRegister, 0); - as_daddiu(SecondScratchReg, SecondScratchReg, 1); - as_sd(SecondScratchReg, ScratchRegister, 0); -} - void MacroAssemblerMIPS64Compat::movq(Register rs, Register rd) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 5baba186fbda..0711982f1876 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -186,7 +186,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void convertInt32ToFloat32(const Address& src, FloatRegister dest); void negateDouble(FloatRegister reg); - void inc64(AbsoluteAddress dest); void movq(Register rs, Register rd); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index ccb8cdbac2b2..882107c1a693 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -416,7 +416,6 @@ class MacroAssemblerNone : public Assembler void convertUInt32ToDouble(Register, FloatRegister) { MOZ_CRASH(); } void convertUInt32ToFloat32(Register, FloatRegister) { MOZ_CRASH(); } - void inc64(AbsoluteAddress) { MOZ_CRASH(); } void incrementInt32Value(Address) { MOZ_CRASH(); } void ensureDouble(ValueOperand, FloatRegister, Label*) { MOZ_CRASH(); } void handleFailureWithHandlerTail(void*) { MOZ_CRASH(); } diff --git a/js/src/jit/x64/MacroAssembler-x64-inl.h b/js/src/jit/x64/MacroAssembler-x64-inl.h index 4c0fbafe86ca..02b18b4b3bd2 100644 --- a/js/src/jit/x64/MacroAssembler-x64-inl.h +++ b/js/src/jit/x64/MacroAssembler-x64-inl.h @@ -174,6 +174,18 @@ MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) vmulsd(Operand(ScratchReg, 0), dest, dest); } +void +MacroAssembler::inc64(AbsoluteAddress dest) +{ + if (X86Encoding::IsAddressImmediate(dest.addr)) { + addPtr(Imm32(1), dest); + } else { + ScratchRegisterScope scratch(*this); + mov(ImmPtr(dest.addr), scratch); + addPtr(Imm32(1), Address(scratch, 0)); + } +} + // =============================================================== // Shift functions @@ -210,18 +222,6 @@ MacroAssembler::rshift64(Imm32 imm, Register64 dest) //}}} check_macroassembler_style // =============================================================== -void -MacroAssemblerX64::inc64(AbsoluteAddress dest) -{ - if (X86Encoding::IsAddressImmediate(dest.addr)) { - asMasm().addPtr(Imm32(1), dest); - } else { - ScratchRegisterScope scratch(asMasm()); - mov(ImmPtr(dest.addr), scratch); - asMasm().addPtr(Imm32(1), Address(scratch, 0)); - } -} - void MacroAssemblerX64::incrementInt32Value(const Address& addr) { diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index b3ad21684685..08c51b7d70d2 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -1295,8 +1295,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared vcvtsi2sdq(src.reg, dest); } - inline void inc64(AbsoluteAddress dest); - inline void incrementInt32Value(const Address& addr); // If source is a double, load it into dest. If source is int32, diff --git a/js/src/jit/x86/MacroAssembler-x86-inl.h b/js/src/jit/x86/MacroAssembler-x86-inl.h index dd368e0b49d1..3c6342ecc5fd 100644 --- a/js/src/jit/x86/MacroAssembler-x86-inl.h +++ b/js/src/jit/x86/MacroAssembler-x86-inl.h @@ -210,6 +210,16 @@ MacroAssembler::mulDoublePtr(ImmPtr imm, Register temp, FloatRegister dest) vmulsd(Operand(temp, 0), dest, dest); } +void +MacroAssembler::inc64(AbsoluteAddress dest) +{ + addl(Imm32(1), Operand(dest)); + Label noOverflow; + j(NonZero, &noOverflow); + addl(Imm32(1), Operand(dest.offset(4))); + bind(&noOverflow); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index 6a09c4099407..75aa45aaae6e 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -1030,14 +1030,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void convertUInt64ToDouble(Register64 src, Register temp, FloatRegister dest); - void inc64(AbsoluteAddress dest) { - addl(Imm32(1), Operand(dest)); - Label noOverflow; - j(NonZero, &noOverflow); - addl(Imm32(1), Operand(dest.offset(4))); - bind(&noOverflow); - } - void incrementInt32Value(const Address& addr) { addl(Imm32(1), payloadOf(addr)); } From 112088dfd3d60f01740d729b4bd70ea88662ef4e Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:04:22 +0900 Subject: [PATCH 030/139] Bug 1229057 - Part 17: Move MacroAssembler::neg32 into generic macro assembler. r=bhackett --HG-- extra : rebase_source : dd91eec870d7197c3238fe7ae5caac443385394f --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.h | 3 --- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 6 ++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 4 ---- js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h | 6 ++++++ js/src/jit/mips32/MacroAssembler-mips32.h | 3 --- js/src/jit/mips64/MacroAssembler-mips64.h | 4 ---- js/src/jit/none/MacroAssembler-none.h | 2 -- js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h | 6 ++++++ js/src/jit/x86-shared/MacroAssembler-x86-shared.h | 3 --- 11 files changed, 26 insertions(+), 19 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index cd9cf3d95722..988d4f4860c2 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -779,6 +779,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void inc64(AbsoluteAddress dest) PER_ARCH; + inline void neg32(Register reg) PER_SHARED_ARCH; + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 75825cf429ca..502229bccb3a 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -341,6 +341,12 @@ MacroAssembler::inc64(AbsoluteAddress dest) ma_ldrd(EDtrAddr(sp, EDtrOffImm(8)), r0, r1, PostIndex); } +void +MacroAssembler::neg32(Register reg) +{ + ma_neg(reg, reg, SetCC); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index 6d39e1fd692e..d8cc9a928954 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -633,9 +633,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_bx(scratch); } - void neg32(Register reg) { - ma_neg(reg, reg, SetCC); - } void negl(Register reg) { ma_neg(reg, reg, SetCC); } diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 27dbfc412169..2518a7cacbca 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -378,6 +378,12 @@ MacroAssembler::inc64(AbsoluteAddress dest) Str(scratch64, MemOperand(scratchAddr64, 0)); } +void +MacroAssembler::neg32(Register reg) +{ + Negs(ARMRegister(reg, 32), Operand(ARMRegister(reg, 32))); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 91bdef1d0c7d..2d7b96f994ed 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -814,10 +814,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler BufferOffset movePatchablePtr(ImmWord ptr, Register dest); BufferOffset movePatchablePtr(ImmPtr ptr, Register dest); - void neg32(Register reg) { - Negs(ARMRegister(reg, 32), Operand(ARMRegister(reg, 32))); - } - void loadPtr(wasm::SymbolicAddress address, Register dest) { vixl::UseScratchRegisterScope temps(this); const ARMRegister scratch = temps.AcquireX(); diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index 93b8de90bdf6..e592432b30af 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -179,6 +179,12 @@ MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) as_divd(dest, dest, src); } +void +MacroAssembler::neg32(Register reg) +{ + ma_negu(reg, reg); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index f317fbabe367..09d98638a106 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -300,9 +300,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS branch(code); } - void neg32(Register reg) { - ma_negu(reg, reg); - } void negl(Register reg) { ma_negu(reg, reg); } diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 0711982f1876..327437d65e6e 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -323,10 +323,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 branch(code); } - void neg32(Register reg) { - ma_negu(reg, reg); - } - void splitTag(Register src, Register dest) { ma_dsrl(dest, src, Imm32(JSVAL_TAG_SHIFT)); } diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index 882107c1a693..a29c88f7aafb 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -234,8 +234,6 @@ class MacroAssemblerNone : public Assembler template void cmpPtrSet(Condition, T, S, Register) { MOZ_CRASH(); } template void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); } - void neg32(Register) { MOZ_CRASH(); } - void negateDouble(FloatRegister) { MOZ_CRASH(); } template void branch32(Condition, T, S, Label*) { MOZ_CRASH(); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index 017b4d051bd3..5833ec7dab64 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -151,6 +151,12 @@ MacroAssembler::divDouble(FloatRegister src, FloatRegister dest) vdivsd(src, dest, dest); } +void +MacroAssembler::neg32(Register reg) +{ + negl(reg); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index 55a52b144862..8b6603eee77b 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -175,9 +175,6 @@ class MacroAssemblerX86Shared : public Assembler void move32(Register src, const Operand& dest) { movl(src, dest); } - void neg32(Register reg) { - negl(reg); - } void test32(Register lhs, Register rhs) { testl(rhs, lhs); } From e30c67bbde22656f9033c92f040c496572d468ef Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:04:30 +0900 Subject: [PATCH 031/139] Bug 1229057 - Part 18: Move MacroAssembler::negateFloat into generic macro assembler. r=bbouvier --HG-- extra : rebase_source : 2843fd59b35b8c2dacfb73c03e9bf6e78ecd8efa --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm64/MacroAssembler-arm64-inl.h | 6 ++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 3 --- js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h | 11 +++++++++++ js/src/jit/x86-shared/MacroAssembler-x86-shared.h | 8 -------- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 988d4f4860c2..df103e826bdc 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -781,6 +781,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void neg32(Register reg) PER_SHARED_ARCH; + inline void negateFloat(FloatRegister reg) DEFINED_ON(arm64, x86_shared); + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 2518a7cacbca..9f877fc63a4a 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -384,6 +384,12 @@ MacroAssembler::neg32(Register reg) Negs(ARMRegister(reg, 32), Operand(ARMRegister(reg, 32))); } +void +MacroAssembler::negateFloat(FloatRegister reg) +{ + fneg(ARMFPRegister(reg, 32), ARMFPRegister(reg, 32)); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index 2d7b96f994ed..b5ecc871b57f 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1229,9 +1229,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void negateDouble(FloatRegister reg) { fneg(ARMFPRegister(reg, 64), ARMFPRegister(reg, 64)); } - void negateFloat(FloatRegister reg) { - fneg(ARMFPRegister(reg, 32), ARMFPRegister(reg, 32)); - } void moveFloat32(FloatRegister src, FloatRegister dest) { fmov(ARMFPRegister(dest, 32), ARMFPRegister(src, 32)); diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index 5833ec7dab64..f403d0020e73 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -157,6 +157,17 @@ MacroAssembler::neg32(Register reg) negl(reg); } +void +MacroAssembler::negateFloat(FloatRegister reg) +{ + ScratchFloat32Scope scratch(*this); + vpcmpeqw(scratch, scratch, scratch); + vpsllq(Imm32(31), scratch, scratch); + + // XOR the float in a float register with -0.0. + vxorps(scratch, reg, reg); // s ^ 0x80000000 +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index 8b6603eee77b..6a7ea512b6d8 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -911,14 +911,6 @@ class MacroAssemblerX86Shared : public Assembler // XOR the float in a float register with -0.0. vxorpd(scratch, reg, reg); // s ^ 0x80000000000000 } - void negateFloat(FloatRegister reg) { - ScratchFloat32Scope scratch(asMasm()); - vpcmpeqw(scratch, scratch, scratch); - vpsllq(Imm32(31), scratch, scratch); - - // XOR the float in a float register with -0.0. - vxorps(scratch, reg, reg); // s ^ 0x80000000 - } void convertFloat32ToDouble(FloatRegister src, FloatRegister dest) { vcvtss2sd(src, dest, dest); } From bce64ea8534282887f12d0892c6e368551c3e816 Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Tue, 1 Dec 2015 17:04:39 +0900 Subject: [PATCH 032/139] Bug 1229057 - Part 19: Move MacroAssembler::negateDouble into generic macro assembler. r=bbouvier --HG-- extra : rebase_source : 80373877c472b41810ef5d01565fc947b94fa8b3 --- js/src/jit/MacroAssembler.h | 2 ++ js/src/jit/arm/MacroAssembler-arm-inl.h | 6 ++++++ js/src/jit/arm/MacroAssembler-arm.cpp | 6 ------ js/src/jit/arm/MacroAssembler-arm.h | 2 -- js/src/jit/arm64/MacroAssembler-arm64-inl.h | 6 ++++++ js/src/jit/arm64/MacroAssembler-arm64.h | 3 --- .../jit/mips-shared/MacroAssembler-mips-shared-inl.h | 6 ++++++ js/src/jit/mips32/MacroAssembler-mips32.cpp | 6 ------ js/src/jit/mips32/MacroAssembler-mips32.h | 2 -- js/src/jit/mips64/MacroAssembler-mips64.cpp | 6 ------ js/src/jit/mips64/MacroAssembler-mips64.h | 2 -- js/src/jit/none/MacroAssembler-none.h | 2 -- .../jit/x86-shared/MacroAssembler-x86-shared-inl.h | 12 ++++++++++++ js/src/jit/x86-shared/MacroAssembler-x86-shared.h | 9 --------- 14 files changed, 32 insertions(+), 38 deletions(-) diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index df103e826bdc..d3830609d578 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -783,6 +783,8 @@ class MacroAssembler : public MacroAssemblerSpecific inline void negateFloat(FloatRegister reg) DEFINED_ON(arm64, x86_shared); + inline void negateDouble(FloatRegister reg) PER_SHARED_ARCH; + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm-inl.h b/js/src/jit/arm/MacroAssembler-arm-inl.h index 502229bccb3a..61edf6d9e473 100644 --- a/js/src/jit/arm/MacroAssembler-arm-inl.h +++ b/js/src/jit/arm/MacroAssembler-arm-inl.h @@ -347,6 +347,12 @@ MacroAssembler::neg32(Register reg) ma_neg(reg, reg, SetCC); } +void +MacroAssembler::negateDouble(FloatRegister reg) +{ + ma_vneg(reg, reg); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 010759d1a981..b72779ef8f91 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -246,12 +246,6 @@ MacroAssemblerARM::convertInt32ToFloat32(const Address& src, FloatRegister dest) as_vcvt(dest, VFPRegister(scratch).sintOverlay()); } -void -MacroAssemblerARM::negateDouble(FloatRegister reg) -{ - ma_vneg(reg, reg); -} - bool MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, SBit s, Condition c) diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index d8cc9a928954..f563ef05a6fb 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -97,8 +97,6 @@ class MacroAssemblerARM : public Assembler void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void negateDouble(FloatRegister reg); - // Somewhat direct wrappers for the low-level assembler funcitons // bitops. Attempt to encode a virtual alu instruction using two real // instructions. diff --git a/js/src/jit/arm64/MacroAssembler-arm64-inl.h b/js/src/jit/arm64/MacroAssembler-arm64-inl.h index 9f877fc63a4a..d1046efd873c 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64-inl.h +++ b/js/src/jit/arm64/MacroAssembler-arm64-inl.h @@ -390,6 +390,12 @@ MacroAssembler::negateFloat(FloatRegister reg) fneg(ARMFPRegister(reg, 32), ARMFPRegister(reg, 32)); } +void +MacroAssembler::negateDouble(FloatRegister reg) +{ + fneg(ARMFPRegister(reg, 64), ARMFPRegister(reg, 64)); +} + // =============================================================== // Shift functions diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index b5ecc871b57f..da13c0bc8036 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -1226,9 +1226,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler void zeroFloat32(FloatRegister reg) { fmov(ARMFPRegister(reg, 32), vixl::wzr); } - void negateDouble(FloatRegister reg) { - fneg(ARMFPRegister(reg, 64), ARMFPRegister(reg, 64)); - } void moveFloat32(FloatRegister src, FloatRegister dest) { fmov(ARMFPRegister(dest, 32), ARMFPRegister(src, 32)); diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h index e592432b30af..2e00baf5c76a 100644 --- a/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h +++ b/js/src/jit/mips-shared/MacroAssembler-mips-shared-inl.h @@ -185,6 +185,12 @@ MacroAssembler::neg32(Register reg) ma_negu(reg, reg); } +void +MacroAssembler::negateDouble(FloatRegister reg) +{ + as_negd(reg, reg); +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/mips32/MacroAssembler-mips32.cpp b/js/src/jit/mips32/MacroAssembler-mips32.cpp index 94d52ee1be14..955933670025 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.cpp +++ b/js/src/jit/mips32/MacroAssembler-mips32.cpp @@ -218,12 +218,6 @@ MacroAssemblerMIPSCompat::convertInt32ToFloat32(const Address& src, FloatRegiste as_cvtsw(dest, dest); } -void -MacroAssemblerMIPSCompat::negateDouble(FloatRegister reg) -{ - as_negd(reg, reg); -} - void MacroAssemblerMIPS::ma_li(Register dest, CodeOffset* label) { diff --git a/js/src/jit/mips32/MacroAssembler-mips32.h b/js/src/jit/mips32/MacroAssembler-mips32.h index 09d98638a106..ce85e06f1d65 100644 --- a/js/src/jit/mips32/MacroAssembler-mips32.h +++ b/js/src/jit/mips32/MacroAssembler-mips32.h @@ -175,8 +175,6 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void negateDouble(FloatRegister reg); - void computeScaledAddress(const BaseIndex& address, Register dest); void computeEffectiveAddress(const Address& address, Register dest) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index eac2053efc62..8cbe3c729940 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -227,12 +227,6 @@ MacroAssemblerMIPS64Compat::convertInt32ToFloat32(const Address& src, FloatRegis as_cvtsw(dest, dest); } -void -MacroAssemblerMIPS64Compat::negateDouble(FloatRegister reg) -{ - as_negd(reg, reg); -} - void MacroAssemblerMIPS64Compat::movq(Register rs, Register rd) { diff --git a/js/src/jit/mips64/MacroAssembler-mips64.h b/js/src/jit/mips64/MacroAssembler-mips64.h index 327437d65e6e..fd92de94f38c 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.h +++ b/js/src/jit/mips64/MacroAssembler-mips64.h @@ -185,8 +185,6 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 void convertInt32ToFloat32(Register src, FloatRegister dest); void convertInt32ToFloat32(const Address& src, FloatRegister dest); - void negateDouble(FloatRegister reg); - void movq(Register rs, Register rd); void computeScaledAddress(const BaseIndex& address, Register dest); diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index a29c88f7aafb..4120c478ed5e 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -234,8 +234,6 @@ class MacroAssemblerNone : public Assembler template void cmpPtrSet(Condition, T, S, Register) { MOZ_CRASH(); } template void cmp32Set(Condition, T, S, Register) { MOZ_CRASH(); } - void negateDouble(FloatRegister) { MOZ_CRASH(); } - template void branch32(Condition, T, S, Label*) { MOZ_CRASH(); } template void branchTest32(Condition, T, S, Label*) { MOZ_CRASH(); } template void branchAdd32(Condition, T, S, Label*) { MOZ_CRASH(); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h index f403d0020e73..f04e3e068361 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared-inl.h @@ -168,6 +168,18 @@ MacroAssembler::negateFloat(FloatRegister reg) vxorps(scratch, reg, reg); // s ^ 0x80000000 } +void +MacroAssembler::negateDouble(FloatRegister reg) +{ + // From MacroAssemblerX86Shared::maybeInlineDouble + ScratchDoubleScope scratch(*this); + vpcmpeqw(scratch, scratch, scratch); + vpsllq(Imm32(63), scratch, scratch); + + // XOR the float in a float register with -0.0. + vxorpd(scratch, reg, reg); // s ^ 0x80000000000000 +} + //}}} check_macroassembler_style // =============================================================== diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index 6a7ea512b6d8..0ef4774febd2 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -902,15 +902,6 @@ class MacroAssemblerX86Shared : public Assembler void zeroFloat32(FloatRegister reg) { vxorps(reg, reg, reg); } - void negateDouble(FloatRegister reg) { - // From MacroAssemblerX86Shared::maybeInlineDouble - ScratchDoubleScope scratch(asMasm()); - vpcmpeqw(scratch, scratch, scratch); - vpsllq(Imm32(63), scratch, scratch); - - // XOR the float in a float register with -0.0. - vxorpd(scratch, reg, reg); // s ^ 0x80000000000000 - } void convertFloat32ToDouble(FloatRegister src, FloatRegister dest) { vcvtss2sd(src, dest, dest); } From 8ee23ffd62f99299f639aadc5d4b8956a3aafd6c Mon Sep 17 00:00:00 2001 From: Tooru Fujisawa Date: Sun, 1 Nov 2015 20:55:15 +0900 Subject: [PATCH 033/139] Bug 1220457 - Show deprecation warning for non-standard RegExp.multiline. r=till --HG-- extra : rebase_source : 3a13f3373f5a5babf32b09a992dc2f2eee6d2f08 --- js/src/builtin/RegExp.cpp | 35 +++++++++++++++++-- .../tests/basic/regexp-multiline-warning.js | 23 ++++++++++++ js/src/js.msg | 1 + js/src/jscompartment.cpp | 1 + js/src/jscompartment.h | 1 + js/src/vm/Xdr.h | 4 +-- 6 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 js/src/jit-test/tests/basic/regexp-multiline-warning.js diff --git a/js/src/builtin/RegExp.cpp b/js/src/builtin/RegExp.cpp index 8d6c4a1b7c31..1758a149c90e 100644 --- a/js/src/builtin/RegExp.cpp +++ b/js/src/builtin/RegExp.cpp @@ -610,8 +610,6 @@ const JSFunctionSpec js::regexp_methods[] = { } DEFINE_STATIC_GETTER(static_input_getter, return res->createPendingInput(cx, args.rval())) -DEFINE_STATIC_GETTER(static_multiline_getter, args.rval().setBoolean(res->multiline()); - return true) DEFINE_STATIC_GETTER(static_lastMatch_getter, return res->createLastMatch(cx, args.rval())) DEFINE_STATIC_GETTER(static_lastParen_getter, return res->createLastParen(cx, args.rval())) DEFINE_STATIC_GETTER(static_leftContext_getter, return res->createLeftContext(cx, args.rval())) @@ -655,6 +653,36 @@ static_input_setter(JSContext* cx, unsigned argc, Value* vp) return true; } +static bool +WarnOnceAboutRegExpMultiline(JSContext* cx) +{ + if (!cx->compartment()->warnedAboutRegExpMultiline) { + if (!JS_ReportErrorFlagsAndNumber(cx, JSREPORT_WARNING, GetErrorMessage, nullptr, + JSMSG_DEPRECATED_REGEXP_MULTILINE)) + { + return false; + } + cx->compartment()->warnedAboutRegExpMultiline = true; + } + + return true; +} + +static bool +static_multiline_getter(JSContext* cx, unsigned argc, Value* vp) +{ + CallArgs args = CallArgsFromVp(argc, vp); + RegExpStatics* res = cx->global()->getRegExpStatics(cx); + if (!res) + return false; + + if (!WarnOnceAboutRegExpMultiline(cx)) + return false; + + args.rval().setBoolean(res->multiline()); + return true; +} + static bool static_multiline_setter(JSContext* cx, unsigned argc, Value* vp) { @@ -663,6 +691,9 @@ static_multiline_setter(JSContext* cx, unsigned argc, Value* vp) if (!res) return false; + if (!WarnOnceAboutRegExpMultiline(cx)) + return false; + bool b = ToBoolean(args.get(0)); res->setMultiline(cx, b); args.rval().setBoolean(b); diff --git a/js/src/jit-test/tests/basic/regexp-multiline-warning.js b/js/src/jit-test/tests/basic/regexp-multiline-warning.js new file mode 100644 index 000000000000..91760f86f63e --- /dev/null +++ b/js/src/jit-test/tests/basic/regexp-multiline-warning.js @@ -0,0 +1,23 @@ +// RegExp.multiline access should be warned once and only once. + +function testWarn(code) { + enableLastWarning(); + var g = newGlobal(); + g.code = code; + g.eval('eval(code)'); + var warning = getLastWarning(); + assertEq(warning !== null, true, "warning should be caught for " + code); + assertEq(warning.name, "SyntaxError"); + + clearLastWarning(); + g.eval('eval(code)'); + warning = getLastWarning(); + assertEq(warning, null, "warning should not be caught for 2nd ocurrence"); + disableLastWarning(); +} + +testWarn("var a = RegExp.multiline;"); +testWarn("RegExp.multiline = true;"); + +testWarn("var a = RegExp['$*'];"); +testWarn("RegExp['$*'] = true;"); diff --git a/js/src/js.msg b/js/src/js.msg index bcc25ebe14f7..6fbe70d416b6 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -444,6 +444,7 @@ MSG_DEF(JSMSG_UNDEFINED_CURRENCY, 0, JSEXN_TYPEERR, "undefined currency in // RegExp MSG_DEF(JSMSG_BAD_CLASS_RANGE, 0, JSEXN_SYNTAXERR, "invalid range in character class") +MSG_DEF(JSMSG_DEPRECATED_REGEXP_MULTILINE, 0, JSEXN_SYNTAXERR, "RegExp.multiline is deprecated. Use m flag instead") MSG_DEF(JSMSG_ESCAPE_AT_END_OF_REGEXP, 0, JSEXN_SYNTAXERR, "\\ at end of pattern") MSG_DEF(JSMSG_INVALID_GROUP, 0, JSEXN_SYNTAXERR, "invalid regexp group") MSG_DEF(JSMSG_MISSING_PAREN, 0, JSEXN_SYNTAXERR, "unterminated parenthetical") diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 548c4430a5e3..0b77258374bb 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -50,6 +50,7 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = marked(true), warnedAboutFlagsArgument(false), warnedAboutExprClosure(false), + warnedAboutRegExpMultiline(false), addonId(options.addonIdOrNull()), #ifdef DEBUG firedOnNewGlobalObject(false), diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index 96938211507a..7552cd2cf9d5 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -278,6 +278,7 @@ struct JSCompartment bool marked; bool warnedAboutFlagsArgument; bool warnedAboutExprClosure; + bool warnedAboutRegExpMultiline; // A null add-on ID means that the compartment is not associated with an // add-on. diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index 67ad02c37a39..b034d7928b85 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -29,11 +29,11 @@ namespace js { * * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode */ -static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 333; +static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 334; static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); -static_assert(JSErr_Limit == 420, +static_assert(JSErr_Limit == 421, "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or " "removed MSG_DEFs from js.msg, you should increment " "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's " From 84dbf3ea1b824d7f8a226d4edad992c8b49017ac Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 17 Dec 2015 10:59:37 +0000 Subject: [PATCH 034/139] Bug 1233065 - about:profiles in the ProfileManager should be smaller, r=ehsan, f=alice0775 --- toolkit/profile/content/profileSelection.xul | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toolkit/profile/content/profileSelection.xul b/toolkit/profile/content/profileSelection.xul index e3315e590cb0..872cb0670a4a 100644 --- a/toolkit/profile/content/profileSelection.xul +++ b/toolkit/profile/content/profileSelection.xul @@ -22,7 +22,7 @@ title="&windowtitle.label;" orient="vertical" buttons="accept,cancel" - style="width: 80em; height: 40em;" + style="width: 60em; height: 40em;" onload="startup();" ondialogaccept="return acceptDialog()" ondialogcancel="return exitDialog()" From 35ff8e160c3aa9fbe1bfb3bee54f077a84258686 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 17 Dec 2015 12:00:35 +0000 Subject: [PATCH 035/139] Bug 901097 - FileReader API in workers, r=sicking, r=nfroyd --HG-- rename : dom/base/test/fileapi_chromeScript.js => dom/workers/test/fileapi_chromeScript.js --- dom/base/FileReader.cpp | 182 ++++++-- dom/base/FileReader.h | 60 ++- dom/webidl/FileReader.webidl | 2 +- dom/workers/test/fileapi_chromeScript.js | 29 ++ dom/workers/test/mochitest.ini | 3 + .../test_serviceworker_interfaces.js | 2 + dom/workers/test/test_fileReader.html | 100 +++++ dom/workers/test/test_worker_interfaces.js | 2 + dom/workers/test/worker_fileReader.js | 417 ++++++++++++++++++ .../meta/FileAPI/idlharness.worker.js.ini | 133 ------ xpcom/io/nsStreamUtils.cpp | 53 ++- xpcom/threads/TimerThread.cpp | 28 +- xpcom/threads/nsICancelableRunnable.idl | 1 + 13 files changed, 807 insertions(+), 205 deletions(-) create mode 100644 dom/workers/test/fileapi_chromeScript.js create mode 100644 dom/workers/test/test_fileReader.html create mode 100644 dom/workers/test/worker_fileReader.js diff --git a/dom/base/FileReader.cpp b/dom/base/FileReader.cpp index 10bfea467d35..ae94b0d72ef1 100644 --- a/dom/base/FileReader.cpp +++ b/dom/base/FileReader.cpp @@ -6,34 +6,34 @@ #include "FileReader.h" -#include "nsContentCID.h" -#include "nsContentUtils.h" -#include "nsDOMClassInfoID.h" -#include "nsError.h" -#include "nsIFile.h" -#include "nsNetCID.h" -#include "nsNetUtil.h" +#include "nsIEventTarget.h" +#include "nsIGlobalObject.h" +#include "nsITimer.h" +#include "nsITransport.h" +#include "nsIStreamTransportService.h" -#include "nsXPCOM.h" -#include "nsIDOMEventListener.h" -#include "nsJSEnvironment.h" -#include "nsCycleCollectionParticipant.h" #include "mozilla/Base64.h" +#include "mozilla/dom/DOMError.h" #include "mozilla/dom/EncodingUtils.h" #include "mozilla/dom/File.h" #include "mozilla/dom/FileReaderBinding.h" #include "mozilla/dom/ProgressEvent.h" -#include "xpcpublic.h" +#include "nsContentUtils.h" +#include "nsCycleCollectionParticipant.h" #include "nsDOMJSUtils.h" +#include "nsError.h" +#include "nsNetCID.h" +#include "nsNetUtil.h" +#include "xpcpublic.h" -#include "jsfriendapi.h" - -#include "nsITransport.h" -#include "nsIStreamTransportService.h" +#include "WorkerPrivate.h" +#include "WorkerScope.h" namespace mozilla { namespace dom { +using namespace workers; + #define ABORT_STR "abort" #define LOAD_STR "load" #define LOADSTART_STR "loadstart" @@ -56,7 +56,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileReader, DOMEventTargetHelper) - tmp->mResultArrayBuffer = nullptr; + tmp->Shutdown(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mBlob) NS_IMPL_CYCLE_COLLECTION_UNLINK(mProgressNotifier) NS_IMPL_CYCLE_COLLECTION_UNLINK(mError) @@ -76,6 +76,20 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(FileReader, DOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(FileReader, DOMEventTargetHelper) +class MOZ_RAII FileReaderDecreaseBusyCounter +{ + RefPtr mFileReader; +public: + explicit FileReaderDecreaseBusyCounter(FileReader* aFileReader) + : mFileReader(aFileReader) + {} + + ~FileReaderDecreaseBusyCounter() + { + mFileReader->DecreaseBusyCounter(); + } +}; + void FileReader::RootResultArrayBuffer() { @@ -84,7 +98,8 @@ FileReader::RootResultArrayBuffer() //FileReader constructors/initializers -FileReader::FileReader(nsPIDOMWindow* aWindow) +FileReader::FileReader(nsPIDOMWindow* aWindow, + WorkerPrivate* aWorkerPrivate) : DOMEventTargetHelper(aWindow) , mFileData(nullptr) , mDataLen(0) @@ -95,15 +110,19 @@ FileReader::FileReader(nsPIDOMWindow* aWindow) , mReadyState(EMPTY) , mTotal(0) , mTransferred(0) + , mTarget(do_GetCurrentThread()) + , mBusyCount(0) + , mWorkerPrivate(aWorkerPrivate) { + MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerPrivate && !aWindow); + MOZ_ASSERT_IF(NS_IsMainThread(), !mWorkerPrivate); SetDOMStringToNull(mResult); } FileReader::~FileReader() { + Shutdown(); FreeFileData(); - mResultArrayBuffer = nullptr; - DropJSObjects(this); } /* static */ already_AddRefed @@ -111,9 +130,17 @@ FileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { // The owner can be null when this object is used by chrome code. nsCOMPtr owner = do_QueryInterface(aGlobal.GetAsSupports()); - RefPtr fileReader = new FileReader(owner); + WorkerPrivate* workerPrivate = nullptr; - if (!owner && nsContentUtils::IsCallerChrome()) { + if (!NS_IsMainThread()) { + JSContext* cx = aGlobal.Context(); + workerPrivate = GetWorkerPrivateFromContext(cx); + MOZ_ASSERT(workerPrivate); + } + + RefPtr fileReader = new FileReader(owner, workerPrivate); + + if (!owner && nsContentUtils::ThreadsafeIsCallerChrome()) { // Instead of grabbing some random global from the context stack, // let's use the default one (junk scope) for now. // We should move away from this Init... @@ -215,7 +242,17 @@ FileReader::DoOnLoadEnd(nsresult aStatus, switch (mDataFormat) { case FILE_AS_ARRAYBUFFER: { AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(DOMEventTargetHelper::GetParentObject()))) { + nsCOMPtr globalObject; + + if (NS_IsMainThread()) { + globalObject = do_QueryInterface(GetParentObject()); + } else { + MOZ_ASSERT(mWorkerPrivate); + MOZ_ASSERT(mBusyCount); + globalObject = mWorkerPrivate->GlobalScope(); + } + + if (!globalObject || !jsapi.Init(globalObject)) { FreeFileData(); return NS_ERROR_FAILURE; } @@ -256,9 +293,29 @@ FileReader::DoOnLoadEnd(nsresult aStatus, } nsresult -FileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) +FileReader::DoAsyncWait() { - MOZ_ASSERT(aStream); + nsresult rv = IncreaseBusyCounter(); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + rv = mAsyncStream->AsyncWait(this, + /* aFlags*/ 0, + /* aRequestedCount */ 0, + mTarget); + if (NS_WARN_IF(NS_FAILED(rv))) { + DecreaseBusyCounter(); + return rv; + } + + return NS_OK; +} + +nsresult +FileReader::DoReadData(uint64_t aCount) +{ + MOZ_ASSERT(mAsyncStream); if (mDataFormat == FILE_AS_BINARY) { //Continuously update our binary string as data comes in @@ -271,8 +328,8 @@ FileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY); uint32_t bytesRead = 0; - aStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount, - &bytesRead); + mAsyncStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount, + &bytesRead); NS_ASSERTION(bytesRead == aCount, "failed to read data"); } else { @@ -287,7 +344,7 @@ FileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) } uint32_t bytesRead = 0; - aStream->Read(mFileData + mDataLen, aCount, &bytesRead); + mAsyncStream->Read(mFileData + mDataLen, aCount, &bytesRead); NS_ASSERTION(bytesRead == aCount, "failed to read data"); } @@ -361,10 +418,7 @@ FileReader::ReadFileContent(Blob& aBlob, return; } - aRv = mAsyncStream->AsyncWait(this, - /* aFlags*/ 0, - /* aRequestedCount */ 0, - NS_GetCurrentThread()); + aRv = DoAsyncWait(); if (NS_WARN_IF(aRv.Failed())) { return; } @@ -467,6 +521,7 @@ FileReader::StartProgressEventTimer() mProgressEventWasDelayed = false; mTimerIsActive = true; mProgressNotifier->Cancel(); + mProgressNotifier->SetTarget(mTarget); mProgressNotifier->InitWithCallback(this, NS_PROGRESS_EVENT_INTERVAL, nsITimer::TYPE_ONE_SHOT); } @@ -550,18 +605,20 @@ FileReader::OnInputStreamReady(nsIAsyncInputStream* aStream) return NS_OK; } + // We use this class to decrease the busy counter at the end of this method. + // In theory we can do it immediatelly but, for debugging reasons, we want to + // be 100% sure we have a feature when OnLoadEnd() is called. + FileReaderDecreaseBusyCounter RAII(this); + uint64_t aCount; nsresult rv = aStream->Available(&aCount); if (NS_SUCCEEDED(rv) && aCount) { - rv = DoReadData(aStream, aCount); + rv = DoReadData(aCount); } if (NS_SUCCEEDED(rv)) { - rv = aStream->AsyncWait(this, - /* aFlags*/ 0, - /* aRequestedCount */ 0, - NS_GetCurrentThread()); + rv = DoAsyncWait(); } if (NS_FAILED(rv) || !aCount) { @@ -643,5 +700,56 @@ FileReader::Abort(ErrorResult& aRv) DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR)); } +nsresult +FileReader::IncreaseBusyCounter() +{ + if (mWorkerPrivate && mBusyCount++ == 0 && + !mWorkerPrivate->AddFeature(mWorkerPrivate->GetJSContext(), this)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +void +FileReader::DecreaseBusyCounter() +{ + MOZ_ASSERT_IF(mWorkerPrivate, mBusyCount); + if (mWorkerPrivate && --mBusyCount == 0) { + mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this); + } +} + +bool +FileReader::Notify(JSContext* aCx, Status aStatus) +{ + MOZ_ASSERT(mWorkerPrivate); + mWorkerPrivate->AssertIsOnWorkerThread(); + + if (aStatus > Running) { + Shutdown(); + } + + return true; +} + +void +FileReader::Shutdown() +{ + mResultArrayBuffer = nullptr; + DropJSObjects(this); + + if (mAsyncStream) { + mAsyncStream->Close(); + mAsyncStream = nullptr; + } + + if (mWorkerPrivate && mBusyCount != 0) { + mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this); + mWorkerPrivate = nullptr; + mBusyCount = 0; + } +} + } // dom namespace } // mozilla namespace diff --git a/dom/base/FileReader.h b/dom/base/FileReader.h index 7026d94a7f10..79c4bfe470b2 100644 --- a/dom/base/FileReader.h +++ b/dom/base/FileReader.h @@ -9,37 +9,45 @@ #include "mozilla/Attributes.h" #include "mozilla/DOMEventTargetHelper.h" -#include "mozilla/dom/DOMError.h" -#include "nsCOMPtr.h" #include "nsIAsyncInputStream.h" -#include "nsIStreamListener.h" -#include "nsISupportsUtils.h" #include "nsIInterfaceRequestor.h" -#include "nsITimer.h" -#include "nsJSUtils.h" +#include "nsCOMPtr.h" #include "nsString.h" -#include "nsTArray.h" #include "nsWeakReference.h" -#include "prtime.h" +#include "WorkerFeature.h" #define NS_PROGRESS_EVENT_INTERVAL 50 +class nsITimer; +class nsIEventTarget; + namespace mozilla { namespace dom { class Blob; +class DOMError; + +namespace workers { +class WorkerPrivate; +} extern const uint64_t kUnknownSize; +class FileReaderDecreaseBusyCounter; + class FileReader final : public DOMEventTargetHelper, public nsIInterfaceRequestor, public nsSupportsWeakReference, public nsIInputStreamCallback, - public nsITimerCallback + public nsITimerCallback, + public workers::WorkerFeature { + friend class FileReaderDecreaseBusyCounter; + public: - explicit FileReader(nsPIDOMWindow* aWindow); + FileReader(nsPIDOMWindow* aWindow, + workers::WorkerPrivate* aWorkerPrivate); NS_DECL_ISUPPORTS_INHERITED @@ -47,9 +55,11 @@ public: NS_DECL_NSIINPUTSTREAMCALLBACK NS_DECL_NSIINTERFACEREQUESTOR - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FileReader, DOMEventTargetHelper) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FileReader, + DOMEventTargetHelper) - virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; // WebIDL static already_AddRefed @@ -96,6 +106,9 @@ public: ReadFileContent(aBlob, EmptyString(), FILE_AS_BINARY, aRv); } + // WorkerFeature + bool Notify(JSContext* aCx, workers::Status) override; + private: virtual ~FileReader(); @@ -131,18 +144,26 @@ private: void DispatchError(nsresult rv, nsAString& finalEvent); nsresult DispatchProgressEvent(const nsAString& aType); - nsresult DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount); + nsresult DoAsyncWait(); + nsresult DoReadData(uint64_t aCount); nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent, nsAString& aTerminationEvent); void FreeFileData() { - free(mFileData); - mFileData = nullptr; - mDataLen = 0; + if (mFileData) { + free(mFileData); + mFileData = nullptr; + mDataLen = 0; + } } + nsresult IncreaseBusyCounter(); + void DecreaseBusyCounter(); + + void Shutdown(); + char *mFileData; RefPtr mBlob; nsCString mCharset; @@ -166,6 +187,13 @@ private: uint64_t mTotal; uint64_t mTransferred; + + nsCOMPtr mTarget; + + uint64_t mBusyCount; + + // Kept alive with a WorkerFeature. + workers::WorkerPrivate* mWorkerPrivate; }; } // dom namespace diff --git a/dom/webidl/FileReader.webidl b/dom/webidl/FileReader.webidl index b4bea2540589..f3647aea423f 100644 --- a/dom/webidl/FileReader.webidl +++ b/dom/webidl/FileReader.webidl @@ -11,7 +11,7 @@ */ [Constructor, - Exposed=(Window,System)] + Exposed=(Window,Worker,System)] interface FileReader : EventTarget { // async read methods [Throws] diff --git a/dom/workers/test/fileapi_chromeScript.js b/dom/workers/test/fileapi_chromeScript.js new file mode 100644 index 000000000000..85f80a60b2be --- /dev/null +++ b/dom/workers/test/fileapi_chromeScript.js @@ -0,0 +1,29 @@ +var { classes: Cc, interfaces: Ci, utils: Cu } = Components; +Cu.importGlobalProperties(["File"]); + +var fileNum = 1; + +function createFileWithData(fileData) { + var willDelete = fileData === null; + var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); + var testFile = dirSvc.get("ProfD", Ci.nsIFile); + testFile.append("fileAPItestfile" + fileNum); + fileNum++; + var outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); + outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate + 0666, 0); + if (willDelete) { + fileData = "some irrelevant test data\n"; + } + outStream.write(fileData, fileData.length); + outStream.close(); + var domFile = new File(testFile); + if (willDelete) { + testFile.remove(/* recursive: */ false); + } + return domFile; +} + +addMessageListener("files.open", function (message) { + sendAsyncMessage("files.opened", message.map(createFileWithData)); +}); diff --git a/dom/workers/test/mochitest.ini b/dom/workers/test/mochitest.ini index daaed889a151..7bb3539b3d16 100644 --- a/dom/workers/test/mochitest.ini +++ b/dom/workers/test/mochitest.ini @@ -119,6 +119,8 @@ support-files = worker_referrer.js websocket_https.html websocket_https_worker.js + worker_fileReader.js + fileapi_chromeScript.js [test_404.html] [test_atob.html] @@ -236,3 +238,4 @@ skip-if = (os == "win") || (os == "mac") || toolkit == 'android' #bug 798220 [test_referrer.html] [test_sharedWorker_ports.html] [test_sharedWorker_lifetime.html] +[test_fileReader.html] diff --git a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js index 98a472882a6c..122d984c33e6 100644 --- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js +++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js @@ -114,6 +114,8 @@ var interfaceNamesInGlobalScope = "FetchEvent", // IMPORTANT: Do not change this list without review from a DOM peer! "File", +// IMPORTANT: Do not change this list without review from a DOM peer! + "FileReader", // IMPORTANT: Do not change this list without review from a DOM peer! "FileReaderSync", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/workers/test/test_fileReader.html b/dom/workers/test/test_fileReader.html new file mode 100644 index 000000000000..26e73bdb64f1 --- /dev/null +++ b/dom/workers/test/test_fileReader.html @@ -0,0 +1,100 @@ + + + + Test for FileReader in workers + + + + + + + + diff --git a/dom/workers/test/test_worker_interfaces.js b/dom/workers/test/test_worker_interfaces.js index bf02b1901324..bf343596a285 100644 --- a/dom/workers/test/test_worker_interfaces.js +++ b/dom/workers/test/test_worker_interfaces.js @@ -106,6 +106,8 @@ var interfaceNamesInGlobalScope = "EventTarget", // IMPORTANT: Do not change this list without review from a DOM peer! "File", +// IMPORTANT: Do not change this list without review from a DOM peer! + "FileReader", // IMPORTANT: Do not change this list without review from a DOM peer! "FileReaderSync", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/workers/test/worker_fileReader.js b/dom/workers/test/worker_fileReader.js new file mode 100644 index 000000000000..f4e91b325e0f --- /dev/null +++ b/dom/workers/test/worker_fileReader.js @@ -0,0 +1,417 @@ +var testRanCounter = 0; +var expectedTestCount = 0; +var testSetupFinished = false; + +function ok(a, msg) { + postMessage({type: 'check', status: !!a, msg: msg }); +} + +function is(a, b, msg) { + ok(a === b, msg); +} + +function finish() { + postMessage({type: 'finish'}); +} + +function convertToUTF16(s) { + res = ""; + for (var i = 0; i < s.length; ++i) { + c = s.charCodeAt(i); + res += String.fromCharCode(c & 255, c >>> 8); + } + return res; +} + +function convertToUTF8(s) { + return unescape(encodeURIComponent(s)); +} + +function convertToDataURL(s) { + return "data:application/octet-stream;base64," + btoa(s); +} + +onmessage = function(message) { + is(FileReader.EMPTY, 0, "correct EMPTY value"); + is(FileReader.LOADING, 1, "correct LOADING value"); + is(FileReader.DONE, 2, "correct DONE value"); + + // List of blobs. + var asciiFile = message.data.blobs.shift(); + var binaryFile = message.data.blobs.shift(); + var nonExistingFile = message.data.blobs.shift(); + var utf8TextFile = message.data.blobs.shift(); + var utf16TextFile = message.data.blobs.shift(); + var emptyFile = message.data.blobs.shift(); + var dataUrlFile0 = message.data.blobs.shift(); + var dataUrlFile1 = message.data.blobs.shift(); + var dataUrlFile2 = message.data.blobs.shift(); + + // List of buffers for testing. + var testTextData = message.data.testTextData; + var testASCIIData = message.data.testASCIIData; + var testBinaryData = message.data.testBinaryData; + var dataurldata0 = message.data.dataurldata0; + var dataurldata1 = message.data.dataurldata1; + var dataurldata2 = message.data.dataurldata2; + + // Test that plain reading works and fires events as expected, both + // for text and binary reading + + var onloadHasRunText = false; + var onloadStartHasRunText = false; + r = new FileReader(); + is(r.readyState, FileReader.EMPTY, "correct initial text readyState"); + r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "plain reading"); + r.addEventListener("load", function() { onloadHasRunText = true }, false); + r.addEventListener("loadstart", function() { onloadStartHasRunText = true }, false); + r.readAsText(asciiFile); + is(r.readyState, FileReader.LOADING, "correct loading text readyState"); + is(onloadHasRunText, false, "text loading must be async"); + is(onloadStartHasRunText, true, "text loadstart should fire sync"); + expectedTestCount++; + + var onloadHasRunBinary = false; + var onloadStartHasRunBinary = false; + r = new FileReader(); + is(r.readyState, FileReader.EMPTY, "correct initial binary readyState"); + r.addEventListener("load", function() { onloadHasRunBinary = true }, false); + r.addEventListener("loadstart", function() { onloadStartHasRunBinary = true }, false); + r.readAsBinaryString(binaryFile); + r.onload = getLoadHandler(testBinaryData, testBinaryData.length, "binary reading"); + is(r.readyState, FileReader.LOADING, "correct loading binary readyState"); + is(onloadHasRunBinary, false, "binary loading must be async"); + is(onloadStartHasRunBinary, true, "binary loadstart should fire sync"); + expectedTestCount++; + + var onloadHasRunArrayBuffer = false; + var onloadStartHasRunArrayBuffer = false; + r = new FileReader(); + is(r.readyState, FileReader.EMPTY, "correct initial arrayBuffer readyState"); + r.addEventListener("load", function() { onloadHasRunArrayBuffer = true }, false); + r.addEventListener("loadstart", function() { onloadStartHasRunArrayBuffer = true }, false); + r.readAsArrayBuffer(binaryFile); + r.onload = getLoadHandlerForArrayBuffer(testBinaryData, testBinaryData.length, "array buffer reading"); + is(r.readyState, FileReader.LOADING, "correct loading arrayBuffer readyState"); + is(onloadHasRunArrayBuffer, false, "arrayBuffer loading must be async"); + is(onloadStartHasRunArrayBuffer, true, "arrayBuffer loadstart should fire sync"); + expectedTestCount++; + + // Test a variety of encodings, and make sure they work properly + r = new FileReader(); + r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "no encoding reading"); + r.readAsText(asciiFile, ""); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "iso8859 reading"); + r.readAsText(asciiFile, "iso-8859-1"); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler(testTextData, + convertToUTF8(testTextData).length, + "utf8 reading"); + r.readAsText(utf8TextFile, "utf8"); + expectedTestCount++; + + r = new FileReader(); + r.readAsText(utf16TextFile, "utf-16"); + r.onload = getLoadHandler(testTextData, + convertToUTF16(testTextData).length, + "utf16 reading"); + expectedTestCount++; + + // Test get result without reading + r = new FileReader(); + is(r.readyState, FileReader.EMPTY, + "readyState in test reader get result without reading"); + is(r.error, null, + "no error in test reader get result without reading"); + is(r.result, null, + "result in test reader get result without reading"); + + // Test loading an empty file works (and doesn't crash!) + r = new FileReader(); + r.onload = getLoadHandler("", 0, "empty no encoding reading"); + r.readAsText(emptyFile, ""); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler("", 0, "empty utf8 reading"); + r.readAsText(emptyFile, "utf8"); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler("", 0, "empty utf16 reading"); + r.readAsText(emptyFile, "utf-16"); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler("", 0, "empty binary string reading"); + r.readAsBinaryString(emptyFile); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandlerForArrayBuffer("", 0, "empty array buffer reading"); + r.readAsArrayBuffer(emptyFile); + expectedTestCount++; + + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(""), 0, "empt binary string reading"); + r.readAsDataURL(emptyFile); + expectedTestCount++; + + // Test reusing a FileReader to read multiple times + r = new FileReader(); + r.onload = getLoadHandler(testASCIIData, + testASCIIData.length, + "to-be-reused reading text") + var makeAnotherReadListener = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener, false); + r.onload = getLoadHandler(testASCIIData, + testASCIIData.length, + "reused reading text"); + r.readAsText(asciiFile); + }; + r.addEventListener("load", makeAnotherReadListener, false); + r.readAsText(asciiFile); + expectedTestCount += 2; + + r = new FileReader(); + r.onload = getLoadHandler(testBinaryData, + testBinaryData.length, + "to-be-reused reading binary") + var makeAnotherReadListener2 = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener2, false); + r.onload = getLoadHandler(testBinaryData, + testBinaryData.length, + "reused reading binary"); + r.readAsBinaryString(binaryFile); + }; + r.addEventListener("load", makeAnotherReadListener2, false); + r.readAsBinaryString(binaryFile); + expectedTestCount += 2; + + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(testBinaryData), + testBinaryData.length, + "to-be-reused reading data url") + var makeAnotherReadListener3 = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener3, false); + r.onload = getLoadHandler(convertToDataURL(testBinaryData), + testBinaryData.length, + "reused reading data url"); + r.readAsDataURL(binaryFile); + }; + r.addEventListener("load", makeAnotherReadListener3, false); + r.readAsDataURL(binaryFile); + expectedTestCount += 2; + + r = new FileReader(); + r.onload = getLoadHandlerForArrayBuffer(testBinaryData, + testBinaryData.length, + "to-be-reused reading arrayBuffer") + var makeAnotherReadListener4 = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener4, false); + r.onload = getLoadHandlerForArrayBuffer(testBinaryData, + testBinaryData.length, + "reused reading arrayBuffer"); + r.readAsArrayBuffer(binaryFile); + }; + r.addEventListener("load", makeAnotherReadListener4, false); + r.readAsArrayBuffer(binaryFile); + expectedTestCount += 2; + + // Test first reading as ArrayBuffer then read as something else + // (BinaryString) and doesn't crash + r = new FileReader(); + r.onload = getLoadHandlerForArrayBuffer(testBinaryData, + testBinaryData.length, + "to-be-reused reading arrayBuffer") + var makeAnotherReadListener5 = function(event) { + r = event.target; + r.removeEventListener("load", makeAnotherReadListener5, false); + r.onload = getLoadHandler(testBinaryData, + testBinaryData.length, + "reused reading binary string"); + r.readAsBinaryString(binaryFile); + }; + r.addEventListener("load", makeAnotherReadListener5, false); + r.readAsArrayBuffer(binaryFile); + expectedTestCount += 2; + + //Test data-URI encoding on differing file sizes + is(dataurldata0.length % 3, 0, "Want to test data with length % 3 == 0"); + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(dataurldata0), + dataurldata0.length, + "dataurl reading, %3 = 0"); + r.readAsDataURL(dataUrlFile0); + expectedTestCount++; + + is(dataurldata1.length % 3, 1, "Want to test data with length % 3 == 1"); + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(dataurldata1), + dataurldata1.length, + "dataurl reading, %3 = 1"); + r.readAsDataURL(dataUrlFile1); + expectedTestCount++; + + is(dataurldata2.length % 3, 2, "Want to test data with length % 3 == 2"); + r = new FileReader(); + r.onload = getLoadHandler(convertToDataURL(dataurldata2), + dataurldata2.length, + "dataurl reading, %3 = 2"); + r.readAsDataURL(dataUrlFile2), + expectedTestCount++; + + + // Test abort() + var abortHasRun = false; + var loadEndHasRun = false; + r = new FileReader(); + r.onabort = function (event) { + is(abortHasRun, false, "abort should only fire once"); + is(loadEndHasRun, false, "loadend shouldn't have fired yet"); + abortHasRun = true; + is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); + is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); + is(event.target.result, null, "file data should be null on aborted reads"); + } + r.onloadend = function (event) { + is(abortHasRun, true, "abort should fire before loadend"); + is(loadEndHasRun, false, "loadend should only fire once"); + loadEndHasRun = true; + is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); + is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); + is(event.target.result, null, "file data should be null on aborted reads"); + } + r.onload = function() { ok(false, "load should not fire for aborted reads") }; + r.onerror = function() { ok(false, "error should not fire for aborted reads") }; + r.onprogress = function() { ok(false, "progress should not fire for aborted reads") }; + var abortThrew = false; + try { + r.abort(); + } catch(e) { + abortThrew = true; + } + is(abortThrew, true, "abort() must throw if not loading"); + is(abortHasRun, false, "abort() is a no-op unless loading"); + r.readAsText(asciiFile); + r.abort(); + is(abortHasRun, true, "abort should fire sync"); + is(loadEndHasRun, true, "loadend should fire sync"); + + // Test calling readAsX to cause abort() + var reuseAbortHasRun = false; + r = new FileReader(); + r.onabort = function (event) { + is(reuseAbortHasRun, false, "abort should only fire once"); + reuseAbortHasRun = true; + is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); + is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); + is(event.target.result, null, "file data should be null on aborted reads"); + } + r.onload = function() { ok(false, "load should not fire for aborted reads") }; + var abortThrew = false; + try { + r.abort(); + } catch(e) { + abortThrew = true; + } + is(abortThrew, true, "abort() must throw if not loading"); + is(reuseAbortHasRun, false, "abort() is a no-op unless loading"); + r.readAsText(asciiFile); + r.readAsText(asciiFile); + is(reuseAbortHasRun, true, "abort should fire sync"); + r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "reuse-as-abort reading"); + expectedTestCount++; + + + // Test reading from nonexistent files + r = new FileReader(); + var didThrow = false; + r.onerror = function (event) { + is(event.target.readyState, FileReader.DONE, "should be DONE while firing onerror"); + is(event.target.error.name, "NotFoundError", "error set to NotFoundError for nonexistent files"); + is(event.target.result, null, "file data should be null on aborted reads"); + testHasRun(); + }; + r.onload = function (event) { + is(false, "nonexistent file shouldn't load! (FIXME: bug 1122788)"); + testHasRun(); + }; + try { + r.readAsDataURL(nonExistingFile); + expectedTestCount++; + } catch(ex) { + didThrow = true; + } + // Once this test passes, we should test that onerror gets called and + // that the FileReader object is in the right state during that call. + is(didThrow, false, "shouldn't throw when opening nonexistent file, should fire error instead"); + + + function getLoadHandler(expectedResult, expectedLength, testName) { + return function (event) { + is(event.target.readyState, FileReader.DONE, + "readyState in test " + testName); + is(event.target.error, null, + "no error in test " + testName); + is(event.target.result, expectedResult, + "result in test " + testName); + is(event.lengthComputable, true, + "lengthComputable in test " + testName); + is(event.loaded, expectedLength, + "loaded in test " + testName); + is(event.total, expectedLength, + "total in test " + testName); + testHasRun(); + } + } + + function getLoadHandlerForArrayBuffer(expectedResult, expectedLength, testName) { + return function (event) { + is(event.target.readyState, FileReader.DONE, + "readyState in test " + testName); + is(event.target.error, null, + "no error in test " + testName); + is(event.lengthComputable, true, + "lengthComputable in test " + testName); + is(event.loaded, expectedLength, + "loaded in test " + testName); + is(event.total, expectedLength, + "total in test " + testName); + is(event.target.result.byteLength, expectedLength, + "array buffer size in test " + testName); + var u8v = new Uint8Array(event.target.result); + is(String.fromCharCode.apply(String, u8v), expectedResult, + "array buffer contents in test " + testName); + u8v = null; + is(event.target.result.byteLength, expectedLength, + "array buffer size after gc in test " + testName); + u8v = new Uint8Array(event.target.result); + is(String.fromCharCode.apply(String, u8v), expectedResult, + "array buffer contents after gc in test " + testName); + testHasRun(); + } + } + + function testHasRun() { + //alert(testRanCounter); + ++testRanCounter; + if (testRanCounter == expectedTestCount) { + is(testSetupFinished, true, "test setup should have finished; check for exceptions"); + is(onloadHasRunText, true, "onload text should have fired by now"); + is(onloadHasRunBinary, true, "onload binary should have fired by now"); + finish(); + } + } + + testSetupFinished = true; +} diff --git a/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini b/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini index 1519b7d55402..37b8a3949920 100644 --- a/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini +++ b/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini @@ -41,136 +41,3 @@ [FileList interface: attribute length] expected: FAIL - - [FileReader interface: existence and properties of interface object] - expected: FAIL - - [FileReader interface object length] - expected: FAIL - - [FileReader interface: existence and properties of interface prototype object] - expected: FAIL - - [FileReader interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [FileReader interface: operation readAsArrayBuffer(Blob)] - expected: FAIL - - [FileReader interface: operation readAsText(Blob,DOMString)] - expected: FAIL - - [FileReader interface: operation readAsDataURL(Blob)] - expected: FAIL - - [FileReader interface: operation abort()] - expected: FAIL - - [FileReader interface: constant EMPTY on interface object] - expected: FAIL - - [FileReader interface: constant EMPTY on interface prototype object] - expected: FAIL - - [FileReader interface: constant LOADING on interface object] - expected: FAIL - - [FileReader interface: constant LOADING on interface prototype object] - expected: FAIL - - [FileReader interface: constant DONE on interface object] - expected: FAIL - - [FileReader interface: constant DONE on interface prototype object] - expected: FAIL - - [FileReader interface: attribute readyState] - expected: FAIL - - [FileReader interface: attribute result] - expected: FAIL - - [FileReader interface: attribute error] - expected: FAIL - - [FileReader interface: attribute onloadstart] - expected: FAIL - - [FileReader interface: attribute onprogress] - expected: FAIL - - [FileReader interface: attribute onload] - expected: FAIL - - [FileReader interface: attribute onabort] - expected: FAIL - - [FileReader interface: attribute onerror] - expected: FAIL - - [FileReader interface: attribute onloadend] - expected: FAIL - - [FileReader must be primary interface of new FileReader()] - expected: FAIL - - [Stringification of new FileReader()] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "readAsArrayBuffer" with the proper type (0)] - expected: FAIL - - [FileReader interface: calling readAsArrayBuffer(Blob) on new FileReader() with too few arguments must throw TypeError] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "readAsText" with the proper type (1)] - expected: FAIL - - [FileReader interface: calling readAsText(Blob,DOMString) on new FileReader() with too few arguments must throw TypeError] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "readAsDataURL" with the proper type (2)] - expected: FAIL - - [FileReader interface: calling readAsDataURL(Blob) on new FileReader() with too few arguments must throw TypeError] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "abort" with the proper type (3)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "EMPTY" with the proper type (4)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "LOADING" with the proper type (5)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "DONE" with the proper type (6)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "readyState" with the proper type (7)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "result" with the proper type (8)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "error" with the proper type (9)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "onloadstart" with the proper type (10)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "onprogress" with the proper type (11)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "onload" with the proper type (12)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "onabort" with the proper type (13)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "onerror" with the proper type (14)] - expected: FAIL - - [FileReader interface: new FileReader() must inherit property "onloadend" with the proper type (15)] - expected: FAIL - diff --git a/xpcom/io/nsStreamUtils.cpp b/xpcom/io/nsStreamUtils.cpp index 9fdcfcd3ddc0..a95dad33e11a 100644 --- a/xpcom/io/nsStreamUtils.cpp +++ b/xpcom/io/nsStreamUtils.cpp @@ -12,7 +12,7 @@ #include "nsIPipe.h" #include "nsICloneableInputStream.h" #include "nsIEventTarget.h" -#include "nsIRunnable.h" +#include "nsICancelableRunnable.h" #include "nsISafeOutputStream.h" #include "nsString.h" #include "nsIAsyncInputStream.h" @@ -25,8 +25,11 @@ using namespace mozilla; //----------------------------------------------------------------------------- +// This is a nsICancelableRunnable because we can dispatch it to Workers and +// those can be shut down at any time, and in these cases, Cancel() is called +// instead of Run(). class nsInputStreamReadyEvent final - : public nsIRunnable + : public nsICancelableRunnable , public nsIInputStreamCallback { public: @@ -95,19 +98,28 @@ public: return NS_OK; } + NS_IMETHOD Cancel() override + { + mCallback = nullptr; + return NS_OK; + } + private: nsCOMPtr mStream; nsCOMPtr mCallback; nsCOMPtr mTarget; }; -NS_IMPL_ISUPPORTS(nsInputStreamReadyEvent, nsIRunnable, - nsIInputStreamCallback) +NS_IMPL_ISUPPORTS(nsInputStreamReadyEvent, nsICancelableRunnable, + nsIRunnable, nsIInputStreamCallback) //----------------------------------------------------------------------------- +// This is a nsICancelableRunnable because we can dispatch it to Workers and +// those can be shut down at any time, and in these cases, Cancel() is called +// instead of Run(). class nsOutputStreamReadyEvent final - : public nsIRunnable + : public nsICancelableRunnable , public nsIOutputStreamCallback { public: @@ -176,14 +188,20 @@ public: return NS_OK; } + NS_IMETHOD Cancel() override + { + mCallback = nullptr; + return NS_OK; + } + private: nsCOMPtr mStream; nsCOMPtr mCallback; nsCOMPtr mTarget; }; -NS_IMPL_ISUPPORTS(nsOutputStreamReadyEvent, nsIRunnable, - nsIOutputStreamCallback) +NS_IMPL_ISUPPORTS(nsOutputStreamReadyEvent, nsICancelableRunnable, + nsIRunnable, nsIOutputStreamCallback) //----------------------------------------------------------------------------- @@ -216,7 +234,7 @@ NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback* aCallback, class nsAStreamCopier : public nsIInputStreamCallback , public nsIOutputStreamCallback - , public nsIRunnable + , public nsICancelableRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS @@ -433,6 +451,8 @@ public: return NS_OK; } + NS_IMETHOD Cancel() MOZ_MUST_OVERRIDE override = 0; + nsresult PostContinuationEvent() { // we cannot post a continuation event if there is currently @@ -489,6 +509,7 @@ protected: NS_IMPL_ISUPPORTS(nsAStreamCopier, nsIInputStreamCallback, nsIOutputStreamCallback, + nsICancelableRunnable, nsIRunnable) class nsStreamCopierIB final : public nsAStreamCopier @@ -527,7 +548,8 @@ public: return state->mSinkCondition; } - uint32_t DoCopy(nsresult* aSourceCondition, nsresult* aSinkCondition) + uint32_t DoCopy(nsresult* aSourceCondition, + nsresult* aSinkCondition) override { ReadSegmentsState state; state.mSink = mSink; @@ -539,6 +561,11 @@ public: *aSinkCondition = state.mSinkCondition; return n; } + + NS_IMETHOD Cancel() override + { + return NS_OK; + } }; class nsStreamCopierOB final : public nsAStreamCopier @@ -577,7 +604,8 @@ public: return state->mSourceCondition; } - uint32_t DoCopy(nsresult* aSourceCondition, nsresult* aSinkCondition) + uint32_t DoCopy(nsresult* aSourceCondition, + nsresult* aSinkCondition) override { WriteSegmentsState state; state.mSource = mSource; @@ -589,6 +617,11 @@ public: *aSourceCondition = state.mSourceCondition; return n; } + + NS_IMETHOD Cancel() override + { + return NS_OK; + } }; //----------------------------------------------------------------------------- diff --git a/xpcom/threads/TimerThread.cpp b/xpcom/threads/TimerThread.cpp index 9eeda7a93c7d..7e032607e7ca 100644 --- a/xpcom/threads/TimerThread.cpp +++ b/xpcom/threads/TimerThread.cpp @@ -127,10 +127,23 @@ public: } // namespace -class nsTimerEvent : public nsRunnable +// This is a nsICancelableRunnable because we can dispatch it to Workers and +// those can be shut down at any time, and in these cases, Cancel() is called +// instead of Run(). +class nsTimerEvent : public nsCancelableRunnable { public: - NS_IMETHOD Run(); + NS_IMETHOD Run() override; + + NS_IMETHOD Cancel() override + { + // Since nsTimerImpl is not thread-safe, we should release |mTimer| + // here in the target thread to avoid race condition. Otherwise, + // ~nsTimerEvent() which calls nsTimerImpl::Release() could run in the + // timer thread and result in race condition. + mTimer = nullptr; + return NS_OK; + } nsTimerEvent() : mTimer() @@ -253,6 +266,8 @@ nsTimerEvent::DeleteAllocatorIfNeeded() NS_IMETHODIMP nsTimerEvent::Run() { + MOZ_ASSERT(mTimer); + if (mGeneration != mTimer->GetGeneration()) { return NS_OK; } @@ -265,13 +280,10 @@ nsTimerEvent::Run() } mTimer->Fire(); - // Since nsTimerImpl is not thread-safe, we should release |mTimer| - // here in the target thread to avoid race condition. Otherwise, - // ~nsTimerEvent() which calls nsTimerImpl::Release() could run in the - // timer thread and result in race condition. - mTimer = nullptr; - return NS_OK; + // We call Cancel() to correctly release mTimer. + // Read more in the Cancel() implementation. + return Cancel(); } nsresult diff --git a/xpcom/threads/nsICancelableRunnable.idl b/xpcom/threads/nsICancelableRunnable.idl index 44b9df477c05..11f09650c18f 100644 --- a/xpcom/threads/nsICancelableRunnable.idl +++ b/xpcom/threads/nsICancelableRunnable.idl @@ -16,6 +16,7 @@ interface nsICancelableRunnable : nsIRunnable /** * Cancels a pending task. If the task has already been executed this will * be a no-op. Calling this method twice is considered an error. + * If cancel() is called, run() will not be called. * * @throws NS_ERROR_UNEXPECTED * Indicates that the runnable has already been canceled. From fe800f661e12a5514845c85b4eee6663d30829c4 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Thu, 17 Dec 2015 14:13:59 +0100 Subject: [PATCH 036/139] Backed out changeset 30839ee209e8 (bug 901097) for mochitest failures on Android and Mulet. r=backout --- dom/base/FileReader.cpp | 182 ++------ dom/base/FileReader.h | 62 +-- dom/webidl/FileReader.webidl | 2 +- dom/workers/test/fileapi_chromeScript.js | 29 -- dom/workers/test/mochitest.ini | 3 - .../test_serviceworker_interfaces.js | 2 - dom/workers/test/test_fileReader.html | 100 ----- dom/workers/test/test_worker_interfaces.js | 2 - dom/workers/test/worker_fileReader.js | 417 ------------------ .../meta/FileAPI/idlharness.worker.js.ini | 133 ++++++ xpcom/io/nsStreamUtils.cpp | 53 +-- xpcom/threads/TimerThread.cpp | 28 +- xpcom/threads/nsICancelableRunnable.idl | 1 - 13 files changed, 206 insertions(+), 808 deletions(-) delete mode 100644 dom/workers/test/fileapi_chromeScript.js delete mode 100644 dom/workers/test/test_fileReader.html delete mode 100644 dom/workers/test/worker_fileReader.js diff --git a/dom/base/FileReader.cpp b/dom/base/FileReader.cpp index ae94b0d72ef1..10bfea467d35 100644 --- a/dom/base/FileReader.cpp +++ b/dom/base/FileReader.cpp @@ -6,34 +6,34 @@ #include "FileReader.h" -#include "nsIEventTarget.h" -#include "nsIGlobalObject.h" -#include "nsITimer.h" -#include "nsITransport.h" -#include "nsIStreamTransportService.h" +#include "nsContentCID.h" +#include "nsContentUtils.h" +#include "nsDOMClassInfoID.h" +#include "nsError.h" +#include "nsIFile.h" +#include "nsNetCID.h" +#include "nsNetUtil.h" +#include "nsXPCOM.h" +#include "nsIDOMEventListener.h" +#include "nsJSEnvironment.h" +#include "nsCycleCollectionParticipant.h" #include "mozilla/Base64.h" -#include "mozilla/dom/DOMError.h" #include "mozilla/dom/EncodingUtils.h" #include "mozilla/dom/File.h" #include "mozilla/dom/FileReaderBinding.h" #include "mozilla/dom/ProgressEvent.h" -#include "nsContentUtils.h" -#include "nsCycleCollectionParticipant.h" -#include "nsDOMJSUtils.h" -#include "nsError.h" -#include "nsNetCID.h" -#include "nsNetUtil.h" #include "xpcpublic.h" +#include "nsDOMJSUtils.h" -#include "WorkerPrivate.h" -#include "WorkerScope.h" +#include "jsfriendapi.h" + +#include "nsITransport.h" +#include "nsIStreamTransportService.h" namespace mozilla { namespace dom { -using namespace workers; - #define ABORT_STR "abort" #define LOAD_STR "load" #define LOADSTART_STR "loadstart" @@ -56,7 +56,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileReader, DOMEventTargetHelper) - tmp->Shutdown(); + tmp->mResultArrayBuffer = nullptr; NS_IMPL_CYCLE_COLLECTION_UNLINK(mBlob) NS_IMPL_CYCLE_COLLECTION_UNLINK(mProgressNotifier) NS_IMPL_CYCLE_COLLECTION_UNLINK(mError) @@ -76,20 +76,6 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) NS_IMPL_ADDREF_INHERITED(FileReader, DOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(FileReader, DOMEventTargetHelper) -class MOZ_RAII FileReaderDecreaseBusyCounter -{ - RefPtr mFileReader; -public: - explicit FileReaderDecreaseBusyCounter(FileReader* aFileReader) - : mFileReader(aFileReader) - {} - - ~FileReaderDecreaseBusyCounter() - { - mFileReader->DecreaseBusyCounter(); - } -}; - void FileReader::RootResultArrayBuffer() { @@ -98,8 +84,7 @@ FileReader::RootResultArrayBuffer() //FileReader constructors/initializers -FileReader::FileReader(nsPIDOMWindow* aWindow, - WorkerPrivate* aWorkerPrivate) +FileReader::FileReader(nsPIDOMWindow* aWindow) : DOMEventTargetHelper(aWindow) , mFileData(nullptr) , mDataLen(0) @@ -110,19 +95,15 @@ FileReader::FileReader(nsPIDOMWindow* aWindow, , mReadyState(EMPTY) , mTotal(0) , mTransferred(0) - , mTarget(do_GetCurrentThread()) - , mBusyCount(0) - , mWorkerPrivate(aWorkerPrivate) { - MOZ_ASSERT_IF(!NS_IsMainThread(), mWorkerPrivate && !aWindow); - MOZ_ASSERT_IF(NS_IsMainThread(), !mWorkerPrivate); SetDOMStringToNull(mResult); } FileReader::~FileReader() { - Shutdown(); FreeFileData(); + mResultArrayBuffer = nullptr; + DropJSObjects(this); } /* static */ already_AddRefed @@ -130,17 +111,9 @@ FileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv) { // The owner can be null when this object is used by chrome code. nsCOMPtr owner = do_QueryInterface(aGlobal.GetAsSupports()); - WorkerPrivate* workerPrivate = nullptr; + RefPtr fileReader = new FileReader(owner); - if (!NS_IsMainThread()) { - JSContext* cx = aGlobal.Context(); - workerPrivate = GetWorkerPrivateFromContext(cx); - MOZ_ASSERT(workerPrivate); - } - - RefPtr fileReader = new FileReader(owner, workerPrivate); - - if (!owner && nsContentUtils::ThreadsafeIsCallerChrome()) { + if (!owner && nsContentUtils::IsCallerChrome()) { // Instead of grabbing some random global from the context stack, // let's use the default one (junk scope) for now. // We should move away from this Init... @@ -242,17 +215,7 @@ FileReader::DoOnLoadEnd(nsresult aStatus, switch (mDataFormat) { case FILE_AS_ARRAYBUFFER: { AutoJSAPI jsapi; - nsCOMPtr globalObject; - - if (NS_IsMainThread()) { - globalObject = do_QueryInterface(GetParentObject()); - } else { - MOZ_ASSERT(mWorkerPrivate); - MOZ_ASSERT(mBusyCount); - globalObject = mWorkerPrivate->GlobalScope(); - } - - if (!globalObject || !jsapi.Init(globalObject)) { + if (NS_WARN_IF(!jsapi.Init(DOMEventTargetHelper::GetParentObject()))) { FreeFileData(); return NS_ERROR_FAILURE; } @@ -293,29 +256,9 @@ FileReader::DoOnLoadEnd(nsresult aStatus, } nsresult -FileReader::DoAsyncWait() +FileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) { - nsresult rv = IncreaseBusyCounter(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = mAsyncStream->AsyncWait(this, - /* aFlags*/ 0, - /* aRequestedCount */ 0, - mTarget); - if (NS_WARN_IF(NS_FAILED(rv))) { - DecreaseBusyCounter(); - return rv; - } - - return NS_OK; -} - -nsresult -FileReader::DoReadData(uint64_t aCount) -{ - MOZ_ASSERT(mAsyncStream); + MOZ_ASSERT(aStream); if (mDataFormat == FILE_AS_BINARY) { //Continuously update our binary string as data comes in @@ -328,8 +271,8 @@ FileReader::DoReadData(uint64_t aCount) NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY); uint32_t bytesRead = 0; - mAsyncStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount, - &bytesRead); + aStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount, + &bytesRead); NS_ASSERTION(bytesRead == aCount, "failed to read data"); } else { @@ -344,7 +287,7 @@ FileReader::DoReadData(uint64_t aCount) } uint32_t bytesRead = 0; - mAsyncStream->Read(mFileData + mDataLen, aCount, &bytesRead); + aStream->Read(mFileData + mDataLen, aCount, &bytesRead); NS_ASSERTION(bytesRead == aCount, "failed to read data"); } @@ -418,7 +361,10 @@ FileReader::ReadFileContent(Blob& aBlob, return; } - aRv = DoAsyncWait(); + aRv = mAsyncStream->AsyncWait(this, + /* aFlags*/ 0, + /* aRequestedCount */ 0, + NS_GetCurrentThread()); if (NS_WARN_IF(aRv.Failed())) { return; } @@ -521,7 +467,6 @@ FileReader::StartProgressEventTimer() mProgressEventWasDelayed = false; mTimerIsActive = true; mProgressNotifier->Cancel(); - mProgressNotifier->SetTarget(mTarget); mProgressNotifier->InitWithCallback(this, NS_PROGRESS_EVENT_INTERVAL, nsITimer::TYPE_ONE_SHOT); } @@ -605,20 +550,18 @@ FileReader::OnInputStreamReady(nsIAsyncInputStream* aStream) return NS_OK; } - // We use this class to decrease the busy counter at the end of this method. - // In theory we can do it immediatelly but, for debugging reasons, we want to - // be 100% sure we have a feature when OnLoadEnd() is called. - FileReaderDecreaseBusyCounter RAII(this); - uint64_t aCount; nsresult rv = aStream->Available(&aCount); if (NS_SUCCEEDED(rv) && aCount) { - rv = DoReadData(aCount); + rv = DoReadData(aStream, aCount); } if (NS_SUCCEEDED(rv)) { - rv = DoAsyncWait(); + rv = aStream->AsyncWait(this, + /* aFlags*/ 0, + /* aRequestedCount */ 0, + NS_GetCurrentThread()); } if (NS_FAILED(rv) || !aCount) { @@ -700,56 +643,5 @@ FileReader::Abort(ErrorResult& aRv) DispatchProgressEvent(NS_LITERAL_STRING(LOADEND_STR)); } -nsresult -FileReader::IncreaseBusyCounter() -{ - if (mWorkerPrivate && mBusyCount++ == 0 && - !mWorkerPrivate->AddFeature(mWorkerPrivate->GetJSContext(), this)) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -void -FileReader::DecreaseBusyCounter() -{ - MOZ_ASSERT_IF(mWorkerPrivate, mBusyCount); - if (mWorkerPrivate && --mBusyCount == 0) { - mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this); - } -} - -bool -FileReader::Notify(JSContext* aCx, Status aStatus) -{ - MOZ_ASSERT(mWorkerPrivate); - mWorkerPrivate->AssertIsOnWorkerThread(); - - if (aStatus > Running) { - Shutdown(); - } - - return true; -} - -void -FileReader::Shutdown() -{ - mResultArrayBuffer = nullptr; - DropJSObjects(this); - - if (mAsyncStream) { - mAsyncStream->Close(); - mAsyncStream = nullptr; - } - - if (mWorkerPrivate && mBusyCount != 0) { - mWorkerPrivate->RemoveFeature(mWorkerPrivate->GetJSContext(), this); - mWorkerPrivate = nullptr; - mBusyCount = 0; - } -} - } // dom namespace } // mozilla namespace diff --git a/dom/base/FileReader.h b/dom/base/FileReader.h index 79c4bfe470b2..7026d94a7f10 100644 --- a/dom/base/FileReader.h +++ b/dom/base/FileReader.h @@ -9,45 +9,37 @@ #include "mozilla/Attributes.h" #include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/dom/DOMError.h" -#include "nsIAsyncInputStream.h" -#include "nsIInterfaceRequestor.h" #include "nsCOMPtr.h" +#include "nsIAsyncInputStream.h" +#include "nsIStreamListener.h" +#include "nsISupportsUtils.h" +#include "nsIInterfaceRequestor.h" +#include "nsITimer.h" +#include "nsJSUtils.h" #include "nsString.h" +#include "nsTArray.h" #include "nsWeakReference.h" -#include "WorkerFeature.h" +#include "prtime.h" #define NS_PROGRESS_EVENT_INTERVAL 50 -class nsITimer; -class nsIEventTarget; - namespace mozilla { namespace dom { class Blob; -class DOMError; - -namespace workers { -class WorkerPrivate; -} extern const uint64_t kUnknownSize; -class FileReaderDecreaseBusyCounter; - class FileReader final : public DOMEventTargetHelper, public nsIInterfaceRequestor, public nsSupportsWeakReference, public nsIInputStreamCallback, - public nsITimerCallback, - public workers::WorkerFeature + public nsITimerCallback { - friend class FileReaderDecreaseBusyCounter; - public: - FileReader(nsPIDOMWindow* aWindow, - workers::WorkerPrivate* aWorkerPrivate); + explicit FileReader(nsPIDOMWindow* aWindow); NS_DECL_ISUPPORTS_INHERITED @@ -55,11 +47,9 @@ public: NS_DECL_NSIINPUTSTREAMCALLBACK NS_DECL_NSIINTERFACEREQUESTOR - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FileReader, - DOMEventTargetHelper) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FileReader, DOMEventTargetHelper) - virtual JSObject* WrapObject(JSContext* aCx, - JS::Handle aGivenProto) override; + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; // WebIDL static already_AddRefed @@ -106,9 +96,6 @@ public: ReadFileContent(aBlob, EmptyString(), FILE_AS_BINARY, aRv); } - // WorkerFeature - bool Notify(JSContext* aCx, workers::Status) override; - private: virtual ~FileReader(); @@ -144,26 +131,18 @@ private: void DispatchError(nsresult rv, nsAString& finalEvent); nsresult DispatchProgressEvent(const nsAString& aType); - nsresult DoAsyncWait(); - nsresult DoReadData(uint64_t aCount); + nsresult DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount); nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent, nsAString& aTerminationEvent); void FreeFileData() { - if (mFileData) { - free(mFileData); - mFileData = nullptr; - mDataLen = 0; - } + free(mFileData); + mFileData = nullptr; + mDataLen = 0; } - nsresult IncreaseBusyCounter(); - void DecreaseBusyCounter(); - - void Shutdown(); - char *mFileData; RefPtr mBlob; nsCString mCharset; @@ -187,13 +166,6 @@ private: uint64_t mTotal; uint64_t mTransferred; - - nsCOMPtr mTarget; - - uint64_t mBusyCount; - - // Kept alive with a WorkerFeature. - workers::WorkerPrivate* mWorkerPrivate; }; } // dom namespace diff --git a/dom/webidl/FileReader.webidl b/dom/webidl/FileReader.webidl index f3647aea423f..b4bea2540589 100644 --- a/dom/webidl/FileReader.webidl +++ b/dom/webidl/FileReader.webidl @@ -11,7 +11,7 @@ */ [Constructor, - Exposed=(Window,Worker,System)] + Exposed=(Window,System)] interface FileReader : EventTarget { // async read methods [Throws] diff --git a/dom/workers/test/fileapi_chromeScript.js b/dom/workers/test/fileapi_chromeScript.js deleted file mode 100644 index 85f80a60b2be..000000000000 --- a/dom/workers/test/fileapi_chromeScript.js +++ /dev/null @@ -1,29 +0,0 @@ -var { classes: Cc, interfaces: Ci, utils: Cu } = Components; -Cu.importGlobalProperties(["File"]); - -var fileNum = 1; - -function createFileWithData(fileData) { - var willDelete = fileData === null; - var dirSvc = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); - var testFile = dirSvc.get("ProfD", Ci.nsIFile); - testFile.append("fileAPItestfile" + fileNum); - fileNum++; - var outStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); - outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate - 0666, 0); - if (willDelete) { - fileData = "some irrelevant test data\n"; - } - outStream.write(fileData, fileData.length); - outStream.close(); - var domFile = new File(testFile); - if (willDelete) { - testFile.remove(/* recursive: */ false); - } - return domFile; -} - -addMessageListener("files.open", function (message) { - sendAsyncMessage("files.opened", message.map(createFileWithData)); -}); diff --git a/dom/workers/test/mochitest.ini b/dom/workers/test/mochitest.ini index 7bb3539b3d16..daaed889a151 100644 --- a/dom/workers/test/mochitest.ini +++ b/dom/workers/test/mochitest.ini @@ -119,8 +119,6 @@ support-files = worker_referrer.js websocket_https.html websocket_https_worker.js - worker_fileReader.js - fileapi_chromeScript.js [test_404.html] [test_atob.html] @@ -238,4 +236,3 @@ skip-if = (os == "win") || (os == "mac") || toolkit == 'android' #bug 798220 [test_referrer.html] [test_sharedWorker_ports.html] [test_sharedWorker_lifetime.html] -[test_fileReader.html] diff --git a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js index 122d984c33e6..98a472882a6c 100644 --- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js +++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js @@ -114,8 +114,6 @@ var interfaceNamesInGlobalScope = "FetchEvent", // IMPORTANT: Do not change this list without review from a DOM peer! "File", -// IMPORTANT: Do not change this list without review from a DOM peer! - "FileReader", // IMPORTANT: Do not change this list without review from a DOM peer! "FileReaderSync", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/workers/test/test_fileReader.html b/dom/workers/test/test_fileReader.html deleted file mode 100644 index 26e73bdb64f1..000000000000 --- a/dom/workers/test/test_fileReader.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - Test for FileReader in workers - - - - - - - - diff --git a/dom/workers/test/test_worker_interfaces.js b/dom/workers/test/test_worker_interfaces.js index bf343596a285..bf02b1901324 100644 --- a/dom/workers/test/test_worker_interfaces.js +++ b/dom/workers/test/test_worker_interfaces.js @@ -106,8 +106,6 @@ var interfaceNamesInGlobalScope = "EventTarget", // IMPORTANT: Do not change this list without review from a DOM peer! "File", -// IMPORTANT: Do not change this list without review from a DOM peer! - "FileReader", // IMPORTANT: Do not change this list without review from a DOM peer! "FileReaderSync", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/workers/test/worker_fileReader.js b/dom/workers/test/worker_fileReader.js deleted file mode 100644 index f4e91b325e0f..000000000000 --- a/dom/workers/test/worker_fileReader.js +++ /dev/null @@ -1,417 +0,0 @@ -var testRanCounter = 0; -var expectedTestCount = 0; -var testSetupFinished = false; - -function ok(a, msg) { - postMessage({type: 'check', status: !!a, msg: msg }); -} - -function is(a, b, msg) { - ok(a === b, msg); -} - -function finish() { - postMessage({type: 'finish'}); -} - -function convertToUTF16(s) { - res = ""; - for (var i = 0; i < s.length; ++i) { - c = s.charCodeAt(i); - res += String.fromCharCode(c & 255, c >>> 8); - } - return res; -} - -function convertToUTF8(s) { - return unescape(encodeURIComponent(s)); -} - -function convertToDataURL(s) { - return "data:application/octet-stream;base64," + btoa(s); -} - -onmessage = function(message) { - is(FileReader.EMPTY, 0, "correct EMPTY value"); - is(FileReader.LOADING, 1, "correct LOADING value"); - is(FileReader.DONE, 2, "correct DONE value"); - - // List of blobs. - var asciiFile = message.data.blobs.shift(); - var binaryFile = message.data.blobs.shift(); - var nonExistingFile = message.data.blobs.shift(); - var utf8TextFile = message.data.blobs.shift(); - var utf16TextFile = message.data.blobs.shift(); - var emptyFile = message.data.blobs.shift(); - var dataUrlFile0 = message.data.blobs.shift(); - var dataUrlFile1 = message.data.blobs.shift(); - var dataUrlFile2 = message.data.blobs.shift(); - - // List of buffers for testing. - var testTextData = message.data.testTextData; - var testASCIIData = message.data.testASCIIData; - var testBinaryData = message.data.testBinaryData; - var dataurldata0 = message.data.dataurldata0; - var dataurldata1 = message.data.dataurldata1; - var dataurldata2 = message.data.dataurldata2; - - // Test that plain reading works and fires events as expected, both - // for text and binary reading - - var onloadHasRunText = false; - var onloadStartHasRunText = false; - r = new FileReader(); - is(r.readyState, FileReader.EMPTY, "correct initial text readyState"); - r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "plain reading"); - r.addEventListener("load", function() { onloadHasRunText = true }, false); - r.addEventListener("loadstart", function() { onloadStartHasRunText = true }, false); - r.readAsText(asciiFile); - is(r.readyState, FileReader.LOADING, "correct loading text readyState"); - is(onloadHasRunText, false, "text loading must be async"); - is(onloadStartHasRunText, true, "text loadstart should fire sync"); - expectedTestCount++; - - var onloadHasRunBinary = false; - var onloadStartHasRunBinary = false; - r = new FileReader(); - is(r.readyState, FileReader.EMPTY, "correct initial binary readyState"); - r.addEventListener("load", function() { onloadHasRunBinary = true }, false); - r.addEventListener("loadstart", function() { onloadStartHasRunBinary = true }, false); - r.readAsBinaryString(binaryFile); - r.onload = getLoadHandler(testBinaryData, testBinaryData.length, "binary reading"); - is(r.readyState, FileReader.LOADING, "correct loading binary readyState"); - is(onloadHasRunBinary, false, "binary loading must be async"); - is(onloadStartHasRunBinary, true, "binary loadstart should fire sync"); - expectedTestCount++; - - var onloadHasRunArrayBuffer = false; - var onloadStartHasRunArrayBuffer = false; - r = new FileReader(); - is(r.readyState, FileReader.EMPTY, "correct initial arrayBuffer readyState"); - r.addEventListener("load", function() { onloadHasRunArrayBuffer = true }, false); - r.addEventListener("loadstart", function() { onloadStartHasRunArrayBuffer = true }, false); - r.readAsArrayBuffer(binaryFile); - r.onload = getLoadHandlerForArrayBuffer(testBinaryData, testBinaryData.length, "array buffer reading"); - is(r.readyState, FileReader.LOADING, "correct loading arrayBuffer readyState"); - is(onloadHasRunArrayBuffer, false, "arrayBuffer loading must be async"); - is(onloadStartHasRunArrayBuffer, true, "arrayBuffer loadstart should fire sync"); - expectedTestCount++; - - // Test a variety of encodings, and make sure they work properly - r = new FileReader(); - r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "no encoding reading"); - r.readAsText(asciiFile, ""); - expectedTestCount++; - - r = new FileReader(); - r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "iso8859 reading"); - r.readAsText(asciiFile, "iso-8859-1"); - expectedTestCount++; - - r = new FileReader(); - r.onload = getLoadHandler(testTextData, - convertToUTF8(testTextData).length, - "utf8 reading"); - r.readAsText(utf8TextFile, "utf8"); - expectedTestCount++; - - r = new FileReader(); - r.readAsText(utf16TextFile, "utf-16"); - r.onload = getLoadHandler(testTextData, - convertToUTF16(testTextData).length, - "utf16 reading"); - expectedTestCount++; - - // Test get result without reading - r = new FileReader(); - is(r.readyState, FileReader.EMPTY, - "readyState in test reader get result without reading"); - is(r.error, null, - "no error in test reader get result without reading"); - is(r.result, null, - "result in test reader get result without reading"); - - // Test loading an empty file works (and doesn't crash!) - r = new FileReader(); - r.onload = getLoadHandler("", 0, "empty no encoding reading"); - r.readAsText(emptyFile, ""); - expectedTestCount++; - - r = new FileReader(); - r.onload = getLoadHandler("", 0, "empty utf8 reading"); - r.readAsText(emptyFile, "utf8"); - expectedTestCount++; - - r = new FileReader(); - r.onload = getLoadHandler("", 0, "empty utf16 reading"); - r.readAsText(emptyFile, "utf-16"); - expectedTestCount++; - - r = new FileReader(); - r.onload = getLoadHandler("", 0, "empty binary string reading"); - r.readAsBinaryString(emptyFile); - expectedTestCount++; - - r = new FileReader(); - r.onload = getLoadHandlerForArrayBuffer("", 0, "empty array buffer reading"); - r.readAsArrayBuffer(emptyFile); - expectedTestCount++; - - r = new FileReader(); - r.onload = getLoadHandler(convertToDataURL(""), 0, "empt binary string reading"); - r.readAsDataURL(emptyFile); - expectedTestCount++; - - // Test reusing a FileReader to read multiple times - r = new FileReader(); - r.onload = getLoadHandler(testASCIIData, - testASCIIData.length, - "to-be-reused reading text") - var makeAnotherReadListener = function(event) { - r = event.target; - r.removeEventListener("load", makeAnotherReadListener, false); - r.onload = getLoadHandler(testASCIIData, - testASCIIData.length, - "reused reading text"); - r.readAsText(asciiFile); - }; - r.addEventListener("load", makeAnotherReadListener, false); - r.readAsText(asciiFile); - expectedTestCount += 2; - - r = new FileReader(); - r.onload = getLoadHandler(testBinaryData, - testBinaryData.length, - "to-be-reused reading binary") - var makeAnotherReadListener2 = function(event) { - r = event.target; - r.removeEventListener("load", makeAnotherReadListener2, false); - r.onload = getLoadHandler(testBinaryData, - testBinaryData.length, - "reused reading binary"); - r.readAsBinaryString(binaryFile); - }; - r.addEventListener("load", makeAnotherReadListener2, false); - r.readAsBinaryString(binaryFile); - expectedTestCount += 2; - - r = new FileReader(); - r.onload = getLoadHandler(convertToDataURL(testBinaryData), - testBinaryData.length, - "to-be-reused reading data url") - var makeAnotherReadListener3 = function(event) { - r = event.target; - r.removeEventListener("load", makeAnotherReadListener3, false); - r.onload = getLoadHandler(convertToDataURL(testBinaryData), - testBinaryData.length, - "reused reading data url"); - r.readAsDataURL(binaryFile); - }; - r.addEventListener("load", makeAnotherReadListener3, false); - r.readAsDataURL(binaryFile); - expectedTestCount += 2; - - r = new FileReader(); - r.onload = getLoadHandlerForArrayBuffer(testBinaryData, - testBinaryData.length, - "to-be-reused reading arrayBuffer") - var makeAnotherReadListener4 = function(event) { - r = event.target; - r.removeEventListener("load", makeAnotherReadListener4, false); - r.onload = getLoadHandlerForArrayBuffer(testBinaryData, - testBinaryData.length, - "reused reading arrayBuffer"); - r.readAsArrayBuffer(binaryFile); - }; - r.addEventListener("load", makeAnotherReadListener4, false); - r.readAsArrayBuffer(binaryFile); - expectedTestCount += 2; - - // Test first reading as ArrayBuffer then read as something else - // (BinaryString) and doesn't crash - r = new FileReader(); - r.onload = getLoadHandlerForArrayBuffer(testBinaryData, - testBinaryData.length, - "to-be-reused reading arrayBuffer") - var makeAnotherReadListener5 = function(event) { - r = event.target; - r.removeEventListener("load", makeAnotherReadListener5, false); - r.onload = getLoadHandler(testBinaryData, - testBinaryData.length, - "reused reading binary string"); - r.readAsBinaryString(binaryFile); - }; - r.addEventListener("load", makeAnotherReadListener5, false); - r.readAsArrayBuffer(binaryFile); - expectedTestCount += 2; - - //Test data-URI encoding on differing file sizes - is(dataurldata0.length % 3, 0, "Want to test data with length % 3 == 0"); - r = new FileReader(); - r.onload = getLoadHandler(convertToDataURL(dataurldata0), - dataurldata0.length, - "dataurl reading, %3 = 0"); - r.readAsDataURL(dataUrlFile0); - expectedTestCount++; - - is(dataurldata1.length % 3, 1, "Want to test data with length % 3 == 1"); - r = new FileReader(); - r.onload = getLoadHandler(convertToDataURL(dataurldata1), - dataurldata1.length, - "dataurl reading, %3 = 1"); - r.readAsDataURL(dataUrlFile1); - expectedTestCount++; - - is(dataurldata2.length % 3, 2, "Want to test data with length % 3 == 2"); - r = new FileReader(); - r.onload = getLoadHandler(convertToDataURL(dataurldata2), - dataurldata2.length, - "dataurl reading, %3 = 2"); - r.readAsDataURL(dataUrlFile2), - expectedTestCount++; - - - // Test abort() - var abortHasRun = false; - var loadEndHasRun = false; - r = new FileReader(); - r.onabort = function (event) { - is(abortHasRun, false, "abort should only fire once"); - is(loadEndHasRun, false, "loadend shouldn't have fired yet"); - abortHasRun = true; - is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); - is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); - is(event.target.result, null, "file data should be null on aborted reads"); - } - r.onloadend = function (event) { - is(abortHasRun, true, "abort should fire before loadend"); - is(loadEndHasRun, false, "loadend should only fire once"); - loadEndHasRun = true; - is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); - is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); - is(event.target.result, null, "file data should be null on aborted reads"); - } - r.onload = function() { ok(false, "load should not fire for aborted reads") }; - r.onerror = function() { ok(false, "error should not fire for aborted reads") }; - r.onprogress = function() { ok(false, "progress should not fire for aborted reads") }; - var abortThrew = false; - try { - r.abort(); - } catch(e) { - abortThrew = true; - } - is(abortThrew, true, "abort() must throw if not loading"); - is(abortHasRun, false, "abort() is a no-op unless loading"); - r.readAsText(asciiFile); - r.abort(); - is(abortHasRun, true, "abort should fire sync"); - is(loadEndHasRun, true, "loadend should fire sync"); - - // Test calling readAsX to cause abort() - var reuseAbortHasRun = false; - r = new FileReader(); - r.onabort = function (event) { - is(reuseAbortHasRun, false, "abort should only fire once"); - reuseAbortHasRun = true; - is(event.target.readyState, FileReader.DONE, "should be DONE while firing onabort"); - is(event.target.error.name, "AbortError", "error set to AbortError for aborted reads"); - is(event.target.result, null, "file data should be null on aborted reads"); - } - r.onload = function() { ok(false, "load should not fire for aborted reads") }; - var abortThrew = false; - try { - r.abort(); - } catch(e) { - abortThrew = true; - } - is(abortThrew, true, "abort() must throw if not loading"); - is(reuseAbortHasRun, false, "abort() is a no-op unless loading"); - r.readAsText(asciiFile); - r.readAsText(asciiFile); - is(reuseAbortHasRun, true, "abort should fire sync"); - r.onload = getLoadHandler(testASCIIData, testASCIIData.length, "reuse-as-abort reading"); - expectedTestCount++; - - - // Test reading from nonexistent files - r = new FileReader(); - var didThrow = false; - r.onerror = function (event) { - is(event.target.readyState, FileReader.DONE, "should be DONE while firing onerror"); - is(event.target.error.name, "NotFoundError", "error set to NotFoundError for nonexistent files"); - is(event.target.result, null, "file data should be null on aborted reads"); - testHasRun(); - }; - r.onload = function (event) { - is(false, "nonexistent file shouldn't load! (FIXME: bug 1122788)"); - testHasRun(); - }; - try { - r.readAsDataURL(nonExistingFile); - expectedTestCount++; - } catch(ex) { - didThrow = true; - } - // Once this test passes, we should test that onerror gets called and - // that the FileReader object is in the right state during that call. - is(didThrow, false, "shouldn't throw when opening nonexistent file, should fire error instead"); - - - function getLoadHandler(expectedResult, expectedLength, testName) { - return function (event) { - is(event.target.readyState, FileReader.DONE, - "readyState in test " + testName); - is(event.target.error, null, - "no error in test " + testName); - is(event.target.result, expectedResult, - "result in test " + testName); - is(event.lengthComputable, true, - "lengthComputable in test " + testName); - is(event.loaded, expectedLength, - "loaded in test " + testName); - is(event.total, expectedLength, - "total in test " + testName); - testHasRun(); - } - } - - function getLoadHandlerForArrayBuffer(expectedResult, expectedLength, testName) { - return function (event) { - is(event.target.readyState, FileReader.DONE, - "readyState in test " + testName); - is(event.target.error, null, - "no error in test " + testName); - is(event.lengthComputable, true, - "lengthComputable in test " + testName); - is(event.loaded, expectedLength, - "loaded in test " + testName); - is(event.total, expectedLength, - "total in test " + testName); - is(event.target.result.byteLength, expectedLength, - "array buffer size in test " + testName); - var u8v = new Uint8Array(event.target.result); - is(String.fromCharCode.apply(String, u8v), expectedResult, - "array buffer contents in test " + testName); - u8v = null; - is(event.target.result.byteLength, expectedLength, - "array buffer size after gc in test " + testName); - u8v = new Uint8Array(event.target.result); - is(String.fromCharCode.apply(String, u8v), expectedResult, - "array buffer contents after gc in test " + testName); - testHasRun(); - } - } - - function testHasRun() { - //alert(testRanCounter); - ++testRanCounter; - if (testRanCounter == expectedTestCount) { - is(testSetupFinished, true, "test setup should have finished; check for exceptions"); - is(onloadHasRunText, true, "onload text should have fired by now"); - is(onloadHasRunBinary, true, "onload binary should have fired by now"); - finish(); - } - } - - testSetupFinished = true; -} diff --git a/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini b/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini index 37b8a3949920..1519b7d55402 100644 --- a/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini +++ b/testing/web-platform/meta/FileAPI/idlharness.worker.js.ini @@ -41,3 +41,136 @@ [FileList interface: attribute length] expected: FAIL + + [FileReader interface: existence and properties of interface object] + expected: FAIL + + [FileReader interface object length] + expected: FAIL + + [FileReader interface: existence and properties of interface prototype object] + expected: FAIL + + [FileReader interface: existence and properties of interface prototype object's "constructor" property] + expected: FAIL + + [FileReader interface: operation readAsArrayBuffer(Blob)] + expected: FAIL + + [FileReader interface: operation readAsText(Blob,DOMString)] + expected: FAIL + + [FileReader interface: operation readAsDataURL(Blob)] + expected: FAIL + + [FileReader interface: operation abort()] + expected: FAIL + + [FileReader interface: constant EMPTY on interface object] + expected: FAIL + + [FileReader interface: constant EMPTY on interface prototype object] + expected: FAIL + + [FileReader interface: constant LOADING on interface object] + expected: FAIL + + [FileReader interface: constant LOADING on interface prototype object] + expected: FAIL + + [FileReader interface: constant DONE on interface object] + expected: FAIL + + [FileReader interface: constant DONE on interface prototype object] + expected: FAIL + + [FileReader interface: attribute readyState] + expected: FAIL + + [FileReader interface: attribute result] + expected: FAIL + + [FileReader interface: attribute error] + expected: FAIL + + [FileReader interface: attribute onloadstart] + expected: FAIL + + [FileReader interface: attribute onprogress] + expected: FAIL + + [FileReader interface: attribute onload] + expected: FAIL + + [FileReader interface: attribute onabort] + expected: FAIL + + [FileReader interface: attribute onerror] + expected: FAIL + + [FileReader interface: attribute onloadend] + expected: FAIL + + [FileReader must be primary interface of new FileReader()] + expected: FAIL + + [Stringification of new FileReader()] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "readAsArrayBuffer" with the proper type (0)] + expected: FAIL + + [FileReader interface: calling readAsArrayBuffer(Blob) on new FileReader() with too few arguments must throw TypeError] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "readAsText" with the proper type (1)] + expected: FAIL + + [FileReader interface: calling readAsText(Blob,DOMString) on new FileReader() with too few arguments must throw TypeError] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "readAsDataURL" with the proper type (2)] + expected: FAIL + + [FileReader interface: calling readAsDataURL(Blob) on new FileReader() with too few arguments must throw TypeError] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "abort" with the proper type (3)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "EMPTY" with the proper type (4)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "LOADING" with the proper type (5)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "DONE" with the proper type (6)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "readyState" with the proper type (7)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "result" with the proper type (8)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "error" with the proper type (9)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "onloadstart" with the proper type (10)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "onprogress" with the proper type (11)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "onload" with the proper type (12)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "onabort" with the proper type (13)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "onerror" with the proper type (14)] + expected: FAIL + + [FileReader interface: new FileReader() must inherit property "onloadend" with the proper type (15)] + expected: FAIL + diff --git a/xpcom/io/nsStreamUtils.cpp b/xpcom/io/nsStreamUtils.cpp index a95dad33e11a..9fdcfcd3ddc0 100644 --- a/xpcom/io/nsStreamUtils.cpp +++ b/xpcom/io/nsStreamUtils.cpp @@ -12,7 +12,7 @@ #include "nsIPipe.h" #include "nsICloneableInputStream.h" #include "nsIEventTarget.h" -#include "nsICancelableRunnable.h" +#include "nsIRunnable.h" #include "nsISafeOutputStream.h" #include "nsString.h" #include "nsIAsyncInputStream.h" @@ -25,11 +25,8 @@ using namespace mozilla; //----------------------------------------------------------------------------- -// This is a nsICancelableRunnable because we can dispatch it to Workers and -// those can be shut down at any time, and in these cases, Cancel() is called -// instead of Run(). class nsInputStreamReadyEvent final - : public nsICancelableRunnable + : public nsIRunnable , public nsIInputStreamCallback { public: @@ -98,28 +95,19 @@ public: return NS_OK; } - NS_IMETHOD Cancel() override - { - mCallback = nullptr; - return NS_OK; - } - private: nsCOMPtr mStream; nsCOMPtr mCallback; nsCOMPtr mTarget; }; -NS_IMPL_ISUPPORTS(nsInputStreamReadyEvent, nsICancelableRunnable, - nsIRunnable, nsIInputStreamCallback) +NS_IMPL_ISUPPORTS(nsInputStreamReadyEvent, nsIRunnable, + nsIInputStreamCallback) //----------------------------------------------------------------------------- -// This is a nsICancelableRunnable because we can dispatch it to Workers and -// those can be shut down at any time, and in these cases, Cancel() is called -// instead of Run(). class nsOutputStreamReadyEvent final - : public nsICancelableRunnable + : public nsIRunnable , public nsIOutputStreamCallback { public: @@ -188,20 +176,14 @@ public: return NS_OK; } - NS_IMETHOD Cancel() override - { - mCallback = nullptr; - return NS_OK; - } - private: nsCOMPtr mStream; nsCOMPtr mCallback; nsCOMPtr mTarget; }; -NS_IMPL_ISUPPORTS(nsOutputStreamReadyEvent, nsICancelableRunnable, - nsIRunnable, nsIOutputStreamCallback) +NS_IMPL_ISUPPORTS(nsOutputStreamReadyEvent, nsIRunnable, + nsIOutputStreamCallback) //----------------------------------------------------------------------------- @@ -234,7 +216,7 @@ NS_NewOutputStreamReadyEvent(nsIOutputStreamCallback* aCallback, class nsAStreamCopier : public nsIInputStreamCallback , public nsIOutputStreamCallback - , public nsICancelableRunnable + , public nsIRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS @@ -451,8 +433,6 @@ public: return NS_OK; } - NS_IMETHOD Cancel() MOZ_MUST_OVERRIDE override = 0; - nsresult PostContinuationEvent() { // we cannot post a continuation event if there is currently @@ -509,7 +489,6 @@ protected: NS_IMPL_ISUPPORTS(nsAStreamCopier, nsIInputStreamCallback, nsIOutputStreamCallback, - nsICancelableRunnable, nsIRunnable) class nsStreamCopierIB final : public nsAStreamCopier @@ -548,8 +527,7 @@ public: return state->mSinkCondition; } - uint32_t DoCopy(nsresult* aSourceCondition, - nsresult* aSinkCondition) override + uint32_t DoCopy(nsresult* aSourceCondition, nsresult* aSinkCondition) { ReadSegmentsState state; state.mSink = mSink; @@ -561,11 +539,6 @@ public: *aSinkCondition = state.mSinkCondition; return n; } - - NS_IMETHOD Cancel() override - { - return NS_OK; - } }; class nsStreamCopierOB final : public nsAStreamCopier @@ -604,8 +577,7 @@ public: return state->mSourceCondition; } - uint32_t DoCopy(nsresult* aSourceCondition, - nsresult* aSinkCondition) override + uint32_t DoCopy(nsresult* aSourceCondition, nsresult* aSinkCondition) { WriteSegmentsState state; state.mSource = mSource; @@ -617,11 +589,6 @@ public: *aSourceCondition = state.mSourceCondition; return n; } - - NS_IMETHOD Cancel() override - { - return NS_OK; - } }; //----------------------------------------------------------------------------- diff --git a/xpcom/threads/TimerThread.cpp b/xpcom/threads/TimerThread.cpp index 7e032607e7ca..9eeda7a93c7d 100644 --- a/xpcom/threads/TimerThread.cpp +++ b/xpcom/threads/TimerThread.cpp @@ -127,23 +127,10 @@ public: } // namespace -// This is a nsICancelableRunnable because we can dispatch it to Workers and -// those can be shut down at any time, and in these cases, Cancel() is called -// instead of Run(). -class nsTimerEvent : public nsCancelableRunnable +class nsTimerEvent : public nsRunnable { public: - NS_IMETHOD Run() override; - - NS_IMETHOD Cancel() override - { - // Since nsTimerImpl is not thread-safe, we should release |mTimer| - // here in the target thread to avoid race condition. Otherwise, - // ~nsTimerEvent() which calls nsTimerImpl::Release() could run in the - // timer thread and result in race condition. - mTimer = nullptr; - return NS_OK; - } + NS_IMETHOD Run(); nsTimerEvent() : mTimer() @@ -266,8 +253,6 @@ nsTimerEvent::DeleteAllocatorIfNeeded() NS_IMETHODIMP nsTimerEvent::Run() { - MOZ_ASSERT(mTimer); - if (mGeneration != mTimer->GetGeneration()) { return NS_OK; } @@ -280,10 +265,13 @@ nsTimerEvent::Run() } mTimer->Fire(); + // Since nsTimerImpl is not thread-safe, we should release |mTimer| + // here in the target thread to avoid race condition. Otherwise, + // ~nsTimerEvent() which calls nsTimerImpl::Release() could run in the + // timer thread and result in race condition. + mTimer = nullptr; - // We call Cancel() to correctly release mTimer. - // Read more in the Cancel() implementation. - return Cancel(); + return NS_OK; } nsresult diff --git a/xpcom/threads/nsICancelableRunnable.idl b/xpcom/threads/nsICancelableRunnable.idl index 11f09650c18f..44b9df477c05 100644 --- a/xpcom/threads/nsICancelableRunnable.idl +++ b/xpcom/threads/nsICancelableRunnable.idl @@ -16,7 +16,6 @@ interface nsICancelableRunnable : nsIRunnable /** * Cancels a pending task. If the task has already been executed this will * be a no-op. Calling this method twice is considered an error. - * If cancel() is called, run() will not be called. * * @throws NS_ERROR_UNEXPECTED * Indicates that the runnable has already been canceled. From 3491c08811bd6116b086ea8ac42816f3868e2f87 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 17 Dec 2015 10:05:12 -0500 Subject: [PATCH 037/139] Bug 1229039 - Miscellaneous logging fixes/updates. r=botond --HG-- extra : commitid : 2U8HdyLyvhc --- gfx/layers/apz/src/InputBlockState.cpp | 1 + gfx/layers/apz/src/InputQueue.cpp | 11 ++++++++--- gfx/layers/apz/util/APZCCallbackHelper.cpp | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gfx/layers/apz/src/InputBlockState.cpp b/gfx/layers/apz/src/InputBlockState.cpp index 7e6f28cc8364..196c011918d1 100644 --- a/gfx/layers/apz/src/InputBlockState.cpp +++ b/gfx/layers/apz/src/InputBlockState.cpp @@ -614,6 +614,7 @@ bool PanGestureBlockState::SetContentResponse(bool aPreventDefault) { if (aPreventDefault) { + TBS_LOG("%p setting interrupted flag\n", this); mInterrupted = true; } bool stateChanged = CancelableBlockState::SetContentResponse(aPreventDefault); diff --git a/gfx/layers/apz/src/InputQueue.cpp b/gfx/layers/apz/src/InputQueue.cpp index 7b62a7ff0000..b06ac33f6d54 100644 --- a/gfx/layers/apz/src/InputQueue.cpp +++ b/gfx/layers/apz/src/InputQueue.cpp @@ -207,7 +207,8 @@ InputQueue::ReceiveMouseInput(const RefPtr& aTarget, *aOutInputBlockId = block->GetBlockId(); } - INPQ_LOG("started new drag block %p for target %p\n", block, aTarget.get()); + INPQ_LOG("started new drag block %p id %" PRIu64 " for target %p\n", + block, block->GetBlockId(), aTarget.get()); SweepDepletedBlocks(); mInputBlockQueue.AppendElement(block); @@ -262,7 +263,8 @@ InputQueue::ReceiveScrollWheelInput(const RefPtr& aTarge if (!block) { block = new WheelBlockState(aTarget, aTargetConfirmed, aEvent); - INPQ_LOG("started new scroll wheel block %p for target %p\n", block, aTarget.get()); + INPQ_LOG("started new scroll wheel block %p id %" PRIu64 " for target %p\n", + block, block->GetBlockId(), aTarget.get()); SweepDepletedBlocks(); mInputBlockQueue.AppendElement(block); @@ -326,10 +328,13 @@ InputQueue::ReceivePanGestureInput(const RefPtr& aTarget if (!block || block->WasInterrupted()) { if (aEvent.mType != PanGestureInput::PANGESTURE_START) { // Only PANGESTURE_START events are allowed to start a new pan gesture block. + INPQ_LOG("pangesture block %p was interrupted %d\n", block, + block ? block->WasInterrupted() : 0); return nsEventStatus_eConsumeDoDefault; } block = new PanGestureBlockState(aTarget, aTargetConfirmed, aEvent); - INPQ_LOG("started new pan gesture block %p for target %p\n", block, aTarget.get()); + INPQ_LOG("started new pan gesture block %p id %" PRIu64 " for target %p\n", + block, block->GetBlockId(), aTarget.get()); if (aTargetConfirmed && aEvent.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection && diff --git a/gfx/layers/apz/util/APZCCallbackHelper.cpp b/gfx/layers/apz/util/APZCCallbackHelper.cpp index 5ef6a4aed43f..43b959854191 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.cpp +++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp @@ -8,6 +8,7 @@ #include "ContentHelper.h" #include "gfxPlatform.h" // For gfxPlatform::UseTiling #include "gfxPrefs.h" +#include "LayersLogging.h" // For Stringify #include "mozilla/dom/Element.h" #include "mozilla/dom/TabParent.h" #include "mozilla/IntegerPrintfMacros.h" From bbb8c0c99f3d19e92c191528ac93c9c75e41abe4 Mon Sep 17 00:00:00 2001 From: Kartikaya Gupta Date: Thu, 17 Dec 2015 10:05:47 -0500 Subject: [PATCH 038/139] Bug 1229039 - If a PanGesture input block gets interrupted, just start a new block instead of not sending the rest of the events through the APZ. r=mstange --HG-- extra : commitid : DfIcUatPF3a --- gfx/layers/apz/src/InputQueue.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/gfx/layers/apz/src/InputQueue.cpp b/gfx/layers/apz/src/InputQueue.cpp index b06ac33f6d54..4323593756c3 100644 --- a/gfx/layers/apz/src/InputQueue.cpp +++ b/gfx/layers/apz/src/InputQueue.cpp @@ -323,22 +323,25 @@ InputQueue::ReceivePanGestureInput(const RefPtr& aTarget block = mInputBlockQueue.LastElement()->AsPanGestureBlock(); } + PanGestureInput event = aEvent; nsEventStatus result = nsEventStatus_eConsumeDoDefault; if (!block || block->WasInterrupted()) { - if (aEvent.mType != PanGestureInput::PANGESTURE_START) { - // Only PANGESTURE_START events are allowed to start a new pan gesture block. - INPQ_LOG("pangesture block %p was interrupted %d\n", block, - block ? block->WasInterrupted() : 0); - return nsEventStatus_eConsumeDoDefault; + if (event.mType != PanGestureInput::PANGESTURE_START) { + // Only PANGESTURE_START events are allowed to start a new pan gesture + // block, but we really want to start a new block here, so we magically + // turn this input into a PANGESTURE_START. + INPQ_LOG("transmogrifying pan input %d to PANGESTURE_START for new block\n", + event.mType); + event.mType = PanGestureInput::PANGESTURE_START; } - block = new PanGestureBlockState(aTarget, aTargetConfirmed, aEvent); + block = new PanGestureBlockState(aTarget, aTargetConfirmed, event); INPQ_LOG("started new pan gesture block %p id %" PRIu64 " for target %p\n", block, block->GetBlockId(), aTarget.get()); if (aTargetConfirmed && - aEvent.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection && - !CanScrollTargetHorizontally(aEvent, block)) { + event.mRequiresContentResponseIfCannotScrollHorizontallyInStartDirection && + !CanScrollTargetHorizontally(event, block)) { // This event may trigger a swipe gesture, depending on what our caller // wants to do it. We need to suspend handling of this block until we get // a content response which will tell us whether to proceed or abort the @@ -368,8 +371,8 @@ InputQueue::ReceivePanGestureInput(const RefPtr& aTarget // null) should take priority. This is equivalent to just always using the // target (confirmed or not) from the block, which is what // MaybeHandleCurrentBlock() does. - if (!MaybeHandleCurrentBlock(block, aEvent)) { - block->AddEvent(aEvent.AsPanGestureInput()); + if (!MaybeHandleCurrentBlock(block, event)) { + block->AddEvent(event.AsPanGestureInput()); } return result; From 1d9e5fddae6e898b025c86ac33ea0e3d220f0620 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Thu, 17 Dec 2015 10:11:26 -0500 Subject: [PATCH 039/139] Bug 1233171 Cancel channel when ScriptLoader is aborted during service worker script load. r=khuey --- dom/workers/ScriptLoader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 5efef6f3d9cd..ba7e17cc0b19 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -629,6 +629,7 @@ private: // If one load info cancels or hits an error, it can race with the start // callback coming from another load info. if (mCanceledMainThread || !mCacheCreator) { + aRequest->Cancel(NS_ERROR_FAILURE); return NS_ERROR_FAILURE; } From d4f6a558a6739dbfdb21fe84027b907a4d12a9dc Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Thu, 17 Dec 2015 15:39:33 +0000 Subject: [PATCH 040/139] Bug 1232630 - Rename C and I to Cc and Ci in profileSelection.js, r=ehsan --- toolkit/profile/content/profileSelection.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/toolkit/profile/content/profileSelection.js b/toolkit/profile/content/profileSelection.js index f880e54b2802..898d5ef29805 100644 --- a/toolkit/profile/content/profileSelection.js +++ b/toolkit/profile/content/profileSelection.js @@ -4,11 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -Components.utils.import("resource://gre/modules/AppConstants.jsm"); -Components.utils.import("resource://gre/modules/Services.jsm"); +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; -const C = Components.classes; -const I = Components.interfaces; +Cu.import("resource://gre/modules/AppConstants.jsm"); +Cu.import("resource://gre/modules/Services.jsm"); const ToolkitProfileService = "@mozilla.org/toolkit/profile-service;1"; @@ -19,9 +18,9 @@ var gProfileService; function startup() { - gDialogParams = window.arguments[0].QueryInterface(I.nsIDialogParamBlock); + gDialogParams = window.arguments[0].QueryInterface(Ci.nsIDialogParamBlock); - gProfileService = C[ToolkitProfileService].getService(I.nsIToolkitProfileService); + gProfileService = Cc[ToolkitProfileService].getService(Ci.nsIToolkitProfileService); gProfileManagerBundle = document.getElementById("bundle_profileManager"); gBrandBundle = document.getElementById("bundle_brand"); From 8f57e94484ff17ee9d8b3e37242a1b79bddafe18 Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Thu, 10 Dec 2015 14:59:49 -0500 Subject: [PATCH 041/139] Bug 1211562 - Update mac tooltool rustc to 1.5. r=mshal Custom build from 1.5.0-src with MACOSX_DEPLOYMENT_TARGET=10.7 --enable-rpath --disable-elf-tls --disable-doc with i686 rustlib copied into the x86_64 install for cross-32 support. --- browser/config/tooltool-manifests/macosx64/releng.manifest | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/config/tooltool-manifests/macosx64/releng.manifest b/browser/config/tooltool-manifests/macosx64/releng.manifest index c34baf77810e..46e237b10b46 100644 --- a/browser/config/tooltool-manifests/macosx64/releng.manifest +++ b/browser/config/tooltool-manifests/macosx64/releng.manifest @@ -10,8 +10,8 @@ "unpack": true }, { -"size": 128301120, -"digest": "d2d71103a6cec84b150b8f08bfef2682aa713c2d6eadce584f79836ef27ba4380ffb444165d999b79605f18ad165641a7a8cc0e04a201675ad5f655a59adbda9", +"size": 215952362, +"digest": "5e9825dbe83b2a157879076da70fc5c989a1638e30d3b14a9901b166db09013c356a9dc4eaf6c16209a1832d9cb1c67ca869e9b9003cab8355a7f03b3dc08775", "algorithm": "sha512", "filename": "rustc.tar.bz2", "unpack": true From 241c3e6e6fe1775d5320bc6dfeb023e1ac0f5e68 Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Tue, 15 Dec 2015 15:58:17 -0800 Subject: [PATCH 042/139] Bug 1211562 - Update linux64 tooltool rustc to 1.5. r=mshal Custom build of stable rustc 1.5 with --enable-rpath --enable-llvm-static-stdcpp and --target=i686-unknown-linux-gnu. https://github.com/rillian/rust-build commit fe6d07b8b86c. --- .../tooltool-manifests/linux64/releng.manifest | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/browser/config/tooltool-manifests/linux64/releng.manifest b/browser/config/tooltool-manifests/linux64/releng.manifest index 2373871b30b5..6522d5585e51 100644 --- a/browser/config/tooltool-manifests/linux64/releng.manifest +++ b/browser/config/tooltool-manifests/linux64/releng.manifest @@ -14,17 +14,17 @@ "unpack": true }, { +"size": 193213220, +"digest": "58b8ebd8de923117831dcbba71172a53e26c25bd16c2b2bb363a1254f2cd4e87f95e2c5f41e2dce10e18e43a17e0a395637c9ddcbf1e27673582792f9095c62e", +"algorithm": "sha512", +"filename": "rustc.tar.xz", +"unpack": true +}, +{ "size": 167175, "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831", "algorithm": "sha512", "filename": "sccache.tar.bz2", "unpack": true -}, -{ -"size": 73029932, -"digest": "ef1818acf065838dcb72554e521f9fd7098f0a3690cb6a3106d7bf18f46c342bfdd5a2b7d86e92ee3ddb9e478380343e58ecf8fd242807b8881a2d53fbec5ab3", -"algorithm": "sha512", -"filename": "rustc.tar.xz", -"unpack": true } ] From aa7ce205e6506ab1167a74896be2befad339c7f9 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 16 Dec 2015 12:58:18 -0800 Subject: [PATCH 043/139] Bug 1208566 - emit proper dependencies when compiling Rust sources; r=mshal --- config/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rules.mk b/config/rules.mk index 938c956720da..81e52860e2b2 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -945,7 +945,7 @@ ifdef MOZ_RUST # in the target's LIBS. $(RSOBJS): $(REPORT_BUILD) - $(RUSTC) $(RUSTFLAGS) --crate-type staticlib -o $(call mk_libname,$<) $(_VPATH_SRCS) + $(RUSTC) $(RUSTFLAGS) --crate-type staticlib --emit dep-info=$(MDDEPDIR)/$(call mk_libname,$<).pp,link=$(call mk_libname,$<) $(_VPATH_SRCS) endif $(SOBJS): From b5bdd4fc50ae85c01ca9892e2417e175dce465e6 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Mon, 5 Oct 2015 13:31:44 -0700 Subject: [PATCH 044/139] Bug 1208566 - require Rust 1.5 for --enable-rust builds; r=mshal Rust 1.5 features fine-grained dependency tracking that we need for proper incremental builds. As a side effect, it also features choosing between the builtin-to-Rust jemalloc and the system allocator, which Gecko needs for interoperation. (Gecko needs to make Rust use the system allocator, which then gets redirected into Gecko's copy of jemalloc if necessary.) It's not great to require an unstable Rust target here, but we need to upgrade at some point anyway, so we might as well make people aware of the upgrade requirement sooner rather than later. --- build/autoconf/rust.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/autoconf/rust.m4 b/build/autoconf/rust.m4 index a4d014a62e48..75409d5a5f8d 100644 --- a/build/autoconf/rust.m4 +++ b/build/autoconf/rust.m4 @@ -25,10 +25,10 @@ AC_DEFUN([MOZ_RUST_SUPPORT], [ fi if test -n "$MOZ_RUST" && test -z "$_RUSTC_MAJOR_VERSION" -o \ "$_RUSTC_MAJOR_VERSION" -lt 1 -o \ - \( "$_RUSTC_MAJOR_VERSION" -eq 1 -a "$_RUSTC_MINOR_VERSION" -lt 4 \); then + \( "$_RUSTC_MAJOR_VERSION" -eq 1 -a "$_RUSTC_MINOR_VERSION" -lt 5 \); then AC_MSG_ERROR([Rust compiler ${RUSTC_VERSION} is too old. To compile Rust language sources please install at least - version 1.4 of the 'rustc' toolchain and make sure it is + version 1.5 of the 'rustc' toolchain and make sure it is first in your path. You can verify this by typing 'rustc --version'.]) fi From 5736e43d34374175527970d3206bad1db6dad855 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Wed, 16 Dec 2015 08:40:13 -0800 Subject: [PATCH 045/139] Bug 1227144 - Remove unused AutoRegExpStaticsBuffer; r=jonco --HG-- extra : rebase_source : c6a792b7f53d61a22a179fd2bd486d8920245d92 --- js/src/vm/RegExpStatics.h | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/js/src/vm/RegExpStatics.h b/js/src/vm/RegExpStatics.h index 31829400027f..082364097791 100644 --- a/js/src/vm/RegExpStatics.h +++ b/js/src/vm/RegExpStatics.h @@ -63,8 +63,6 @@ class RegExpStatics struct InitBuffer {}; explicit RegExpStatics(InitBuffer) {} - friend class AutoRegExpStaticsBuffer; - public: /* Mutators. */ inline void updateLazily(JSContext* cx, JSLinearString* input, @@ -160,38 +158,6 @@ class RegExpStatics } }; -class MOZ_RAII AutoRegExpStaticsBuffer : private JS::CustomAutoRooter -{ - public: - explicit AutoRegExpStaticsBuffer(JSContext* cx - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) - : CustomAutoRooter(cx), statics(RegExpStatics::InitBuffer()) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - - RegExpStatics& getStatics() { return statics; } - - private: - virtual void trace(JSTracer* trc) { - if (statics.matchesInput) { - TraceRoot(trc, reinterpret_cast(&statics.matchesInput), - "AutoRegExpStaticsBuffer matchesInput"); - } - if (statics.lazySource) { - TraceRoot(trc, reinterpret_cast(&statics.lazySource), - "AutoRegExpStaticsBuffer lazySource"); - } - if (statics.pendingInput) { - TraceRoot(trc, reinterpret_cast(&statics.pendingInput), - "AutoRegExpStaticsBuffer pendingInput"); - } - } - - RegExpStatics statics; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - inline bool RegExpStatics::createDependent(JSContext* cx, size_t start, size_t end, MutableHandleValue out) { From 0020f5aa6dcb08db47692b3d1484408ecbb29df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Pag=C3=A8s?= Date: Thu, 17 Dec 2015 12:11:28 +0100 Subject: [PATCH 046/139] Bug 1229379 - use mozlog in talos. r=jgraham,jmaher --HG-- extra : rebase_source : 45e9249ae9cb0e4ba084ac39bccc37d88ddeea24 --- .../mozharness/mozilla/testing/talos.py | 13 ++++++- testing/talos/requirements.txt | 1 + testing/talos/talos/cmdline.py | 6 ++-- testing/talos/talos/config.py | 6 ++-- testing/talos/talos/ffsetup.py | 28 +++++++++------ testing/talos/talos/output.py | 31 +++++++++-------- testing/talos/talos/run_tests.py | 23 +++++++------ testing/talos/talos/sps_profile.py | 34 +++++++++++-------- .../talos/startup_test/media/media_manager.py | 11 +++--- testing/talos/talos/talos_process.py | 16 ++++++--- testing/talos/talos/ttest.py | 17 ++++++---- testing/talos/talos/utils.py | 12 ++----- 12 files changed, 117 insertions(+), 81 deletions(-) diff --git a/testing/mozharness/mozharness/mozilla/testing/talos.py b/testing/mozharness/mozharness/mozilla/testing/talos.py index 77c6b117fc56..86dae3107c17 100755 --- a/testing/mozharness/mozharness/mozilla/testing/talos.py +++ b/testing/mozharness/mozharness/mozilla/testing/talos.py @@ -382,7 +382,18 @@ class Talos(TestingMixin, MercurialScript, BlobUploadMixin): output_timeout = self.config.get('talos_output_timeout', 3600) # run talos tests run_tests = os.path.join(self.talos_path, 'talos', 'run_tests.py') - command = [python, run_tests, '--debug'] + options + + mozlog_opts = ['--log-tbpl-level=debug'] + if not self.run_local and 'suite' in self.config: + fname_pattern = '%s_%%s.log' % self.config['suite'] + mozlog_opts.append('--log-errorsummary=%s' + % os.path.join(env['MOZ_UPLOAD_DIR'], + fname_pattern % 'errorsummary')) + mozlog_opts.append('--log-raw=%s' + % os.path.join(env['MOZ_UPLOAD_DIR'], + fname_pattern % 'raw')) + + command = [python, run_tests] + options + mozlog_opts self.return_code = self.run_command(command, cwd=self.workdir, output_timeout=output_timeout, output_parser=parser, diff --git a/testing/talos/requirements.txt b/testing/talos/requirements.txt index c19cb0bb9040..f378ace783dd 100644 --- a/testing/talos/requirements.txt +++ b/testing/talos/requirements.txt @@ -1,3 +1,4 @@ +mozlog>=3.1 mozcrash>=0.15 mozfile>=1.2 mozhttpd>=0.7 diff --git a/testing/talos/talos/cmdline.py b/testing/talos/talos/cmdline.py index 1c00fd8aba43..1ef22222bc31 100644 --- a/testing/talos/talos/cmdline.py +++ b/testing/talos/talos/cmdline.py @@ -5,6 +5,8 @@ import argparse import os +from mozlog.commandline import add_logging_group + class _StopAction(argparse.Action): def __init__(self, option_strings, dest=argparse.SUPPRESS, @@ -137,8 +139,8 @@ def create_parser(mach_interface=False): help="print available tests") add_arg('--print-suites', action=_ListSuite, help="list available suites") - add_arg('--debug', action='store_true', - help='show debug information') + + add_logging_group(parser) return parser diff --git a/testing/talos/talos/config.py b/testing/talos/talos/config.py index 27ce7d8dc2e2..84773a471126 100644 --- a/testing/talos/talos/config.py +++ b/testing/talos/talos/config.py @@ -6,6 +6,8 @@ import sys import os import copy +from mozlog.commandline import setup_logging + from talos import utils, test from talos.cmdline import parse_args @@ -448,12 +450,12 @@ def get_config(argv=None): raise ConfigurationError('No such suite: %r' % cli_opts.suite) argv += ['-a', ':'.join(suite_conf['tests'])] argv += suite_conf.get('talos_options', []) - # and reparse the args - cli_opts = parse_args(argv=argv) + # args needs to be reparsed now elif not cli_opts.activeTests: raise ConfigurationError('--activeTests or --suite required!') cli_opts = parse_args(argv=argv) + setup_logging("talos", cli_opts, {"tbpl": sys.stdout}) config = copy.deepcopy(DEFAULTS) config.update(cli_opts.__dict__) for validate in CONF_VALIDATORS: diff --git a/testing/talos/talos/ffsetup.py b/testing/talos/talos/ffsetup.py index 81f34755276f..b206cfd5ff3f 100644 --- a/testing/talos/talos/ffsetup.py +++ b/testing/talos/talos/ffsetup.py @@ -9,16 +9,20 @@ Set up a browser environment before running a test. import os import re import tempfile -import logging import mozfile from mozprocess import ProcessHandler from mozprofile.profile import Profile +from mozlog import get_proxy_logger + from talos import utils from talos.utils import TalosError from talos.sps_profile import SpsProfile +LOG = get_proxy_logger() + + class FFSetup(object): """ Initialize the browser environment before running a test. @@ -111,30 +115,32 @@ class FFSetup(object): ) def browser_log(line): - logging.debug('BROWSER_OUTPUT: %s', line) + LOG.process_output(browser.pid, line) browser = ProcessHandler(command_args, env=self.env, processOutputLine=browser_log) browser.run() + LOG.process_start(browser.pid, ' '.join(command_args)) try: - browser.wait() + exit_code = browser.wait() except KeyboardInterrupt: browser.kill() raise + LOG.process_exit(browser.pid, exit_code) results_raw = '\n'.join(browser.output) if not self.PROFILE_REGEX.search(results_raw): - logging.info("Could not find %s in browser output", - self.PROFILE_REGEX.pattern) - logging.info("Raw results:%s", results_raw) + LOG.info("Could not find %s in browser output" + % self.PROFILE_REGEX.pattern) + LOG.info("Raw results:%s" % results_raw) raise TalosError("browser failed to close after being initialized") def _init_sps_profile(self): upload_dir = os.getenv('MOZ_UPLOAD_DIR') if self.test_config.get('sps_profile') and not upload_dir: - logging.critical("Profiling ignored because MOZ_UPLOAD_DIR was not" - " set") + LOG.critical("Profiling ignored because MOZ_UPLOAD_DIR was not" + " set") if upload_dir and self.test_config.get('sps_profile'): self.sps_profile = SpsProfile(upload_dir, self.browser_config, @@ -147,8 +153,8 @@ class FFSetup(object): self.sps_profile.clean() def __enter__(self): - logging.info('Initialising browser for %s test...', - self.test_config['name']) + LOG.info('Initialising browser for %s test...' + % self.test_config['name']) self._init_env() self._init_profile() try: @@ -157,7 +163,7 @@ class FFSetup(object): self.clean() raise self._init_sps_profile() - logging.info('Browser initialized.') + LOG.info('Browser initialized.') return self def __exit__(self, type, value, tb): diff --git a/testing/talos/talos/output.py b/testing/talos/talos/output.py index 04fbc4cacf3e..57a15801231b 100755 --- a/testing/talos/talos/output.py +++ b/testing/talos/talos/output.py @@ -7,15 +7,17 @@ import filter import json -import logging import post_file import time import utils +from StringIO import StringIO +from mozlog import get_proxy_logger + # NOTE: we have a circular dependecy with output.py when we import results import results as TalosResults -from StringIO import StringIO +LOG = get_proxy_logger() def filesizeformat(bytes): @@ -108,14 +110,14 @@ class Output(object): def JS_Metric(cls, val_list): """v8 benchmark score""" results = [i for i, j in val_list] - logging.info("javascript benchmark") + LOG.info("javascript benchmark") return sum(results) @classmethod def CanvasMark_Metric(cls, val_list): """CanvasMark benchmark score (NOTE: this is identical to JS_Metric)""" results = [i for i, j in val_list] - logging.info("CanvasMark benchmark") + LOG.info("CanvasMark benchmark") return sum(results) @@ -150,7 +152,7 @@ class GraphserverOutput(Output): ) for test in self.results.results: - logging.debug("Working with test: %s", test.name()) + LOG.debug("Working with test: %s" % test.name()) # get full name of test testname = test.name() @@ -161,7 +163,7 @@ class GraphserverOutput(Output): # /run_tests.py#l176 testname += test.extension() - logging.debug("Generating results file: %s" % test.name()) + LOG.debug("Generating results file: %s" % test.name()) # HACK: when running xperf, we upload xperf counters to the graph # server but we do not want to @@ -184,7 +186,7 @@ class GraphserverOutput(Output): self.shortName(counter_type)) if not values: # failed to collect any data for this counter - logging.error( + LOG.error( "No results collected for: " + counterName ) # NOTE: we are not going to enforce this warning for now as this happens too @@ -218,7 +220,7 @@ class GraphserverOutput(Output): info['testname'] = counterName # append the counter string - logging.info( + LOG.info( "Generating results file: %s" % counterName) result_strings.append(self.construct_results(vals, **info)) @@ -276,7 +278,7 @@ class GraphserverOutput(Output): try: buffer.write("%d,%.2f,%s\n" % (i, float(val), page)) except ValueError: - logging.info( + LOG.info( "We expected a numeric value and recieved '%s' instead" % val ) @@ -292,7 +294,7 @@ class GraphserverOutput(Output): if line.find("RETURN\t") > -1: line = line.replace("RETURN\t", "") links += line + '\n' - logging.debug("process_Request line: %s", line) + LOG.debug("process_Request line: %s" % line) if not links: raise utils.TalosError("send failed, graph server says:\n%s" % post) @@ -308,9 +310,10 @@ class GraphserverOutput(Output): times = 0 msg = "" while times < self.retries: - logging.info( - "Posting result %d of %d to %s://%s%s, attempt %d", - index, len(results), scheme, server, path, times) + LOG.info( + "Posting result %d of %d to %s://%s%s, attempt %d" % ( + index, len(results), scheme, server, path, times) + ) try: links.append(self.process_Request( post_file.post_multipart(server, path, @@ -404,7 +407,7 @@ class PerfherderOutput(Output): # This is the output that treeherder expects to find when parsing the # log file - logging.info("PERFHERDER_DATA: %s" % json.dumps(results)) + LOG.info("PERFHERDER_DATA: %s" % json.dumps(results)) if results_scheme in ('file'): json.dump(results, file(results_path, 'w'), indent=2, sort_keys=True) diff --git a/testing/talos/talos/run_tests.py b/testing/talos/talos/run_tests.py index e6e5ec326b63..cc88037271fe 100755 --- a/testing/talos/talos/run_tests.py +++ b/testing/talos/talos/run_tests.py @@ -5,7 +5,6 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. import mozversion -import logging import os import sys import time @@ -14,6 +13,8 @@ import urllib import utils import mozhttpd +from mozlog import get_proxy_logger + from talos.results import TalosResults from talos.ttest import TTest from talos.utils import TalosError, TalosCrash, TalosRegression @@ -21,6 +22,7 @@ from talos.config import get_configs, ConfigurationError # directory of this file here = os.path.dirname(os.path.realpath(__file__)) +LOG = get_proxy_logger() def useBaseTestDefaults(base, tests): @@ -67,7 +69,7 @@ def buildCommandLine(test): def setup_webserver(webserver): """use mozhttpd to setup a webserver""" - logging.info("starting webserver on %r" % webserver) + LOG.info("starting webserver on %r" % webserver) host, port = webserver.split(':') return mozhttpd.MozHttpd(host=host, port=int(port), docroot=here) @@ -153,8 +155,8 @@ def run_tests(config, browser_config): '%a, %d %b %Y %H:%M:%S GMT'))) else: date = int(time.time()) - logging.debug("using testdate: %d", date) - logging.debug("actual date: %d", int(time.time())) + LOG.debug("using testdate: %d" % date) + LOG.debug("actual date: %d" % int(time.time())) # results container talos_results = TalosResults(title=title, @@ -185,20 +187,20 @@ def run_tests(config, browser_config): try: # run the tests timer = utils.Timer() - logging.info("Starting test suite %s", title) + LOG.info("Starting test suite %s" % title) for test in tests: testname = test['name'] testtimer = utils.Timer() - logging.info("Starting test %s", testname) + LOG.info("Starting test %s" % testname) mytest = TTest() talos_results.add(mytest.runTest(browser_config, test)) - logging.info("Completed test %s (%s)", testname, - testtimer.elapsed()) + LOG.info("Completed test %s (%s)" + % (testname, testtimer.elapsed())) except TalosRegression: - logging.error("Detected a regression for %s", testname) + LOG.error("Detected a regression for %s" % testname) # by returning 1, we report an orange to buildbot # http://docs.buildbot.net/latest/developer/results.html return 1 @@ -212,7 +214,7 @@ def run_tests(config, browser_config): finally: httpd.stop() - logging.info("Completed test suite (%s)", timer.elapsed()) + LOG.info("Completed test suite (%s)" % timer.elapsed()) # output results if results_urls: @@ -233,7 +235,6 @@ def main(args=sys.argv[1:]): config, browser_config = get_configs() except ConfigurationError, exc: sys.exit("ERROR: %s" % exc) - utils.startLogger('debug' if config['debug'] else 'info') sys.exit(run_tests(config, browser_config)) diff --git a/testing/talos/talos/sps_profile.py b/testing/talos/talos/sps_profile.py index c48c8ea007fa..9c778007a08f 100644 --- a/testing/talos/talos/sps_profile.py +++ b/testing/talos/talos/sps_profile.py @@ -8,14 +8,16 @@ module to handle sps profilling. import os import tempfile -import logging import zipfile import json - import mozfile +from mozlog import get_proxy_logger + from talos.profiler import symbolication, sps +LOG = get_proxy_logger() + class SpsProfile(object): """ @@ -42,7 +44,7 @@ class SpsProfile(object): self.upload_dir, "profile_{0}.sps.zip".format(test_config['name']) ) - logging.info("Clearing archive {0}".format(self.profile_arcname)) + LOG.info("Clearing archive {0}".format(self.profile_arcname)) mozfile.remove(self.profile_arcname) self.symbol_paths = { @@ -51,11 +53,11 @@ class SpsProfile(object): 'WINDOWS': tempfile.mkdtemp() } - logging.info("Activating Gecko Profiling. Temp. profile dir:" - " {0}, interval: {1}, entries: {2}" - .format(sps_profile_dir, - sps_profile_interval, - sps_profile_entries)) + LOG.info("Activating Gecko Profiling. Temp. profile dir:" + " {0}, interval: {1}, entries: {2}" + .format(sps_profile_dir, + sps_profile_interval, + sps_profile_entries)) self.profiling_info = { "sps_profile_interval": sps_profile_interval, @@ -94,15 +96,17 @@ class SpsProfile(object): symbolicator.symbolicate_profile(profile) sps.save_profile(profile, profile_path) except MemoryError: - logging.exception( + LOG.critical( "Ran out of memory while trying" " to symbolicate profile {0} (cycle {1})" - .format(profile_path, cycle) + .format(profile_path, cycle), + exc_info=True ) except Exception: - logging.exception("Encountered an exception during profile" - " symbolication {0} (cycle {1})" - .format(profile_path, cycle)) + LOG.critical("Encountered an exception during profile" + " symbolication {0} (cycle {1})" + .format(profile_path, cycle), + exc_info=True) def symbolicate(self, cycle): """ @@ -182,14 +186,14 @@ class SpsProfile(object): testname, cycle_name ) - logging.info( + LOG.info( "Adding profile {0} to archive {1}" .format(path_in_zip, self.profile_arcname) ) try: arc.write(profile_path, path_in_zip) except Exception: - logging.exception( + LOG.exception( "Failed to copy profile {0} as {1} to" " archive {2}".format(profile_path, path_in_zip, diff --git a/testing/talos/talos/startup_test/media/media_manager.py b/testing/talos/talos/startup_test/media/media_manager.py index da83120f7392..a27bca29a932 100755 --- a/testing/talos/talos/startup_test/media/media_manager.py +++ b/testing/talos/talos/startup_test/media/media_manager.py @@ -6,11 +6,14 @@ import sys import platform import optparse -import logging import mozhttpd # media test utilities import media_utils +from mozlog import get_proxy_logger + +LOG = get_proxy_logger() + """ MediaManager serves as entry point for running media performance tests. It is responsible for the following @@ -134,9 +137,9 @@ def run_server(doc_root): ] ) - logging.info("Server %s at %s:%s", - httpd_server.docroot, httpd_server.host, - httpd_server.port) + LOG.info("Server %s at %s:%s" % (httpd_server.docroot, + httpd_server.host, + httpd_server.port)) ObjectDb.httpd_server = httpd_server httpd_server.start() return httpd_server diff --git a/testing/talos/talos/talos_process.py b/testing/talos/talos/talos_process.py index d70d837900af..f688bb934452 100644 --- a/testing/talos/talos/talos_process.py +++ b/testing/talos/talos/talos_process.py @@ -3,14 +3,17 @@ # You can obtain one at http://mozilla.org/MPL/2.0/. import time -import logging import psutil import mozcrash from mozprocess import ProcessHandler from threading import Event +from mozlog import get_proxy_logger + from utils import TalosError +LOG = get_proxy_logger() + class ProcessContext(object): """ @@ -26,7 +29,7 @@ class ProcessContext(object): def kill_process(self): if self.process and self.process.is_running(): - logging.debug("Terminating %s", self.process) + LOG.debug("Terminating %s" % self.process) self.process.terminate() try: self.process.wait(3) @@ -43,6 +46,7 @@ class Reader(object): self.got_timeout = False self.timeout_message = '' self.event = event + self.proc = None def __call__(self, line): if line.find('__endTimestamp') != -1: @@ -55,7 +59,7 @@ class Reader(object): if not (line.startswith('JavaScript error:') or line.startswith('JavaScript warning:')): - logging.debug('BROWSER_OUTPUT: %s', line) + LOG.process_output(self.proc.pid, line) self.output.append(line) @@ -94,7 +98,9 @@ def run_browser(command, minidump_dir, timeout=None, on_started=None, kwargs['processOutputLine'] = reader kwargs['onFinish'] = event.set proc = ProcessHandler(command, **kwargs) + reader.proc = proc proc.run() + LOG.process_start(proc.pid, ' '.join(command)) try: context.process = psutil.Process(proc.pid) if on_started: @@ -110,7 +116,7 @@ def run_browser(command, minidump_dir, timeout=None, on_started=None, if proc.wait(1) is not None: break if proc.poll() is None: - logging.info( + LOG.info( "Browser shutdown timed out after {0} seconds, terminating" " process.".format(wait_for_quit_timeout) ) @@ -129,6 +135,6 @@ def run_browser(command, minidump_dir, timeout=None, on_started=None, "__startAfterTerminationTimestamp%d__endAfterTerminationTimestamp" % (int(time.time()) * 1000)) - logging.info("Browser exited with error code: {0}".format(return_code)) + LOG.process_exit(proc.pid, return_code) context.output = reader.output return context diff --git a/testing/talos/talos/ttest.py b/testing/talos/talos/ttest.py index 40ab51f33633..272c94a38547 100644 --- a/testing/talos/talos/ttest.py +++ b/testing/talos/talos/ttest.py @@ -22,13 +22,16 @@ import mozcrash import talosconfig import shutil import mozfile -import logging + +from mozlog import get_proxy_logger from talos.utils import TalosCrash, TalosRegression from talos.talos_process import run_browser from talos.ffsetup import FFSetup from talos.cmanager import CounterManagement +LOG = get_proxy_logger() + class TTest(object): platform_type = utils.PLATFORM_TYPE @@ -56,7 +59,7 @@ class TTest(object): """ - logging.debug("operating with platform_type : %s", self.platform_type) + LOG.debug("operating with platform_type : %s" % self.platform_type) with FFSetup(browser_config, test_config) as setup: return self._runTest(browser_config, test_config, setup) @@ -103,8 +106,8 @@ class TTest(object): ) for i in range(test_config['cycles']): - logging.info("Running cycle %d/%d for %s test...", - i+1, test_config['cycles'], test_config['name']) + LOG.info("Running cycle %d/%d for %s test..." + % (i+1, test_config['cycles'], test_config['name'])) # remove the browser error file mozfile.remove(browser_config['error_filename']) @@ -116,8 +119,8 @@ class TTest(object): origin = os.path.join(test_config['profile_path'], keep) dest = os.path.join(setup.profile_dir, keep) - logging.debug("Reinstalling %s on top of %s", origin, - dest) + LOG.debug("Reinstalling %s on top of %s" + % (origin, dest)) shutil.copy(origin, dest) # Run the test @@ -245,7 +248,7 @@ class TTest(object): ) for c in test_results.all_counter_results: for key, value in c.items(): - logging.debug("COUNTER %r: %s", key, value) + LOG.debug("COUNTER %r: %s" % (key, value)) # return results return test_results diff --git a/testing/talos/talos/utils.py b/testing/talos/talos/utils.py index 56f5aed15570..e07807c75c7a 100755 --- a/testing/talos/talos/utils.py +++ b/testing/talos/talos/utils.py @@ -9,13 +9,15 @@ import time import urlparse import string import urllib -import logging import json import re import platform +from mozlog import get_proxy_logger + # directory of this file for use with interpolatePath() here = os.path.dirname(os.path.realpath(__file__)) +LOG = get_proxy_logger() def _get_platform(): @@ -53,13 +55,6 @@ class Timer(object): return time.strftime("%H:%M:%S", time.gmtime(seconds)) -def startLogger(levelChoice): - # declare and define global logger object to send logging messages to - log_levels = {'debug': logging.DEBUG, 'info': logging.INFO} - logging.basicConfig(format='%(asctime)-15s %(levelname)s : %(message)s', - level=log_levels[levelChoice]) - - class TalosError(Exception): "Errors found while running the talos harness." @@ -179,7 +174,6 @@ def GenerateBrowserCommandLine(browser_path, extra_args, profile_dir, if url.find('media_manager.py') != -1: command_args = url.split(' ') - logging.debug("command line: %s", ' '.join(command_args)) return command_args From a34ac440474d9eb60d083e061eabe540bfdf396c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Pag=C3=A8s?= Date: Mon, 14 Dec 2015 15:15:42 +0100 Subject: [PATCH 047/139] Bug 1229379 - use mozlog test report protocol in talos. r=jgraham,jmaher --HG-- extra : rebase_source : 44f33f8a65255eb7df5ea93024a3ce395976779f --- testing/talos/talos/run_tests.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/testing/talos/talos/run_tests.py b/testing/talos/talos/run_tests.py index cc88037271fe..878dc24790ab 100755 --- a/testing/talos/talos/run_tests.py +++ b/testing/talos/talos/run_tests.py @@ -17,7 +17,7 @@ from mozlog import get_proxy_logger from talos.results import TalosResults from talos.ttest import TTest -from talos.utils import TalosError, TalosCrash, TalosRegression +from talos.utils import TalosError, TalosRegression from talos.config import get_configs, ConfigurationError # directory of this file @@ -184,34 +184,36 @@ def run_tests(config, browser_config): httpd.start() testname = None + # run the tests + timer = utils.Timer() + LOG.suite_start(tests=[test['name'] for test in tests]) try: - # run the tests - timer = utils.Timer() - LOG.info("Starting test suite %s" % title) for test in tests: testname = test['name'] - testtimer = utils.Timer() - LOG.info("Starting test %s" % testname) + LOG.test_start(testname) mytest = TTest() talos_results.add(mytest.runTest(browser_config, test)) - LOG.info("Completed test %s (%s)" - % (testname, testtimer.elapsed())) + LOG.test_end(testname, status='OK') - except TalosRegression: + except TalosRegression as exc: LOG.error("Detected a regression for %s" % testname) # by returning 1, we report an orange to buildbot # http://docs.buildbot.net/latest/developer/results.html + LOG.test_end(testname, status='FAIL', message=unicode(exc), + stack=traceback.format_exc()) return 1 - except (TalosCrash, TalosError): + except Exception as exc: # NOTE: if we get into this condition, talos has an internal # problem and cannot continue # this will prevent future tests from running - traceback.print_exception(*sys.exc_info()) + LOG.test_end(testname, status='ERROR', message=unicode(exc), + stack=traceback.format_exc()) # indicate a failure to buildbot, turn the job red return 2 finally: + LOG.suite_end() httpd.stop() LOG.info("Completed test suite (%s)" % timer.elapsed()) From 12be9c02473678434ecc0388445f97a095622d9c Mon Sep 17 00:00:00 2001 From: Rail Aliiev Date: Thu, 17 Dec 2015 11:40:07 -0500 Subject: [PATCH 048/139] Bug 1233314 - beta repacks are failing trying to find checksums file. r=mshal --- browser/locales/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in index c5615035ade4..4c092f005687 100644 --- a/browser/locales/Makefile.in +++ b/browser/locales/Makefile.in @@ -72,7 +72,7 @@ SEARCHPLUGINS_NAMES = $(shell cat $(call MERGE_FILE,/searchplugins/list.txt)) dd SEARCHPLUGINS_FILENAMES = $(subst :hidden,,$(SEARCHPLUGINS_NAMES)) SEARCHPLUGINS_PATH := .deps/generated_$(AB_CD) SEARCHPLUGINS_TARGET := libs searchplugins -SEARCHPLUGINS := $(foreach plugin,$(addsuffix .xml,$(SEARCHPLUGINS_FILENAMES)),$(or $(wildcard $(call EN_US_OR_L10N_FILE,searchplugins/$(plugin))),$(info Missing searchplugin: $(plugin)))) +SEARCHPLUGINS := $(foreach plugin,$(addsuffix .xml,$(SEARCHPLUGINS_FILENAMES)),$(or $(wildcard $(call EN_US_OR_L10N_FILE,searchplugins/$(plugin))),$(warning Missing searchplugin: $(plugin)))) # Some locale-specific search plugins may have preprocessor directives, but the # default en-US ones do not. SEARCHPLUGINS_FLAGS := --silence-missing-directive-warnings From 5f38bdeff2f3d0d6ecdc855c5555b5f4ae7cf419 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Thu, 17 Dec 2015 09:34:33 -0800 Subject: [PATCH 049/139] Backed out 2 changesets (bug 1208566) for breaking mulet builds Backed out changeset a5618a5cbc7f (bug 1208566) Backed out changeset f3fd530324ee (bug 1208566) --HG-- extra : commitid : DaxmN4TLzwv --- build/autoconf/rust.m4 | 4 ++-- config/rules.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/autoconf/rust.m4 b/build/autoconf/rust.m4 index 75409d5a5f8d..a4d014a62e48 100644 --- a/build/autoconf/rust.m4 +++ b/build/autoconf/rust.m4 @@ -25,10 +25,10 @@ AC_DEFUN([MOZ_RUST_SUPPORT], [ fi if test -n "$MOZ_RUST" && test -z "$_RUSTC_MAJOR_VERSION" -o \ "$_RUSTC_MAJOR_VERSION" -lt 1 -o \ - \( "$_RUSTC_MAJOR_VERSION" -eq 1 -a "$_RUSTC_MINOR_VERSION" -lt 5 \); then + \( "$_RUSTC_MAJOR_VERSION" -eq 1 -a "$_RUSTC_MINOR_VERSION" -lt 4 \); then AC_MSG_ERROR([Rust compiler ${RUSTC_VERSION} is too old. To compile Rust language sources please install at least - version 1.5 of the 'rustc' toolchain and make sure it is + version 1.4 of the 'rustc' toolchain and make sure it is first in your path. You can verify this by typing 'rustc --version'.]) fi diff --git a/config/rules.mk b/config/rules.mk index 81e52860e2b2..938c956720da 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -945,7 +945,7 @@ ifdef MOZ_RUST # in the target's LIBS. $(RSOBJS): $(REPORT_BUILD) - $(RUSTC) $(RUSTFLAGS) --crate-type staticlib --emit dep-info=$(MDDEPDIR)/$(call mk_libname,$<).pp,link=$(call mk_libname,$<) $(_VPATH_SRCS) + $(RUSTC) $(RUSTFLAGS) --crate-type staticlib -o $(call mk_libname,$<) $(_VPATH_SRCS) endif $(SOBJS): From 7c631d5c9c8ed11e228be7e5fecbcfee371e2f24 Mon Sep 17 00:00:00 2001 From: Wes Kocher Date: Thu, 17 Dec 2015 09:34:50 -0800 Subject: [PATCH 050/139] Backed out 2 changesets (bug 1211562) for breaking mulet builds Backed out changeset 5889e20eb419 (bug 1211562) Backed out changeset d7450e4e52de (bug 1211562) --HG-- extra : commitid : EMPpcYGsvqf --- .../tooltool-manifests/linux64/releng.manifest | 14 +++++++------- .../tooltool-manifests/macosx64/releng.manifest | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/browser/config/tooltool-manifests/linux64/releng.manifest b/browser/config/tooltool-manifests/linux64/releng.manifest index 6522d5585e51..2373871b30b5 100644 --- a/browser/config/tooltool-manifests/linux64/releng.manifest +++ b/browser/config/tooltool-manifests/linux64/releng.manifest @@ -14,17 +14,17 @@ "unpack": true }, { -"size": 193213220, -"digest": "58b8ebd8de923117831dcbba71172a53e26c25bd16c2b2bb363a1254f2cd4e87f95e2c5f41e2dce10e18e43a17e0a395637c9ddcbf1e27673582792f9095c62e", -"algorithm": "sha512", -"filename": "rustc.tar.xz", -"unpack": true -}, -{ "size": 167175, "digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831", "algorithm": "sha512", "filename": "sccache.tar.bz2", "unpack": true +}, +{ +"size": 73029932, +"digest": "ef1818acf065838dcb72554e521f9fd7098f0a3690cb6a3106d7bf18f46c342bfdd5a2b7d86e92ee3ddb9e478380343e58ecf8fd242807b8881a2d53fbec5ab3", +"algorithm": "sha512", +"filename": "rustc.tar.xz", +"unpack": true } ] diff --git a/browser/config/tooltool-manifests/macosx64/releng.manifest b/browser/config/tooltool-manifests/macosx64/releng.manifest index 46e237b10b46..c34baf77810e 100644 --- a/browser/config/tooltool-manifests/macosx64/releng.manifest +++ b/browser/config/tooltool-manifests/macosx64/releng.manifest @@ -10,8 +10,8 @@ "unpack": true }, { -"size": 215952362, -"digest": "5e9825dbe83b2a157879076da70fc5c989a1638e30d3b14a9901b166db09013c356a9dc4eaf6c16209a1832d9cb1c67ca869e9b9003cab8355a7f03b3dc08775", +"size": 128301120, +"digest": "d2d71103a6cec84b150b8f08bfef2682aa713c2d6eadce584f79836ef27ba4380ffb444165d999b79605f18ad165641a7a8cc0e04a201675ad5f655a59adbda9", "algorithm": "sha512", "filename": "rustc.tar.bz2", "unpack": true From 1a97b60af0eced6d5964413337268e98f1b20fb3 Mon Sep 17 00:00:00 2001 From: Haik Aftandilian Date: Thu, 17 Dec 2015 09:37:47 -0800 Subject: [PATCH 051/139] Bug 1232374 - remove nsAutoArrayPtr usages from toolkit/; r=froydnj --- .../nsParentalControlsServiceWin.cpp | 5 ++--- toolkit/profile/nsToolkitProfileService.cpp | 19 ++++++++----------- toolkit/system/gnome/nsPackageKitService.cpp | 4 ++-- toolkit/xre/MacLaunchHelper.mm | 6 +++--- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/toolkit/components/parentalcontrols/nsParentalControlsServiceWin.cpp b/toolkit/components/parentalcontrols/nsParentalControlsServiceWin.cpp index 03bda7e47867..e73bb097aa16 100644 --- a/toolkit/components/parentalcontrols/nsParentalControlsServiceWin.cpp +++ b/toolkit/components/parentalcontrols/nsParentalControlsServiceWin.cpp @@ -13,6 +13,7 @@ #include "nsILocalFileWin.h" #include "nsArrayUtils.h" #include "nsIXULAppInfo.h" +#include "mozilla/UniquePtr.h" #include "mozilla/WindowsVersion.h" using namespace mozilla; @@ -248,9 +249,7 @@ nsParentalControlsService::RequestURIOverrides(nsIArray *aTargets, nsIInterfaceR // Allocate an array of sub uri int32_t count = arrayLength - 1; - nsAutoArrayPtr arrUrls(new LPCWSTR[count]); - if (!arrUrls) - return NS_ERROR_OUT_OF_MEMORY; + auto arrUrls = MakeUnique(count); uint32_t uriIdx = 0, idx; for (idx = 1; idx < arrayLength; idx++) diff --git a/toolkit/profile/nsToolkitProfileService.cpp b/toolkit/profile/nsToolkitProfileService.cpp index b7cd948f89c0..06eb1770885e 100644 --- a/toolkit/profile/nsToolkitProfileService.cpp +++ b/toolkit/profile/nsToolkitProfileService.cpp @@ -4,6 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/ArrayUtils.h" +#include "mozilla/UniquePtr.h" #include #include @@ -971,12 +972,10 @@ nsToolkitProfileService::Flush() uint32_t length; const int bufsize = 100+MAXPATHLEN*pCount; - nsAutoArrayPtr buffer (new char[bufsize]); + auto buffer = MakeUnique(bufsize); - NS_ENSURE_TRUE(buffer, NS_ERROR_OUT_OF_MEMORY); - - char *pos = buffer; - char *end = buffer + bufsize; + char *pos = buffer.get(); + char *end = pos + bufsize; pos += snprintf(pos, end - pos, "[General]\n" @@ -1024,13 +1023,11 @@ nsToolkitProfileService::Flush() rv = mListFile->OpenANSIFileDesc("w", &writeFile); NS_ENSURE_SUCCESS(rv, rv); - if (buffer) { - length = pos - buffer; + length = pos - buffer.get(); - if (fwrite(buffer, sizeof(char), length, writeFile) != length) { - fclose(writeFile); - return NS_ERROR_UNEXPECTED; - } + if (fwrite(buffer.get(), sizeof(char), length, writeFile) != length) { + fclose(writeFile); + return NS_ERROR_UNEXPECTED; } fclose(writeFile); diff --git a/toolkit/system/gnome/nsPackageKitService.cpp b/toolkit/system/gnome/nsPackageKitService.cpp index 87b9f3544908..b05d483dd4ba 100644 --- a/toolkit/system/gnome/nsPackageKitService.cpp +++ b/toolkit/system/gnome/nsPackageKitService.cpp @@ -4,7 +4,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsArrayUtils.h" -#include "nsAutoPtr.h" #include "nsIObserver.h" #include "nsIObserverService.h" #include "nsISupportsPrimitives.h" @@ -12,6 +11,7 @@ #include "nsString.h" #include "prlink.h" #include "mozilla/unused.h" +#include "mozilla/UniquePtr.h" #include #include @@ -216,7 +216,7 @@ nsPackageKitService::InstallPackages(uint32_t aInstallMethod, // Create the GVariant* parameter from the list of packages. GVariant* parameters = nullptr; - nsAutoArrayPtr packages(new gchar*[arrayLength + 1]); + auto packages = MakeUnique(arrayLength + 1); nsresult rv = NS_OK; for (uint32_t i = 0; i < arrayLength; i++) { diff --git a/toolkit/xre/MacLaunchHelper.mm b/toolkit/xre/MacLaunchHelper.mm index 8d922c728bc9..8191e870aff1 100644 --- a/toolkit/xre/MacLaunchHelper.mm +++ b/toolkit/xre/MacLaunchHelper.mm @@ -6,8 +6,8 @@ #include "MacLaunchHelper.h" #include "nsMemory.h" -#include "nsAutoPtr.h" #include "nsIAppStartup.h" +#include "mozilla/UniquePtr.h" #include #include @@ -40,7 +40,7 @@ void LaunchChildMac(int aArgc, char** aArgv, { // "posix_spawnp" uses null termination for arguments rather than a count. // Note that we are not duplicating the argument strings themselves. - nsAutoArrayPtr argv_copy(new char*[aArgc + 1]); + auto argv_copy = MakeUnique(aArgc + 1); for (int i = 0; i < aArgc; i++) { argv_copy[i] = aArgv[i]; } @@ -80,7 +80,7 @@ void LaunchChildMac(int aArgc, char** aArgv, envp = *cocoaEnvironment; } - int result = posix_spawnp(pid, argv_copy[0], NULL, &spawnattr, argv_copy, envp); + int result = posix_spawnp(pid, argv_copy[0], NULL, &spawnattr, argv_copy.get(), envp); posix_spawnattr_destroy(&spawnattr); From f97631d0c39c3365cffa5ac5153272a435b4ef1b Mon Sep 17 00:00:00 2001 From: Garrett Robinson Date: Wed, 16 Dec 2015 11:58:40 -0800 Subject: [PATCH 052/139] Bug 1194893 - Pref for default file upload directory. r=smaug --HG-- extra : rebase_source : dafc24f3ed145ab406f77a82e2ec8162d695f134 --- dom/html/HTMLInputElement.cpp | 31 ++++--- dom/html/test/mochitest.ini | 2 + .../test_filepicker_default_directory.html | 83 +++++++++++++++++++ modules/libpref/init/all.js | 3 + 4 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 dom/html/test/test_filepicker_default_directory.html diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp index aaca0823c4f6..ecad501e6641 100644 --- a/dom/html/HTMLInputElement.cpp +++ b/dom/html/HTMLInputElement.cpp @@ -295,20 +295,25 @@ NS_IMPL_ISUPPORTS(UploadLastDir::ContentPrefCallback, nsIContentPrefCallback2) NS_IMETHODIMP UploadLastDir::ContentPrefCallback::HandleCompletion(uint16_t aReason) { - nsCOMPtr localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); - NS_ENSURE_STATE(localFile); + nsCOMPtr localFile; + nsAutoString prefStr; - if (aReason == nsIContentPrefCallback2::COMPLETE_ERROR || - !mResult) { - // Default to "desktop" directory for each platform - nsCOMPtr homeDir; - NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR, getter_AddRefs(homeDir)); - localFile = do_QueryInterface(homeDir); - } else { - nsAutoString prefStr; - nsCOMPtr pref; - mResult->GetValue(getter_AddRefs(pref)); - pref->GetAsAString(prefStr); + if (aReason == nsIContentPrefCallback2::COMPLETE_ERROR || !mResult) { + prefStr = Preferences::GetString("dom.input.fallbackUploadDir"); + if (prefStr.IsEmpty()) { + // If no custom directory was set through the pref, default to + // "desktop" directory for each platform. + NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR, getter_AddRefs(localFile)); + } + } + + if (!localFile) { + if (prefStr.IsEmpty() && mResult) { + nsCOMPtr pref; + mResult->GetValue(getter_AddRefs(pref)); + pref->GetAsAString(prefStr); + } + localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); localFile->InitWithPath(prefStr); } diff --git a/dom/html/test/mochitest.ini b/dom/html/test/mochitest.ini index 340a2654481d..c25fef89f416 100644 --- a/dom/html/test/mochitest.ini +++ b/dom/html/test/mochitest.ini @@ -600,3 +600,5 @@ skip-if = buildapp == 'b2g' # bug 1129014 [test_image_clone_load.html] [test_bug1203668.html] [test_bug1166138.html] +[test_filepicker_default_directory.html] +skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' diff --git a/dom/html/test/test_filepicker_default_directory.html b/dom/html/test/test_filepicker_default_directory.html new file mode 100644 index 000000000000..c2212baa04b2 --- /dev/null +++ b/dom/html/test/test_filepicker_default_directory.html @@ -0,0 +1,83 @@ + + + + + Test for filepicker default directory + + + + + +Mozilla Bug 1194893 +
+ +
+
+
+
+ + diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index c7803e140459..291084294bdc 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5131,3 +5131,6 @@ pref("dom.mozKillSwitch.enabled", false); pref("toolkit.pageThumbs.screenSizeDivisor", 7); pref("toolkit.pageThumbs.minWidth", 0); pref("toolkit.pageThumbs.minHeight", 0); + +// Allow customization of the fallback directory for file uploads +pref("dom.input.fallbackUploadDir", ""); From 4d4d47ca92edcd8a1d8ff6df84a144ba4628d88b Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 17 Dec 2015 11:13:45 -0800 Subject: [PATCH 053/139] Fix crash trying to allocate textures for oversize scrollbars. (bug 1214261, r=mstange) --- layout/generic/nsGfxScrollFrame.cpp | 26 ++++++++++++++------------ layout/generic/nsGfxScrollFrame.h | 1 - 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 19ebdaa671bc..1a1ffad6b4ff 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -2676,11 +2676,10 @@ struct HoveredStateComparator void ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, - const nsRect& aDirtyRect, - const nsDisplayListSet& aLists, - bool aUsingDisplayPort, - bool aCreateLayer, - bool aPositioned) + const nsRect& aDirtyRect, + const nsDisplayListSet& aLists, + bool aCreateLayer, + bool aPositioned) { nsITheme* theme = mOuter->PresContext()->GetTheme(); if (theme && @@ -2734,9 +2733,12 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, } // The display port doesn't necessarily include the scrollbars, so just - // include all of the scrollbars if we have a display port. - nsRect dirty = aUsingDisplayPort ? - scrollParts[i]->GetVisualOverflowRectRelativeToParent() : aDirtyRect; + // include all of the scrollbars if we are in a RCD-RSF. We only do + // this for the root scrollframe of the root content document, which is + // zoomable, and where the scrollbar sizes are bounded by the widget. + nsRect dirty = mIsRoot && mOuter->PresContext()->IsRootContentDocument() + ? scrollParts[i]->GetVisualOverflowRectRelativeToParent() + : aDirtyRect; nsDisplayListBuilder::AutoBuildingDisplayList buildingForChild(aBuilder, scrollParts[i], dirty + mOuter->GetOffsetTo(scrollParts[i]), true); @@ -2934,7 +2936,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (addScrollBars) { // Add classic scrollbars. - AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, usingDisplayPort, + AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, createLayersForScrollbars, false); } @@ -2946,7 +2948,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, if (addScrollBars) { // Add overlay scrollbars. - AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, usingDisplayPort, + AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, createLayersForScrollbars, true); } @@ -3001,7 +3003,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, // Note that this does not apply for overlay scrollbars; those are drawn // in the positioned-elements layer on top of everything else by the call // to AppendScrollPartsTo(..., true) further down. - AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, usingDisplayPort, + AppendScrollPartsTo(aBuilder, aDirtyRect, aLists, createLayersForScrollbars, false); if (aBuilder->IsForImageVisibility()) { @@ -3192,7 +3194,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, } } // Now display overlay scrollbars and the resizer, if we have one. - AppendScrollPartsTo(aBuilder, aDirtyRect, scrolledContent, usingDisplayPort, + AppendScrollPartsTo(aBuilder, aDirtyRect, scrolledContent, createLayersForScrollbars, true); scrolledContent.MoveTo(aLists); } diff --git a/layout/generic/nsGfxScrollFrame.h b/layout/generic/nsGfxScrollFrame.h index f8c554e60270..6e37a0adb7b0 100644 --- a/layout/generic/nsGfxScrollFrame.h +++ b/layout/generic/nsGfxScrollFrame.h @@ -77,7 +77,6 @@ public: void AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists, - bool aUsingDisplayPort, bool aCreateLayer, bool aPositioned); From 8a7ec78385a0d2c25ba49dd27707fb78fadd5aae Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 17 Dec 2015 11:20:08 -0800 Subject: [PATCH 054/139] Force a repaint after DXGI device resets. (bug 1188019, r=bas) --- gfx/thebes/gfxPlatform.h | 6 ++++++ gfx/thebes/gfxWindowsPlatform.cpp | 24 ++++++++++++++++++++++++ gfx/thebes/gfxWindowsPlatform.h | 3 ++- layout/base/nsRefreshDriver.cpp | 2 ++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/gfx/thebes/gfxPlatform.h b/gfx/thebes/gfxPlatform.h index 6ce806a198c9..351dfdbc75fb 100644 --- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -605,6 +605,12 @@ public: virtual void FlushContentDrawing() {} + // If a device reset has occurred, update the necessary platform backend + // bits. + virtual bool UpdateForDeviceReset() { + return false; + } + /** * Helper method, creates a draw target for a specific Azure backend. * Used by CreateOffscreenDrawTarget. diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 64c1a310487d..99ee4466daee 100755 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -1192,6 +1192,30 @@ gfxWindowsPlatform::DidRenderingDeviceReset(DeviceResetReason* aResetReason) return false; } +BOOL CALLBACK +InvalidateWindowForDeviceReset(HWND aWnd, LPARAM aMsg) +{ + RedrawWindow(aWnd, nullptr, nullptr, + RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_FRAME); + return TRUE; +} + +bool +gfxWindowsPlatform::UpdateForDeviceReset() +{ + if (!DidRenderingDeviceReset()) { + return false; + } + + // Trigger an ::OnPaint for each window. + ::EnumThreadWindows(GetCurrentThreadId(), + InvalidateWindowForDeviceReset, + 0); + + gfxCriticalNote << "Detected rendering device reset on refresh"; + return true; +} + void gfxWindowsPlatform::GetPlatformCMSOutputProfile(void* &mem, size_t &mem_size) { diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 20ec4c5fc210..02c0af4e6419 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -213,7 +213,8 @@ public: */ virtual bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) override; - virtual bool DidRenderingDeviceReset(DeviceResetReason* aResetReason = nullptr) override; + bool DidRenderingDeviceReset(DeviceResetReason* aResetReason = nullptr) override; + bool UpdateForDeviceReset() override; mozilla::gfx::BackendType GetContentBackendFor(mozilla::layers::LayersBackend aLayers) override; diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index 0248232ed93d..8f5d81e62e0c 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -1644,6 +1644,8 @@ nsRefreshDriver::Tick(int64_t aNowEpoch, TimeStamp aNowTime) AutoRestore restoreTickStart(mTickStart); mTickStart = TimeStamp::Now(); + gfxPlatform::GetPlatform()->UpdateForDeviceReset(); + /* * The timer holds a reference to |this| while calling |Notify|. * However, implementations of |WillRefresh| are permitted to destroy From 0507edf8dcb5e7b3a5757a0698ab18784a18b4fa Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 17 Dec 2015 14:45:44 -0500 Subject: [PATCH 055/139] Bug 1082598 - Part 1: Update Skia to master revision 53c5d5fb795fe04bec050c0583223027c25b839b. r=jrmuizel --- .../skia/include/android/SkBRDAllocator.h | 29 + .../include/android/SkBitmapRegionDecoder.h | 90 + gfx/skia/skia/include/c/sk_canvas.h | 154 + gfx/skia/skia/include/c/sk_data.h | 70 + gfx/skia/skia/include/c/sk_image.h | 71 + gfx/skia/skia/include/c/sk_maskfilter.h | 47 + gfx/skia/skia/include/c/sk_matrix.h | 49 + gfx/skia/skia/include/c/sk_paint.h | 145 + gfx/skia/skia/include/c/sk_path.h | 84 + gfx/skia/skia/include/c/sk_picture.h | 70 + gfx/skia/skia/include/c/sk_shader.h | 143 + gfx/skia/skia/include/c/sk_surface.h | 73 + gfx/skia/skia/include/c/sk_types.h | 205 + gfx/skia/skia/include/codec/SkAndroidCodec.h | 230 + gfx/skia/skia/include/codec/SkCodec.h | 614 ++ gfx/skia/skia/include/codec/SkEncodedFormat.h | 27 + gfx/skia/skia/include/config/SkUserConfig.h | 84 +- gfx/skia/skia/include/core/SkAnnotation.h | 9 +- gfx/skia/skia/include/core/SkBBHFactory.h | 46 +- gfx/skia/skia/include/core/SkBitmap.h | 235 +- gfx/skia/skia/include/core/SkBitmapDevice.h | 116 +- gfx/skia/skia/include/core/SkBlitRow.h | 51 +- gfx/skia/skia/include/core/SkCanvas.h | 611 +- gfx/skia/skia/include/core/SkChunkAlloc.h | 14 +- gfx/skia/skia/include/core/SkClipStack.h | 15 +- gfx/skia/skia/include/core/SkColor.h | 8 +- gfx/skia/skia/include/core/SkColorFilter.h | 78 +- gfx/skia/skia/include/core/SkColorPriv.h | 97 +- gfx/skia/skia/include/core/SkColorTable.h | 90 +- gfx/skia/skia/include/core/SkComposeShader.h | 17 +- gfx/skia/skia/include/core/SkData.h | 83 +- gfx/skia/skia/include/core/SkDataTable.h | 2 - gfx/skia/skia/include/core/SkDevice.h | 207 +- .../skia/include/core/SkDeviceProperties.h | 103 - gfx/skia/skia/include/core/SkDocument.h | 111 +- gfx/skia/skia/include/core/SkDraw.h | 37 +- gfx/skia/skia/include/core/SkDrawFilter.h | 2 - gfx/skia/skia/include/core/SkDrawLooper.h | 8 +- .../skia/include/core/SkDrawPictureCallback.h | 29 - gfx/skia/skia/include/core/SkDrawable.h | 77 + .../skia/include/core/SkDynamicAnnotations.h | 113 - gfx/skia/skia/include/core/SkFilterQuality.h | 24 + gfx/skia/skia/include/core/SkFixed.h | 80 +- gfx/skia/skia/include/core/SkFlattenable.h | 61 +- .../skia/include/core/SkFlattenableBuffers.h | 10 - gfx/skia/skia/include/core/SkFont.h | 16 +- gfx/skia/skia/include/core/SkFontHost.h | 36 - .../include/{ports => core}/SkFontStyle.h | 2 + gfx/skia/skia/include/core/SkGraphics.h | 98 +- gfx/skia/skia/include/core/SkImage.h | 342 +- gfx/skia/skia/include/core/SkImageDecoder.h | 237 +- gfx/skia/skia/include/core/SkImageEncoder.h | 14 +- gfx/skia/skia/include/core/SkImageFilter.h | 285 +- gfx/skia/skia/include/core/SkImageGenerator.h | 189 +- gfx/skia/skia/include/core/SkImageInfo.h | 173 +- gfx/skia/skia/include/core/SkInstCnt.h | 147 - gfx/skia/skia/include/core/SkMallocPixelRef.h | 33 +- gfx/skia/skia/include/core/SkMask.h | 20 +- gfx/skia/skia/include/core/SkMaskFilter.h | 71 +- gfx/skia/skia/include/core/SkMath.h | 37 +- gfx/skia/skia/include/core/SkMatrix.h | 164 +- gfx/skia/skia/include/core/SkMetaData.h | 2 +- .../skia/include/core/SkMultiPictureDraw.h | 75 + gfx/skia/skia/include/core/SkOSFile.h | 66 +- gfx/skia/skia/include/core/SkPackBits.h | 47 +- gfx/skia/skia/include/core/SkPaint.h | 191 +- .../skia/include/core/SkPaintOptionsAndroid.h | 130 - gfx/skia/skia/include/core/SkPatch.h | 124 - gfx/skia/skia/include/core/SkPath.h | 356 +- gfx/skia/skia/include/core/SkPathEffect.h | 43 +- gfx/skia/skia/include/core/SkPathMeasure.h | 3 + gfx/skia/skia/include/core/SkPathRef.h | 117 +- gfx/skia/skia/include/core/SkPicture.h | 287 +- .../skia/include/core/SkPictureRecorder.h | 93 +- gfx/skia/skia/include/core/SkPixelRef.h | 199 +- .../skia/include/core/SkPixelSerializer.h | 52 + gfx/skia/skia/include/core/SkPixmap.h | 265 + gfx/skia/skia/include/core/SkPngChunkReader.h | 45 + gfx/skia/skia/include/core/SkPoint.h | 31 +- gfx/skia/skia/include/core/SkPoint3.h | 124 + gfx/skia/skia/include/core/SkPostConfig.h | 165 +- gfx/skia/skia/include/core/SkPreConfig.h | 53 +- gfx/skia/skia/include/core/SkRRect.h | 60 +- gfx/skia/skia/include/core/SkRSXform.h | 67 + gfx/skia/skia/include/core/SkRasterizer.h | 4 - gfx/skia/skia/include/core/SkRect.h | 189 +- gfx/skia/skia/include/core/SkRefCnt.h | 146 +- gfx/skia/skia/include/core/SkRegion.h | 1 - gfx/skia/skia/include/core/SkScalar.h | 275 +- gfx/skia/skia/include/core/SkShader.h | 175 +- gfx/skia/skia/include/core/SkStream.h | 160 +- gfx/skia/skia/include/core/SkString.h | 30 +- gfx/skia/skia/include/core/SkStrokeRec.h | 58 +- gfx/skia/skia/include/core/SkSurface.h | 182 +- gfx/skia/skia/include/core/SkSurfaceProps.h | 86 + gfx/skia/skia/include/core/SkTArray.h | 73 +- gfx/skia/skia/include/core/SkTDArray.h | 53 +- gfx/skia/skia/include/core/SkTInternalLList.h | 18 +- gfx/skia/skia/include/core/SkTLazy.h | 50 +- gfx/skia/skia/include/core/SkTSearch.h | 2 +- gfx/skia/skia/include/core/SkTextBlob.h | 184 + gfx/skia/skia/include/core/SkThread.h | 143 - gfx/skia/skia/include/core/SkTime.h | 9 +- .../skia/include/core/SkTraceMemoryDump.h | 80 + gfx/skia/skia/include/core/SkTypeface.h | 107 +- gfx/skia/skia/include/core/SkTypes.h | 77 +- gfx/skia/skia/include/core/SkUtils.h | 51 +- gfx/skia/skia/include/core/SkWriteBuffer.h | 28 +- gfx/skia/skia/include/core/SkWriter32.h | 13 +- gfx/skia/skia/include/core/SkXfermode.h | 132 +- .../skia/include/device/xps/SkXPSDevice.h | 57 +- .../skia/include/effects/Sk1DPathEffect.h | 18 +- .../skia/include/effects/Sk2DPathEffect.h | 28 +- .../skia/include/effects/SkArcToPathEffect.h | 40 + .../skia/include/effects/SkAvoidXfermode.h | 68 - .../skia/include/effects/SkBitmapSource.h | 43 - .../skia/include/effects/SkBlurDrawLooper.h | 13 +- .../skia/include/effects/SkBlurImageFilter.h | 32 +- .../skia/include/effects/SkColorCubeFilter.h | 77 + .../effects/SkColorFilterImageFilter.h | 21 +- gfx/skia/skia/include/effects/SkColorMatrix.h | 8 +- .../include/effects/SkColorMatrixFilter.h | 22 +- .../include/effects/SkComposeImageFilter.h | 23 +- .../skia/include/effects/SkCornerPathEffect.h | 14 +- .../skia/include/effects/SkDashPathEffect.h | 18 +- .../include/effects/SkDiscretePathEffect.h | 13 +- .../include/effects/SkDisplacementMapEffect.h | 21 +- .../include/effects/SkDropShadowImageFilter.h | 40 +- .../skia/include/effects/SkEmbossMaskFilter.h | 7 +- .../skia/include/effects/SkGradientShader.h | 84 - gfx/skia/skia/include/effects/SkImageSource.h | 48 + .../skia/include/effects/SkLayerDrawLooper.h | 21 +- .../skia/include/effects/SkLayerRasterizer.h | 5 +- .../skia/include/effects/SkLerpXfermode.h | 9 +- .../include/effects/SkLightingImageFilter.h | 42 +- .../skia/include/effects/SkLumaColorFilter.h | 7 +- .../include/effects/SkMagnifierImageFilter.h | 17 +- .../effects/SkMatrixConvolutionImageFilter.h | 22 +- .../skia/include/effects/SkMergeImageFilter.h | 36 +- .../skia/include/effects/SkModeColorFilter.h | 65 + .../include/effects/SkMorphologyImageFilter.h | 54 +- .../include/effects/SkOffsetImageFilter.h | 31 +- .../include/effects/SkPaintFlagsDrawFilter.h | 2 +- .../include/effects/SkPerlinNoiseShader.h | 34 +- .../include/effects/SkPictureImageFilter.h | 57 +- .../skia/include/effects/SkPixelXorXfermode.h | 14 +- gfx/skia/skia/include/effects/SkPorterDuff.h | 79 - .../include/effects/SkRectShaderImageFilter.h | 16 +- .../include/effects/SkStippleMaskFilter.h | 45 - .../skia/include/effects/SkTableColorFilter.h | 6 + .../skia/include/effects/SkTableMaskFilter.h | 29 +- .../skia/include/effects/SkTestImageFilters.h | 32 +- .../skia/include/effects/SkTileImageFilter.h | 28 +- .../include/effects/SkTransparentShader.h | 46 - .../include/effects/SkXfermodeImageFilter.h | 22 +- .../skia/include/gpu/GrBackendEffectFactory.h | 144 - gfx/skia/skia/include/gpu/GrBlend.h | 228 + gfx/skia/skia/include/gpu/GrCaps.h | 287 + gfx/skia/skia/include/gpu/GrClip.h | 185 + gfx/skia/skia/include/gpu/GrClipData.h | 61 - gfx/skia/skia/include/gpu/GrColor.h | 111 +- gfx/skia/skia/include/gpu/GrConfig.h | 87 +- gfx/skia/skia/include/gpu/GrContext.h | 1063 +--- gfx/skia/skia/include/gpu/GrContextFactory.h | 199 - gfx/skia/skia/include/gpu/GrContextOptions.h | 65 + gfx/skia/skia/include/gpu/GrCoordTransform.h | 122 +- gfx/skia/skia/include/gpu/GrDrawContext.h | 313 ++ gfx/skia/skia/include/gpu/GrDrawEffect.h | 50 - gfx/skia/skia/include/gpu/GrEffect.h | 230 - gfx/skia/skia/include/gpu/GrEffectStage.h | 141 - gfx/skia/skia/include/gpu/GrEffectUnitTest.h | 101 - gfx/skia/skia/include/gpu/GrFontScaler.h | 85 - .../skia/include/gpu/GrFragmentProcessor.h | 219 + gfx/skia/skia/include/gpu/GrGpuResource.h | 340 +- gfx/skia/skia/include/gpu/GrGpuResourceRef.h | 213 + gfx/skia/skia/include/gpu/GrInvariantOutput.h | 330 ++ gfx/skia/skia/include/gpu/GrPaint.h | 241 +- gfx/skia/skia/include/gpu/GrProcessor.h | 153 + .../skia/include/gpu/GrProcessorUnitTest.h | 153 + gfx/skia/skia/include/gpu/GrProgramElement.h | 148 + gfx/skia/skia/include/gpu/GrRenderTarget.h | 175 +- gfx/skia/skia/include/gpu/GrResourceKey.h | 321 ++ gfx/skia/skia/include/gpu/GrShaderVar.h | 191 + gfx/skia/skia/include/gpu/GrSurface.h | 132 +- .../include/gpu/GrTBackendEffectFactory.h | 77 - gfx/skia/skia/include/gpu/GrTestUtils.h | 105 + gfx/skia/skia/include/gpu/GrTexture.h | 180 +- gfx/skia/skia/include/gpu/GrTextureAccess.h | 123 +- gfx/skia/skia/include/gpu/GrTextureParams.h | 110 + gfx/skia/skia/include/gpu/GrTextureProvider.h | 191 + gfx/skia/skia/include/gpu/GrTypes.h | 293 +- gfx/skia/skia/include/gpu/GrTypesPriv.h | 230 +- gfx/skia/skia/include/gpu/GrUserConfig.h | 40 - gfx/skia/skia/include/gpu/GrXferProcessor.h | 389 ++ gfx/skia/skia/include/gpu/SkGpuDevice.h | 221 - gfx/skia/skia/include/gpu/SkGr.h | 125 +- gfx/skia/skia/include/gpu/SkGrPixelRef.h | 24 +- .../gpu/effects/GrConstColorProcessor.h | 66 + .../include/gpu/effects/GrCoverageSetOpXP.h | 56 + .../include/gpu/effects/GrCustomXfermode.h | 24 + .../gpu/effects/GrPorterDuffXferProcessor.h | 75 + .../gpu/effects/GrXfermodeFragmentProcessor.h | 34 + gfx/skia/skia/include/gpu/gl/GrGLConfig.h | 58 +- .../skia/include/gpu/gl/GrGLConfig_chrome.h | 15 - gfx/skia/skia/include/gpu/gl/GrGLExtensions.h | 11 +- gfx/skia/skia/include/gpu/gl/GrGLFunctions.h | 568 +- gfx/skia/skia/include/gpu/gl/GrGLInterface.h | 193 +- .../skia/include/gpu/gl/GrGLSLPrettyPrint.h | 19 + gfx/skia/skia/include/gpu/gl/GrGLTypes.h | 86 + .../skia/include/gpu/gl/SkANGLEGLContext.h | 51 - .../skia/include/gpu/gl/SkDebugGLContext.h | 27 - gfx/skia/skia/include/gpu/gl/SkGLContext.h | 133 + .../skia/include/gpu/gl/SkGLContextHelper.h | 87 - .../skia/include/gpu/gl/SkMesaGLContext.h | 51 - .../skia/include/gpu/gl/SkNativeGLContext.h | 88 - .../skia/include/gpu/gl/SkNullGLContext.h | 21 +- .../include/gpu/gl/angle/SkANGLEGLContext.h | 54 + .../command_buffer/SkCommandBufferGLContext.h | 66 + .../include/images/SkDecodingImageGenerator.h | 16 +- gfx/skia/skia/include/images/SkForceLinking.h | 2 +- gfx/skia/skia/include/images/SkMovie.h | 2 +- gfx/skia/skia/include/pathops/SkPathOps.h | 43 +- gfx/skia/skia/include/pdf/SkPDFDevice.h | 345 -- gfx/skia/skia/include/pdf/SkPDFDocument.h | 113 - gfx/skia/skia/include/pipe/SkGPipe.h | 8 +- .../skia/include/ports/SkAtomics_atomic.h | 59 + gfx/skia/skia/include/ports/SkAtomics_std.h | 71 + gfx/skia/skia/include/ports/SkAtomics_sync.h | 73 + .../include/ports/SkFontConfigInterface.h | 29 +- gfx/skia/skia/include/ports/SkFontMgr.h | 42 +- .../skia/include/ports/SkFontMgr_android.h | 47 + .../skia/include/ports/SkFontMgr_custom.h | 18 + .../skia/include/ports/SkFontMgr_fontconfig.h | 22 + .../skia/include/ports/SkFontMgr_indirect.h | 33 +- .../skia/include/ports/SkRemotableFontMgr.h | 14 +- .../skia/include/ports/SkTypeface_android.h | 77 - .../skia/include/ports/SkTypeface_cairo.h | 2 +- gfx/skia/skia/include/ports/SkTypeface_mac.h | 30 +- gfx/skia/skia/include/ports/SkTypeface_win.h | 5 +- gfx/skia/skia/include/private/SkAtomics.h | 137 + gfx/skia/skia/include/private/SkChecksum.h | 75 + .../include/{core => private}/SkFloatBits.h | 1 - .../{core => private}/SkFloatingPoint.h | 111 +- .../skia/include/private/SkGpuFenceSync.h | 29 + .../skia/include/private/SkMiniRecorder.h | 60 + gfx/skia/skia/include/private/SkMutex.h | 125 + .../skia/include/{core => private}/SkOnce.h | 61 +- gfx/skia/skia/include/private/SkOncePtr.h | 106 + gfx/skia/skia/include/private/SkRecords.h | 370 ++ gfx/skia/skia/include/private/SkSemaphore.h | 86 + gfx/skia/skia/include/private/SkSpinlock.h | 44 + gfx/skia/skia/include/private/SkTHash.h | 301 + gfx/skia/skia/include/private/SkTLogic.h | 228 + .../include/{core => private}/SkTemplates.h | 228 +- gfx/skia/skia/include/private/SkThreadID.h | 19 + gfx/skia/skia/include/private/SkUniquePtr.h | 400 ++ gfx/skia/skia/include/private/SkUtility.h | 32 + .../include/{core => private}/SkWeakRefCnt.h | 6 +- gfx/skia/skia/include/record/SkRecording.h | 75 - gfx/skia/skia/include/svg/SkSVGCanvas.h | 31 + .../include/svg/{ => parser}/SkSVGAttribute.h | 3 +- .../skia/include/svg/{ => parser}/SkSVGBase.h | 0 .../svg/{ => parser}/SkSVGPaintState.h | 0 .../include/svg/{ => parser}/SkSVGParser.h | 1 - .../include/svg/{ => parser}/SkSVGTypes.h | 0 gfx/skia/skia/include/utils/SkBoundaryPatch.h | 2 +- gfx/skia/skia/include/utils/SkCamera.h | 4 +- .../skia/include/utils/SkCanvasStateUtils.h | 9 +- gfx/skia/skia/include/utils/SkCondVar.h | 78 - gfx/skia/skia/include/utils/SkDebugUtils.h | 8 +- .../skia/include/utils/SkDeferredCanvas.h | 253 - gfx/skia/skia/include/utils/SkDumpCanvas.h | 95 +- gfx/skia/skia/include/utils/SkEventTracer.h | 7 +- .../include/utils/SkFrontBufferedStream.h | 6 +- gfx/skia/skia/include/utils/SkJSONCPP.h | 30 +- gfx/skia/skia/include/utils/SkLayer.h | 2 +- gfx/skia/skia/include/utils/SkLua.h | 2 + gfx/skia/skia/include/utils/SkLuaCanvas.h | 76 +- gfx/skia/skia/include/utils/SkMatrix44.h | 57 +- gfx/skia/skia/include/utils/SkNWayCanvas.h | 90 +- .../skia/include/utils/SkNoSaveLayerCanvas.h | 21 +- .../skia/include/utils/SkPaintFilterCanvas.h | 102 + gfx/skia/skia/include/utils/SkParse.h | 2 +- gfx/skia/skia/include/utils/SkPathUtils.h | 40 - gfx/skia/skia/include/utils/SkPictureUtils.h | 71 +- gfx/skia/skia/include/utils/SkProxyCanvas.h | 89 - gfx/skia/skia/include/utils/SkRTConf.h | 11 +- gfx/skia/skia/include/utils/SkRandom.h | 139 - gfx/skia/skia/include/utils/SkRunnable.h | 25 - .../skia/include/{views => utils}/SkTextBox.h | 10 + gfx/skia/skia/include/utils/SkThreadPool.h | 221 - .../skia/include/utils/ios/SkStream_NSData.h | 41 - gfx/skia/skia/include/utils/mac/SkCGUtils.h | 22 +- .../include/utils/win/SkAutoCoInitialize.h | 11 +- gfx/skia/skia/include/utils/win/SkHRESULT.h | 4 +- gfx/skia/skia/include/utils/win/SkIStream.h | 15 +- .../skia/include/utils/win/SkTScopedComPtr.h | 9 +- gfx/skia/skia/include/views/SkEvent.h | 2 +- gfx/skia/skia/include/views/SkEventSink.h | 2 +- .../skia/include/views/SkOSWindow_Android.h | 34 +- gfx/skia/skia/include/views/SkOSWindow_Mac.h | 14 +- gfx/skia/skia/include/views/SkOSWindow_NaCl.h | 52 - gfx/skia/skia/include/views/SkOSWindow_SDL.h | 52 +- gfx/skia/skia/include/views/SkOSWindow_Unix.h | 21 +- gfx/skia/skia/include/views/SkOSWindow_Win.h | 68 +- gfx/skia/skia/include/views/SkOSWindow_iOS.h | 9 +- gfx/skia/skia/include/views/SkView.h | 12 +- gfx/skia/skia/include/views/SkWidget.h | 8 +- gfx/skia/skia/include/views/SkWindow.h | 42 +- .../include/views/android/AndroidKeyToSkKey.h | 35 - .../include/views/animated/SkWidgetViews.h | 2 +- gfx/skia/skia/include/xml/SkBML_WXMLParser.h | 2 +- gfx/skia/skia/include/xml/SkDOM.h | 14 +- gfx/skia/skia/include/xml/SkJS.h | 39 - gfx/skia/skia/include/xml/SkXMLWriter.h | 28 +- .../skia/src/android/SkBitmapRegionCanvas.cpp | 140 + .../skia/src/android/SkBitmapRegionCanvas.h | 41 + .../skia/src/android/SkBitmapRegionCodec.cpp | 147 + .../skia/src/android/SkBitmapRegionCodec.h | 37 + .../src/android/SkBitmapRegionDecoder.cpp | 76 + .../src/android/SkBitmapRegionDecoderPriv.h | 59 + .../{SkDrawable.cpp => SkADrawable.cpp} | 10 +- .../animator/{SkDrawable.h => SkADrawable.h} | 8 +- gfx/skia/skia/src/animator/SkAnimate.h | 6 +- .../skia/src/animator/SkAnimateActive.cpp | 16 +- gfx/skia/skia/src/animator/SkAnimateActive.h | 2 +- gfx/skia/skia/src/animator/SkAnimateBase.cpp | 10 +- gfx/skia/skia/src/animator/SkAnimateBase.h | 20 +- gfx/skia/skia/src/animator/SkAnimateField.cpp | 12 +- gfx/skia/skia/src/animator/SkAnimateMaker.cpp | 24 +- gfx/skia/skia/src/animator/SkAnimateMaker.h | 2 +- gfx/skia/skia/src/animator/SkAnimateSet.cpp | 8 +- gfx/skia/skia/src/animator/SkAnimateSet.h | 6 +- gfx/skia/skia/src/animator/SkAnimator.cpp | 78 +- .../skia/src/animator/SkAnimatorScript.cpp | 24 +- .../skia/src/animator/SkAnimatorScript2.cpp | 20 +- gfx/skia/skia/src/animator/SkBoundable.cpp | 2 +- gfx/skia/skia/src/animator/SkBoundable.h | 6 +- .../src/animator/SkBuildCondensedInfo.cpp | 14 +- gfx/skia/skia/src/animator/SkDisplayAdd.cpp | 28 +- gfx/skia/skia/src/animator/SkDisplayAdd.h | 24 +- gfx/skia/skia/src/animator/SkDisplayApply.cpp | 80 +- gfx/skia/skia/src/animator/SkDisplayApply.h | 42 +- gfx/skia/skia/src/animator/SkDisplayBounds.h | 2 +- gfx/skia/skia/src/animator/SkDisplayEvent.cpp | 12 +- gfx/skia/skia/src/animator/SkDisplayEvent.h | 12 +- .../skia/src/animator/SkDisplayEvents.cpp | 14 +- .../skia/src/animator/SkDisplayInclude.cpp | 7 - gfx/skia/skia/src/animator/SkDisplayInclude.h | 6 +- gfx/skia/skia/src/animator/SkDisplayInput.cpp | 2 +- gfx/skia/skia/src/animator/SkDisplayInput.h | 8 +- gfx/skia/skia/src/animator/SkDisplayList.cpp | 24 +- gfx/skia/skia/src/animator/SkDisplayList.h | 10 +- gfx/skia/skia/src/animator/SkDisplayMath.cpp | 2 +- gfx/skia/skia/src/animator/SkDisplayMath.h | 8 +- gfx/skia/skia/src/animator/SkDisplayMovie.cpp | 6 +- gfx/skia/skia/src/animator/SkDisplayMovie.h | 24 +- gfx/skia/skia/src/animator/SkDisplayNumber.h | 2 +- gfx/skia/skia/src/animator/SkDisplayPost.cpp | 16 +- gfx/skia/skia/src/animator/SkDisplayPost.h | 18 +- gfx/skia/skia/src/animator/SkDisplayRandom.h | 6 +- gfx/skia/skia/src/animator/SkDisplayType.cpp | 31 +- gfx/skia/skia/src/animator/SkDisplayTypes.cpp | 2 +- gfx/skia/skia/src/animator/SkDisplayTypes.h | 16 +- .../skia/src/animator/SkDisplayXMLParser.cpp | 34 +- gfx/skia/skia/src/animator/SkDisplayable.cpp | 32 +- gfx/skia/skia/src/animator/SkDraw3D.cpp | 2 +- gfx/skia/skia/src/animator/SkDraw3D.h | 12 +- gfx/skia/skia/src/animator/SkDrawBitmap.cpp | 6 +- gfx/skia/skia/src/animator/SkDrawBitmap.h | 18 +- gfx/skia/skia/src/animator/SkDrawBlur.cpp | 2 +- gfx/skia/skia/src/animator/SkDrawBlur.h | 2 +- gfx/skia/skia/src/animator/SkDrawClip.cpp | 6 +- gfx/skia/skia/src/animator/SkDrawClip.h | 6 +- gfx/skia/skia/src/animator/SkDrawColor.cpp | 8 +- gfx/skia/skia/src/animator/SkDrawColor.h | 18 +- gfx/skia/skia/src/animator/SkDrawDash.cpp | 2 +- gfx/skia/skia/src/animator/SkDrawDash.h | 2 +- gfx/skia/skia/src/animator/SkDrawDiscrete.cpp | 2 +- gfx/skia/skia/src/animator/SkDrawDiscrete.h | 2 +- gfx/skia/skia/src/animator/SkDrawEmboss.cpp | 2 +- gfx/skia/skia/src/animator/SkDrawEmboss.h | 2 +- .../src/animator/SkDrawExtraPathEffect.cpp | 72 +- gfx/skia/skia/src/animator/SkDrawFull.h | 2 +- gfx/skia/skia/src/animator/SkDrawGradient.cpp | 4 +- gfx/skia/skia/src/animator/SkDrawGradient.h | 14 +- gfx/skia/skia/src/animator/SkDrawGroup.cpp | 66 +- gfx/skia/skia/src/animator/SkDrawGroup.h | 40 +- gfx/skia/skia/src/animator/SkDrawLine.h | 2 +- gfx/skia/skia/src/animator/SkDrawMatrix.cpp | 14 +- gfx/skia/skia/src/animator/SkDrawMatrix.h | 28 +- gfx/skia/skia/src/animator/SkDrawOval.h | 2 +- gfx/skia/skia/src/animator/SkDrawPaint.cpp | 26 +- gfx/skia/skia/src/animator/SkDrawPaint.h | 22 +- gfx/skia/skia/src/animator/SkDrawPath.cpp | 2 +- gfx/skia/skia/src/animator/SkDrawPath.h | 30 +- gfx/skia/skia/src/animator/SkDrawPoint.h | 2 +- .../skia/src/animator/SkDrawRectangle.cpp | 2 +- gfx/skia/skia/src/animator/SkDrawRectangle.h | 18 +- .../skia/src/animator/SkDrawSaveLayer.cpp | 2 +- gfx/skia/skia/src/animator/SkDrawSaveLayer.h | 6 +- gfx/skia/skia/src/animator/SkDrawShader.cpp | 22 +- gfx/skia/skia/src/animator/SkDrawShader.h | 4 +- gfx/skia/skia/src/animator/SkDrawText.h | 6 +- gfx/skia/skia/src/animator/SkDrawTextBox.h | 8 +- gfx/skia/skia/src/animator/SkDrawTo.cpp | 2 +- gfx/skia/skia/src/animator/SkDrawTo.h | 4 +- .../src/animator/SkDrawTransparentShader.cpp | 15 - .../src/animator/SkDrawTransparentShader.h | 18 - gfx/skia/skia/src/animator/SkDump.cpp | 6 +- gfx/skia/skia/src/animator/SkDump.h | 10 +- .../skia/src/animator/SkGetCondensedInfo.cpp | 14 +- gfx/skia/skia/src/animator/SkHitClear.h | 4 +- gfx/skia/skia/src/animator/SkHitTest.h | 12 +- gfx/skia/skia/src/animator/SkIntArray.h | 4 +- gfx/skia/skia/src/animator/SkMatrixParts.cpp | 22 +- gfx/skia/skia/src/animator/SkMatrixParts.h | 24 +- gfx/skia/skia/src/animator/SkMemberInfo.cpp | 30 +- gfx/skia/skia/src/animator/SkMemberInfo.h | 57 +- gfx/skia/skia/src/animator/SkOperand.h | 6 +- .../src/animator/SkOperandIterpolator.cpp | 2 +- gfx/skia/skia/src/animator/SkPaintPart.cpp | 12 +- gfx/skia/skia/src/animator/SkPaintPart.h | 12 +- gfx/skia/skia/src/animator/SkParseSVGPath.cpp | 2 +- gfx/skia/skia/src/animator/SkPathParts.cpp | 8 +- gfx/skia/skia/src/animator/SkPathParts.h | 28 +- gfx/skia/skia/src/animator/SkPostParts.cpp | 2 +- gfx/skia/skia/src/animator/SkPostParts.h | 8 +- gfx/skia/skia/src/animator/SkScript.cpp | 34 +- .../skia/src/animator/SkScriptRuntime.cpp | 16 +- .../skia/src/animator/SkScriptTokenizer.cpp | 32 +- gfx/skia/skia/src/animator/SkSnapshot.h | 6 +- .../src/animator/SkTDArray_Experimental.h | 18 +- gfx/skia/skia/src/animator/SkTextOnPath.cpp | 2 +- gfx/skia/skia/src/animator/SkTextOnPath.h | 2 +- gfx/skia/skia/src/animator/SkTextToPath.cpp | 4 +- gfx/skia/skia/src/animator/SkTextToPath.h | 6 +- gfx/skia/skia/src/animator/SkTime.cpp | 18 - gfx/skia/skia/src/animator/SkTypedArray.cpp | 14 +- .../skia/src/animator/SkXMLAnimatorWriter.cpp | 6 +- .../skia/src/animator/SkXMLAnimatorWriter.h | 11 +- gfx/skia/skia/src/c/sk_c_from_to.h | 34 + gfx/skia/skia/src/c/sk_paint.cpp | 170 + gfx/skia/skia/src/c/sk_surface.cpp | 708 +++ gfx/skia/skia/src/c/sk_types_priv.h | 41 + gfx/skia/skia/src/codec/SkAndroidCodec.cpp | 132 + gfx/skia/skia/src/codec/SkBmpCodec.cpp | 580 ++ gfx/skia/skia/src/codec/SkBmpCodec.h | 152 + gfx/skia/skia/src/codec/SkBmpMaskCodec.cpp | 108 + gfx/skia/skia/src/codec/SkBmpMaskCodec.h | 62 + gfx/skia/skia/src/codec/SkBmpRLECodec.cpp | 514 ++ gfx/skia/skia/src/codec/SkBmpRLECodec.h | 103 + .../skia/src/codec/SkBmpStandardCodec.cpp | 298 + gfx/skia/skia/src/codec/SkBmpStandardCodec.h | 90 + gfx/skia/skia/src/codec/SkCodec.cpp | 361 ++ gfx/skia/skia/src/codec/SkCodecPriv.h | 256 + gfx/skia/skia/src/codec/SkCodec_libgif.cpp | 591 ++ gfx/skia/skia/src/codec/SkCodec_libgif.h | 207 + gfx/skia/skia/src/codec/SkCodec_libico.cpp | 302 + gfx/skia/skia/src/codec/SkCodec_libico.h | 63 + gfx/skia/skia/src/codec/SkCodec_libpng.cpp | 875 +++ gfx/skia/skia/src/codec/SkCodec_libpng.h | 83 + gfx/skia/skia/src/codec/SkCodec_wbmp.cpp | 209 + gfx/skia/skia/src/codec/SkCodec_wbmp.h | 63 + gfx/skia/skia/src/codec/SkJpegCodec.cpp | 456 ++ gfx/skia/skia/src/codec/SkJpegCodec.h | 126 + gfx/skia/skia/src/codec/SkJpegDecoderMgr.cpp | 74 + gfx/skia/skia/src/codec/SkJpegDecoderMgr.h | 76 + .../skia/src/codec/SkJpegUtility_codec.cpp | 94 + gfx/skia/skia/src/codec/SkJpegUtility_codec.h | 50 + gfx/skia/skia/src/codec/SkMaskSwizzler.cpp | 400 ++ gfx/skia/skia/src/codec/SkMaskSwizzler.h | 71 + gfx/skia/skia/src/codec/SkMasks.cpp | 161 + gfx/skia/skia/src/codec/SkMasks.h | 86 + gfx/skia/skia/src/codec/SkSampledCodec.cpp | 296 + gfx/skia/skia/src/codec/SkSampledCodec.h | 64 + gfx/skia/skia/src/codec/SkSampler.cpp | 102 + gfx/skia/skia/src/codec/SkSampler.h | 62 + gfx/skia/skia/src/codec/SkSwizzler.cpp | 835 +++ gfx/skia/skia/src/codec/SkSwizzler.h | 278 + .../skia/src/codec/SkWebpAdapterCodec.cpp | 46 + gfx/skia/skia/src/codec/SkWebpAdapterCodec.h | 41 + gfx/skia/skia/src/codec/SkWebpCodec.cpp | 255 + gfx/skia/skia/src/codec/SkWebpCodec.h | 42 + gfx/skia/skia/src/core/Sk4px.h | 249 + gfx/skia/skia/src/core/SkAAClip.cpp | 149 +- gfx/skia/skia/src/core/SkAAClip.h | 29 +- .../src/core/SkAdvancedTypefaceMetrics.cpp | 6 +- .../core/SkAdvancedTypefaceMetrics.h | 34 +- gfx/skia/skia/src/core/SkAnnotation.cpp | 14 +- gfx/skia/skia/src/core/SkBBHFactory.cpp | 38 +- gfx/skia/skia/src/core/SkBBoxHierarchy.h | 79 +- .../skia/src/core/SkBBoxHierarchyRecord.cpp | 112 - .../skia/src/core/SkBBoxHierarchyRecord.h | 47 - gfx/skia/skia/src/core/SkBBoxRecord.cpp | 347 -- gfx/skia/skia/src/core/SkBBoxRecord.h | 91 - gfx/skia/skia/src/core/SkBigPicture.cpp | 99 + gfx/skia/skia/src/core/SkBigPicture.h | 89 + gfx/skia/skia/src/core/SkBitmap.cpp | 717 ++- gfx/skia/skia/src/core/SkBitmapCache.cpp | 306 + gfx/skia/skia/src/core/SkBitmapCache.h | 81 + gfx/skia/skia/src/core/SkBitmapController.cpp | 221 + gfx/skia/skia/src/core/SkBitmapController.h | 65 + gfx/skia/skia/src/core/SkBitmapDevice.cpp | 207 +- gfx/skia/skia/src/core/SkBitmapFilter.cpp | 130 +- gfx/skia/skia/src/core/SkBitmapFilter.h | 16 +- gfx/skia/skia/src/core/SkBitmapHeap.cpp | 82 +- gfx/skia/skia/src/core/SkBitmapHeap.h | 48 +- gfx/skia/skia/src/core/SkBitmapProcShader.cpp | 252 +- gfx/skia/skia/src/core/SkBitmapProcShader.h | 57 +- gfx/skia/skia/src/core/SkBitmapProcState.cpp | 587 +- gfx/skia/skia/src/core/SkBitmapProcState.h | 74 +- .../skia/src/core/SkBitmapProcState_matrix.h | 12 +- .../core/SkBitmapProcState_matrixProcs.cpp | 26 +- .../core/SkBitmapProcState_matrix_template.h | 12 +- .../skia/src/core/SkBitmapProcState_procs.h | 69 +- .../skia/src/core/SkBitmapProcState_sample.h | 52 +- .../src/core/SkBitmapProcState_shaderproc.h | 12 +- gfx/skia/skia/src/core/SkBitmapProvider.cpp | 87 + gfx/skia/skia/src/core/SkBitmapProvider.h | 45 + gfx/skia/skia/src/core/SkBitmapScaler.cpp | 165 +- gfx/skia/skia/src/core/SkBitmapScaler.h | 66 +- gfx/skia/skia/src/core/SkBitmap_scroll.cpp | 105 - gfx/skia/skia/src/core/SkBlitBWMaskTemplate.h | 10 +- gfx/skia/skia/src/core/SkBlitMask.h | 22 +- gfx/skia/skia/src/core/SkBlitMask_D32.cpp | 331 +- gfx/skia/skia/src/core/SkBlitRow_D16.cpp | 72 +- gfx/skia/skia/src/core/SkBlitRow_D32.cpp | 124 +- gfx/skia/skia/src/core/SkBlitter.cpp | 324 +- gfx/skia/skia/src/core/SkBlitter.h | 121 +- gfx/skia/skia/src/core/SkBlitter_A8.cpp | 60 +- gfx/skia/skia/src/core/SkBlitter_ARGB32.cpp | 117 +- gfx/skia/skia/src/core/SkBlitter_RGB16.cpp | 227 +- gfx/skia/skia/src/core/SkBlitter_Sprite.cpp | 26 +- gfx/skia/skia/src/core/SkBuffer.cpp | 10 +- gfx/skia/skia/src/core/SkBuffer.h | 3 +- gfx/skia/skia/src/core/SkCachedData.cpp | 198 + gfx/skia/skia/src/core/SkCachedData.h | 112 + gfx/skia/skia/src/core/SkCanvas.cpp | 2332 ++++---- gfx/skia/skia/src/core/SkCanvasPriv.h | 23 + gfx/skia/skia/src/core/SkChecksum.cpp | 47 + gfx/skia/skia/src/core/SkChecksum.h | 155 - gfx/skia/skia/src/core/SkChunkAlloc.cpp | 127 +- gfx/skia/skia/src/core/SkClipStack.cpp | 133 +- gfx/skia/skia/src/core/SkColor.cpp | 17 +- gfx/skia/skia/src/core/SkColorFilter.cpp | 131 +- .../{include => src}/core/SkColorShader.h | 40 +- gfx/skia/skia/src/core/SkColorTable.cpp | 112 +- gfx/skia/skia/src/core/SkComposeShader.cpp | 82 +- gfx/skia/skia/src/core/SkConfig8888.cpp | 82 +- gfx/skia/skia/src/core/SkConfig8888.h | 15 +- gfx/skia/skia/src/core/SkConvolver.cpp | 31 +- gfx/skia/skia/src/core/SkConvolver.h | 15 +- gfx/skia/skia/src/core/SkCoreBlitters.h | 90 +- gfx/skia/skia/src/core/SkData.cpp | 126 +- gfx/skia/skia/src/core/SkDataTable.cpp | 37 +- gfx/skia/skia/src/core/SkDebug.cpp | 6 + gfx/skia/skia/src/core/SkDeque.cpp | 92 +- gfx/skia/skia/src/core/SkDescriptor.h | 29 +- gfx/skia/skia/src/core/SkDevice.cpp | 381 +- .../skia/src/core/SkDeviceImageFilterProxy.h | 33 - gfx/skia/skia/src/core/SkDeviceLooper.cpp | 38 +- gfx/skia/skia/src/core/SkDeviceLooper.h | 15 +- gfx/skia/skia/src/core/SkDeviceProfile.cpp | 8 +- gfx/skia/skia/src/core/SkDeviceProfile.h | 6 +- gfx/skia/skia/src/core/SkDiscardableMemory.h | 4 +- gfx/skia/skia/src/core/SkDistanceFieldGen.cpp | 16 +- gfx/skia/skia/src/core/SkDistanceFieldGen.h | 4 +- gfx/skia/skia/src/core/SkDraw.cpp | 894 +-- gfx/skia/skia/src/core/SkDrawLooper.cpp | 9 +- gfx/skia/skia/src/core/SkDrawProcs.h | 73 - gfx/skia/skia/src/core/SkDrawable.cpp | 85 + gfx/skia/skia/src/core/SkEdge.cpp | 23 +- gfx/skia/skia/src/core/SkEdge.h | 7 +- gfx/skia/skia/src/core/SkEdgeBuilder.cpp | 61 +- gfx/skia/skia/src/core/SkEdgeBuilder.h | 8 +- gfx/skia/skia/src/core/SkEdgeClipper.cpp | 192 +- gfx/skia/skia/src/core/SkEdgeClipper.h | 5 + gfx/skia/skia/src/core/SkEmptyShader.h | 16 +- .../skia/{include => src}/core/SkEndian.h | 6 +- gfx/skia/skia/src/core/SkError.cpp | 32 +- gfx/skia/skia/src/core/SkFilterShader.cpp | 41 +- gfx/skia/skia/src/core/SkFilterShader.h | 17 +- gfx/skia/skia/src/core/SkFindAndPlaceGlyph.h | 712 +++ gfx/skia/skia/src/core/SkFlate.cpp | 140 - gfx/skia/skia/src/core/SkFlate.h | 52 - gfx/skia/skia/src/core/SkFlattenable.cpp | 36 +- .../src/core/SkFlattenableSerialization.cpp | 6 +- gfx/skia/skia/src/core/SkFloat.cpp | 387 -- gfx/skia/skia/src/core/SkFloat.h | 107 - gfx/skia/skia/src/core/SkFloatBits.cpp | 24 +- gfx/skia/skia/src/core/SkFont.cpp | 10 +- gfx/skia/skia/src/core/SkFontDescriptor.cpp | 81 +- gfx/skia/skia/src/core/SkFontDescriptor.h | 55 +- gfx/skia/skia/src/core/SkFontHost.cpp | 208 - gfx/skia/skia/src/core/SkFontMgr.cpp | 268 + gfx/skia/skia/src/core/SkFontStream.cpp | 2 +- gfx/skia/skia/src/core/SkFontStream.h | 2 +- gfx/skia/skia/src/core/SkFontStyle.cpp | 33 + .../skia/src/core/SkForceCPlusPlusLinking.cpp | 20 + gfx/skia/skia/src/core/SkGeometry.cpp | 753 +-- gfx/skia/skia/src/core/SkGeometry.h | 135 +- gfx/skia/skia/src/core/SkGlyph.h | 96 +- gfx/skia/skia/src/core/SkGlyphCache.cpp | 584 +- gfx/skia/skia/src/core/SkGlyphCache.h | 247 +- gfx/skia/skia/src/core/SkGlyphCache_Globals.h | 40 +- gfx/skia/skia/src/core/SkGraphics.cpp | 92 +- gfx/skia/skia/src/core/SkHalf.cpp | 97 + gfx/skia/skia/src/core/SkHalf.h | 26 + gfx/skia/skia/src/core/SkImageCacherator.cpp | 355 ++ gfx/skia/skia/src/core/SkImageCacherator.h | 101 + gfx/skia/skia/src/core/SkImageFilter.cpp | 515 +- gfx/skia/skia/src/core/SkImageGenerator.cpp | 190 +- gfx/skia/skia/src/core/SkImageGeneratorPriv.h | 15 +- gfx/skia/skia/src/core/SkImageInfo.cpp | 62 +- gfx/skia/skia/src/core/SkLayerInfo.h | 85 + gfx/skia/skia/src/core/SkLazyFnPtr.h | 67 - gfx/skia/skia/src/core/SkLazyPtr.h | 158 - gfx/skia/skia/src/core/SkLight.h | 56 + gfx/skia/skia/src/core/SkLightingShader.cpp | 725 +++ gfx/skia/skia/src/core/SkLightingShader.h | 100 + gfx/skia/skia/src/core/SkLineClipper.cpp | 14 +- gfx/skia/skia/src/core/SkLineClipper.h | 5 +- .../src/core/SkLocalMatrixImageFilter.cpp | 58 + .../skia/src/core/SkLocalMatrixImageFilter.h | 40 + .../skia/src/core/SkLocalMatrixShader.cpp | 24 +- gfx/skia/skia/src/core/SkLocalMatrixShader.h | 39 +- gfx/skia/skia/src/core/SkMallocPixelRef.cpp | 100 +- gfx/skia/skia/src/core/SkMask.cpp | 15 +- gfx/skia/skia/src/core/SkMaskCache.cpp | 191 + gfx/skia/skia/src/core/SkMaskCache.h | 44 + gfx/skia/skia/src/core/SkMaskFilter.cpp | 47 +- gfx/skia/skia/src/core/SkMaskGamma.cpp | 12 +- gfx/skia/skia/src/core/SkMaskGamma.h | 12 +- gfx/skia/skia/src/core/SkMath.cpp | 134 - gfx/skia/skia/src/core/SkMathPriv.h | 14 +- gfx/skia/skia/src/core/SkMatrix.cpp | 445 +- .../skia/src/core/SkMatrixClipStateMgr.cpp | 419 -- gfx/skia/skia/src/core/SkMatrixClipStateMgr.h | 406 -- .../{effects => core}/SkMatrixImageFilter.cpp | 60 +- .../core}/SkMatrixImageFilter.h | 20 +- gfx/skia/skia/src/core/SkMessageBus.h | 35 +- gfx/skia/skia/src/core/SkMetaData.cpp | 22 +- gfx/skia/skia/src/core/SkMiniRecorder.cpp | 140 + gfx/skia/skia/src/core/SkMipMap.cpp | 270 +- gfx/skia/skia/src/core/SkMipMap.h | 23 +- gfx/skia/skia/src/core/SkMultiPictureDraw.cpp | 207 + gfx/skia/skia/src/core/SkNextID.h | 21 + gfx/skia/skia/src/core/SkNinePatchIter.cpp | 72 + gfx/skia/skia/src/core/SkNinePatchIter.h | 42 + gfx/skia/skia/src/core/SkNx.h | 336 ++ gfx/skia/skia/src/core/SkOpts.cpp | 135 + gfx/skia/skia/src/core/SkOpts.h | 62 + gfx/skia/skia/src/core/SkPackBits.cpp | 354 +- gfx/skia/skia/src/core/SkPaint.cpp | 1148 ++-- .../skia/src/core/SkPaintOptionsAndroid.cpp | 41 - gfx/skia/skia/src/core/SkPaintPriv.cpp | 100 +- gfx/skia/skia/src/core/SkPaintPriv.h | 52 +- gfx/skia/skia/src/core/SkPatch.cpp | 224 - gfx/skia/skia/src/core/SkPath.cpp | 1202 ++-- gfx/skia/skia/src/core/SkPathEffect.cpp | 46 +- gfx/skia/skia/src/core/SkPathHeap.cpp | 95 - gfx/skia/skia/src/core/SkPathHeap.h | 76 - gfx/skia/skia/src/core/SkPathMeasure.cpp | 142 +- gfx/skia/skia/src/core/SkPathPriv.h | 68 + gfx/skia/skia/src/core/SkPathRef.cpp | 258 +- gfx/skia/skia/src/core/SkPicture.cpp | 553 +- gfx/skia/skia/src/core/SkPictureCommon.h | 151 + .../skia/src/core/SkPictureContentInfo.cpp | 175 + gfx/skia/skia/src/core/SkPictureContentInfo.h | 89 + gfx/skia/skia/src/core/SkPictureData.cpp | 1070 +--- gfx/skia/skia/src/core/SkPictureData.h | 192 +- gfx/skia/skia/src/core/SkPictureFlat.cpp | 24 +- gfx/skia/skia/src/core/SkPictureFlat.h | 120 +- .../skia/src/core/SkPictureImageGenerator.cpp | 161 + gfx/skia/skia/src/core/SkPicturePlayback.cpp | 242 +- gfx/skia/skia/src/core/SkPicturePlayback.h | 34 +- .../skia/src/core/SkPictureRangePlayback.cpp | 57 - .../skia/src/core/SkPictureRangePlayback.h | 41 - gfx/skia/skia/src/core/SkPictureRecord.cpp | 1472 ++--- gfx/skia/skia/src/core/SkPictureRecord.h | 239 +- gfx/skia/skia/src/core/SkPictureRecorder.cpp | 211 +- .../src/core/SkPictureReplacementPlayback.cpp | 171 - .../src/core/SkPictureReplacementPlayback.h | 86 - gfx/skia/skia/src/core/SkPictureShader.cpp | 266 +- gfx/skia/skia/src/core/SkPictureShader.h | 40 +- gfx/skia/skia/src/core/SkPictureStateTree.cpp | 218 - gfx/skia/skia/src/core/SkPictureStateTree.h | 162 - gfx/skia/skia/src/core/SkPixelRef.cpp | 341 +- gfx/skia/skia/src/core/SkPixmap.cpp | 275 + gfx/skia/skia/src/core/SkPoint.cpp | 25 +- gfx/skia/skia/src/core/SkPoint3.cpp | 80 + .../skia/src/core/SkProcSpriteBlitter.cpp | 47 - gfx/skia/skia/src/core/SkPtrRecorder.cpp | 4 +- gfx/skia/skia/src/core/SkPtrRecorder.h | 31 +- gfx/skia/skia/src/core/SkPx.h | 89 + gfx/skia/skia/src/core/SkQuadTree.cpp | 219 - gfx/skia/skia/src/core/SkQuadTree.h | 113 - gfx/skia/skia/src/core/SkRRect.cpp | 191 +- gfx/skia/skia/src/core/SkRTree.cpp | 564 +- gfx/skia/skia/src/core/SkRTree.h | 175 +- gfx/skia/skia/src/core/SkRWBuffer.cpp | 349 ++ gfx/skia/skia/src/core/SkRWBuffer.h | 97 + gfx/skia/skia/src/core/SkRasterClip.cpp | 186 +- gfx/skia/skia/src/core/SkRasterClip.h | 39 +- gfx/skia/skia/src/core/SkRasterizer.cpp | 7 +- gfx/skia/skia/src/core/SkReadBuffer.cpp | 117 +- .../skia/{include => src}/core/SkReadBuffer.h | 21 +- .../skia/{include => src}/core/SkReader32.h | 18 +- gfx/skia/skia/src/core/SkRecord.cpp | 42 + gfx/skia/skia/src/core/SkRecord.h | 170 +- gfx/skia/skia/src/core/SkRecordAnalysis.cpp | 66 - gfx/skia/skia/src/core/SkRecordAnalysis.h | 8 - gfx/skia/skia/src/core/SkRecordDraw.cpp | 806 ++- gfx/skia/skia/src/core/SkRecordDraw.h | 70 +- gfx/skia/skia/src/core/SkRecordOpts.cpp | 369 +- gfx/skia/skia/src/core/SkRecordOpts.h | 15 +- gfx/skia/skia/src/core/SkRecordPattern.h | 126 +- gfx/skia/skia/src/core/SkRecorder.cpp | 363 +- gfx/skia/skia/src/core/SkRecorder.h | 156 +- gfx/skia/skia/src/core/SkRecording.cpp | 44 - gfx/skia/skia/src/core/SkRecords.cpp | 32 + gfx/skia/skia/src/core/SkRecords.h | 291 - gfx/skia/skia/src/core/SkRect.cpp | 172 +- gfx/skia/skia/src/core/SkRefDict.cpp | 14 +- gfx/skia/skia/src/core/SkRefDict.h | 8 +- gfx/skia/skia/src/core/SkRegion.cpp | 26 +- gfx/skia/skia/src/core/SkRegionPriv.h | 9 +- gfx/skia/skia/src/core/SkRegion_path.cpp | 82 +- gfx/skia/skia/src/core/SkRemote.cpp | 758 +++ gfx/skia/skia/src/core/SkRemote.h | 116 + gfx/skia/skia/src/core/SkRemote_protocol.h | 36 + gfx/skia/skia/src/core/SkResourceCache.cpp | 709 +++ gfx/skia/skia/src/core/SkResourceCache.h | 286 + gfx/skia/skia/src/core/SkScalar.cpp | 6 +- gfx/skia/skia/src/core/SkScaledImageCache.cpp | 796 --- gfx/skia/skia/src/core/SkScaledImageCache.h | 214 - gfx/skia/skia/src/core/SkScalerContext.cpp | 415 +- gfx/skia/skia/src/core/SkScalerContext.h | 105 +- gfx/skia/skia/src/core/SkScan.h | 21 +- gfx/skia/skia/src/core/SkScan_AntiPath.cpp | 106 +- gfx/skia/skia/src/core/SkScan_Antihair.cpp | 319 +- gfx/skia/skia/src/core/SkScan_Hairline.cpp | 372 +- gfx/skia/skia/src/core/SkScan_Path.cpp | 140 +- gfx/skia/skia/src/core/SkSemaphore.cpp | 99 + gfx/skia/skia/src/core/SkShader.cpp | 116 +- gfx/skia/skia/src/core/SkSharedMutex.cpp | 350 ++ gfx/skia/skia/src/core/SkSharedMutex.h | 82 + gfx/skia/skia/src/core/SkSinTable.h | 277 - gfx/skia/skia/src/core/SkSmallAllocator.h | 76 +- gfx/skia/skia/src/core/SkSpinlock.cpp | 13 + gfx/skia/skia/src/core/SkSpriteBlitter.h | 30 +- .../skia/src/core/SkSpriteBlitterTemplate.h | 24 +- .../skia/src/core/SkSpriteBlitter_ARGB32.cpp | 101 +- .../skia/src/core/SkSpriteBlitter_RGB16.cpp | 116 +- gfx/skia/skia/src/core/SkStream.cpp | 264 +- gfx/skia/skia/src/core/SkStreamPriv.h | 8 +- gfx/skia/skia/src/core/SkString.cpp | 102 +- gfx/skia/skia/src/core/SkStringUtils.cpp | 44 + gfx/skia/skia/src/core/SkStringUtils.h | 18 + gfx/skia/skia/src/core/SkStroke.cpp | 1273 ++++- gfx/skia/skia/src/core/SkStroke.h | 22 + gfx/skia/skia/src/core/SkStrokeRec.cpp | 43 +- gfx/skia/skia/src/core/SkStrokerPriv.cpp | 35 +- gfx/skia/skia/src/core/SkSurfacePriv.h | 25 + gfx/skia/skia/src/core/SkTDPQueue.h | 195 + gfx/skia/skia/src/core/SkTDynamicHash.h | 22 +- gfx/skia/skia/src/core/SkTInternalSList.h | 132 - gfx/skia/skia/src/core/SkTLList.h | 206 +- gfx/skia/skia/src/core/SkTLS.cpp | 33 +- gfx/skia/skia/src/core/SkTLS.h | 19 +- gfx/skia/skia/src/core/SkTMultiMap.h | 45 +- gfx/skia/skia/src/core/SkTObjectPool.h | 109 - gfx/skia/skia/src/core/SkTRefArray.h | 112 - gfx/skia/skia/src/core/SkTSearch.cpp | 2 +- gfx/skia/skia/src/core/SkTTopoSort.h | 112 + gfx/skia/skia/src/core/SkTaskGroup.cpp | 228 + gfx/skia/skia/src/core/SkTaskGroup.h | 98 + gfx/skia/skia/src/core/SkTextBlob.cpp | 649 +++ .../skia/src/core/SkTextBlobRunIterator.h | 40 + gfx/skia/skia/src/core/SkTextFormatParams.h | 10 +- gfx/skia/skia/src/core/SkTextMapStateProc.h | 26 +- gfx/skia/skia/src/core/SkThreadID.cpp | 16 + gfx/skia/skia/src/core/SkThreadPriv.h | 23 - gfx/skia/skia/src/core/SkTileGrid.cpp | 132 - gfx/skia/skia/src/core/SkTileGrid.h | 142 - gfx/skia/skia/src/core/SkTime.cpp | 69 + gfx/skia/skia/src/core/SkTraceEvent.h | 739 +-- gfx/skia/skia/src/core/SkTraceEventCommon.h | 1038 ++++ gfx/skia/skia/src/core/SkTypeface.cpp | 285 +- gfx/skia/skia/src/core/SkTypefaceCache.cpp | 72 +- gfx/skia/skia/src/core/SkTypefaceCache.h | 24 +- gfx/skia/skia/src/core/SkUtils.cpp | 158 +- gfx/skia/skia/src/core/SkUtilsArm.cpp | 85 +- gfx/skia/skia/src/core/SkUtilsArm.h | 4 +- .../skia/src/core/SkValidatingReadBuffer.cpp | 21 +- .../skia/src/core/SkValidatingReadBuffer.h | 56 +- gfx/skia/skia/src/core/SkVarAlloc.cpp | 70 + gfx/skia/skia/src/core/SkVarAlloc.h | 55 + gfx/skia/skia/src/core/SkVertState.cpp | 2 +- gfx/skia/skia/src/core/SkVertState.h | 2 +- gfx/skia/skia/src/core/SkWriteBuffer.cpp | 114 +- gfx/skia/skia/src/core/SkWriter32.cpp | 30 +- gfx/skia/skia/src/core/SkXfermode.cpp | 1128 +--- .../src/core/SkXfermodeInterpretation.cpp | 51 + .../skia/src/core/SkXfermodeInterpretation.h | 30 + gfx/skia/skia/src/core/SkXfermode_proccoeff.h | 59 +- gfx/skia/skia/src/core/SkYUVPlanesCache.cpp | 89 + gfx/skia/skia/src/core/SkYUVPlanesCache.h | 50 + gfx/skia/skia/src/device/xps/SkXPSDevice.cpp | 655 +-- gfx/skia/skia/src/doc/SkDocument.cpp | 16 +- gfx/skia/skia/src/doc/SkDocument_PDF.cpp | 430 +- gfx/skia/skia/src/doc/SkDocument_PDF_None.cpp | 9 + gfx/skia/skia/src/doc/SkDocument_XPS.cpp | 82 + gfx/skia/skia/src/doc/SkDocument_XPS_None.cpp | 15 + .../effects/GrCircleBlurFragmentProcessor.cpp | 261 + .../effects/GrCircleBlurFragmentProcessor.h | 87 + gfx/skia/skia/src/effects/Sk1DPathEffect.cpp | 40 +- gfx/skia/skia/src/effects/Sk2DPathEffect.cpp | 50 +- .../src/effects/SkAlphaThresholdFilter.cpp | 312 +- .../skia/src/effects/SkArcToPathEffect.cpp | 78 + .../skia/src/effects/SkArithmeticMode.cpp | 255 +- .../skia/src/effects/SkArithmeticMode_gpu.cpp | 321 ++ .../skia/src/effects/SkArithmeticMode_gpu.h | 122 + gfx/skia/skia/src/effects/SkAvoidXfermode.cpp | 180 - gfx/skia/skia/src/effects/SkBitmapSource.cpp | 93 - .../skia/src/effects/SkBlurDrawLooper.cpp | 25 +- .../skia/src/effects/SkBlurImageFilter.cpp | 247 +- gfx/skia/skia/src/effects/SkBlurMask.cpp | 20 +- gfx/skia/skia/src/effects/SkBlurMask.h | 13 +- .../skia/src/effects/SkBlurMaskFilter.cpp | 919 +-- .../skia/src/effects/SkColorCubeFilter.cpp | 336 ++ .../src/effects/SkColorFilterImageFilter.cpp | 121 +- gfx/skia/skia/src/effects/SkColorFilters.cpp | 519 +- gfx/skia/skia/src/effects/SkColorMatrix.cpp | 97 +- .../skia/src/effects/SkColorMatrixFilter.cpp | 406 +- .../skia/src/effects/SkComposeImageFilter.cpp | 63 +- .../skia/src/effects/SkCornerPathEffect.cpp | 38 +- .../skia/src/effects/SkDashPathEffect.cpp | 184 +- .../skia/src/effects/SkDiscretePathEffect.cpp | 70 +- .../src/effects/SkDisplacementMapEffect.cpp | 352 +- .../src/effects/SkDropShadowImageFilter.cpp | 79 +- .../skia/src/effects/SkEmbossMaskFilter.cpp | 26 +- gfx/skia/skia/src/effects/SkGpuBlurUtils.cpp | 398 +- gfx/skia/skia/src/effects/SkGpuBlurUtils.h | 15 +- gfx/skia/skia/src/effects/SkImageSource.cpp | 118 + .../skia/src/effects/SkLayerDrawLooper.cpp | 66 +- .../skia/src/effects/SkLayerRasterizer.cpp | 61 +- gfx/skia/skia/src/effects/SkLerpXfermode.cpp | 12 +- .../src/effects/SkLightingImageFilter.cpp | 1591 ++++-- .../skia/src/effects/SkLumaColorFilter.cpp | 104 +- .../src/effects/SkMagnifierImageFilter.cpp | 335 +- .../SkMatrixConvolutionImageFilter.cpp | 188 +- .../skia/src/effects/SkMergeImageFilter.cpp | 130 +- .../src/effects/SkMorphologyImageFilter.cpp | 595 +- .../skia/src/effects/SkOffsetImageFilter.cpp | 29 +- .../skia/src/effects/SkPerlinNoiseShader.cpp | 486 +- .../skia/src/effects/SkPictureImageFilter.cpp | 149 +- .../skia/src/effects/SkPixelXorXfermode.cpp | 6 +- gfx/skia/skia/src/effects/SkPorterDuff.cpp | 87 - .../src/effects/SkRectShaderImageFilter.cpp | 39 +- .../skia/src/effects/SkStippleMaskFilter.cpp | 52 - .../skia/src/effects/SkTableColorFilter.cpp | 455 +- .../skia/src/effects/SkTableMaskFilter.cpp | 15 +- .../skia/src/effects/SkTestImageFilters.cpp | 31 +- .../skia/src/effects/SkTileImageFilter.cpp | 49 +- .../skia/src/effects/SkTransparentShader.cpp | 126 - .../src/effects/SkXfermodeImageFilter.cpp | 108 +- .../src/effects/gradients/SkClampRange.cpp | 102 +- .../skia/src/effects/gradients/SkClampRange.h | 26 +- ...mapCache.cpp => SkGradientBitmapCache.cpp} | 36 +- ...kBitmapCache.h => SkGradientBitmapCache.h} | 14 +- .../effects/gradients/SkGradientShader.cpp | 715 +-- .../effects/gradients/SkGradientShaderPriv.h | 127 +- .../effects/gradients/SkLinearGradient.cpp | 588 +- .../src/effects/gradients/SkLinearGradient.h | 51 +- .../effects/gradients/SkRadialGradient.cpp | 337 +- .../src/effects/gradients/SkRadialGradient.h | 29 +- .../src/effects/gradients/SkSweepGradient.cpp | 174 +- .../src/effects/gradients/SkSweepGradient.h | 29 +- .../gradients/SkTwoPointConicalGradient.cpp | 141 +- .../gradients/SkTwoPointConicalGradient.h | 29 +- .../SkTwoPointConicalGradient_gpu.cpp | 847 +-- .../gradients/SkTwoPointConicalGradient_gpu.h | 6 +- .../gradients/SkTwoPointRadialGradient.cpp | 714 --- .../gradients/SkTwoPointRadialGradient.h | 64 - .../skia/src/fonts/SkFontMgr_fontconfig.cpp | 94 +- .../skia/src/fonts/SkFontMgr_indirect.cpp | 166 +- gfx/skia/skia/src/fonts/SkGScalerContext.cpp | 30 +- gfx/skia/skia/src/fonts/SkGScalerContext.h | 33 +- .../skia/src/fonts/SkRandomScalerContext.cpp | 256 + .../skia/src/fonts/SkRandomScalerContext.h | 55 + .../skia/src/fonts/SkRemotableFontMgr.cpp | 11 +- .../skia/src/fonts/SkTestScalerContext.cpp | 283 +- gfx/skia/skia/src/fonts/SkTestScalerContext.h | 98 +- .../skia/src/gpu/GrAAConvexPathRenderer.cpp | 716 --- .../skia/src/gpu/GrAAConvexPathRenderer.h | 30 - .../skia/src/gpu/GrAAHairLinePathRenderer.cpp | 1042 ---- .../skia/src/gpu/GrAAHairLinePathRenderer.h | 65 - gfx/skia/skia/src/gpu/GrAARectRenderer.cpp | 929 ---- gfx/skia/skia/src/gpu/GrAARectRenderer.h | 118 - .../src/gpu/GrAddPathRenderers_default.cpp | 34 - gfx/skia/skia/src/gpu/GrAllocPool.cpp | 116 - gfx/skia/skia/src/gpu/GrAllocPool.h | 60 - gfx/skia/skia/src/gpu/GrAllocator.h | 63 +- gfx/skia/skia/src/gpu/GrAtlas.cpp | 293 - gfx/skia/skia/src/gpu/GrAtlas.h | 133 - gfx/skia/skia/src/gpu/GrAtlasTextBlob.cpp | 109 + gfx/skia/skia/src/gpu/GrAtlasTextBlob.h | 250 + gfx/skia/skia/src/gpu/GrAtlasTextContext.cpp | 1398 +++++ gfx/skia/skia/src/gpu/GrAtlasTextContext.h | 193 + gfx/skia/skia/src/gpu/GrAutoLocaleSetter.h | 66 + gfx/skia/skia/src/gpu/GrBatchAtlas.cpp | 264 + gfx/skia/skia/src/gpu/GrBatchAtlas.h | 265 + gfx/skia/skia/src/gpu/GrBatchFlushState.cpp | 30 + gfx/skia/skia/src/gpu/GrBatchFlushState.h | 194 + gfx/skia/skia/src/gpu/GrBatchFontCache.cpp | 236 + gfx/skia/skia/src/gpu/GrBatchFontCache.h | 228 + gfx/skia/skia/src/gpu/GrBatchTest.cpp | 57 + gfx/skia/skia/src/gpu/GrBatchTest.h | 39 + gfx/skia/skia/src/gpu/GrBinHashKey.h | 160 - gfx/skia/skia/src/gpu/GrBitmapTextContext.cpp | 594 -- gfx/skia/skia/src/gpu/GrBitmapTextContext.h | 55 - gfx/skia/skia/src/gpu/GrBlend.cpp | 242 +- gfx/skia/skia/src/gpu/GrBlend.h | 45 - gfx/skia/skia/src/gpu/GrBlurUtils.cpp | 347 ++ gfx/skia/skia/src/gpu/GrBlurUtils.h | 59 + gfx/skia/skia/src/gpu/GrBufferAllocPool.cpp | 337 +- gfx/skia/skia/src/gpu/GrBufferAllocPool.h | 155 +- gfx/skia/skia/src/gpu/GrCacheID.cpp | 34 - gfx/skia/skia/src/gpu/GrCaps.cpp | 251 + gfx/skia/skia/src/gpu/GrClip.cpp | 53 + gfx/skia/skia/src/gpu/GrClipData.cpp | 34 - gfx/skia/skia/src/gpu/GrClipMaskCache.cpp | 21 - gfx/skia/skia/src/gpu/GrClipMaskCache.h | 235 - gfx/skia/skia/src/gpu/GrClipMaskManager.cpp | 1169 ++-- gfx/skia/skia/src/gpu/GrClipMaskManager.h | 169 +- gfx/skia/skia/src/gpu/GrContext.cpp | 2146 ++----- gfx/skia/skia/src/gpu/GrContextFactory.cpp | 123 + gfx/skia/skia/src/gpu/GrContextFactory.h | 147 + gfx/skia/skia/src/gpu/GrCoordTransform.cpp | 64 + .../skia/src/gpu/GrDefaultGeoProcFactory.cpp | 343 ++ .../skia/src/gpu/GrDefaultGeoProcFactory.h | 138 + .../skia/src/gpu/GrDefaultPathRenderer.cpp | 537 -- gfx/skia/skia/src/gpu/GrDefaultPathRenderer.h | 62 - .../src/gpu/GrDistanceFieldTextContext.cpp | 599 -- .../skia/src/gpu/GrDistanceFieldTextContext.h | 55 - gfx/skia/skia/src/gpu/GrDrawContext.cpp | 806 +++ gfx/skia/skia/src/gpu/GrDrawState.cpp | 506 -- gfx/skia/skia/src/gpu/GrDrawState.h | 1018 ---- gfx/skia/skia/src/gpu/GrDrawTarget.cpp | 1579 ++---- gfx/skia/skia/src/gpu/GrDrawTarget.h | 1134 +--- gfx/skia/skia/src/gpu/GrDrawTargetCaps.h | 107 - gfx/skia/skia/src/gpu/GrDrawingManager.cpp | 197 + gfx/skia/skia/src/gpu/GrDrawingManager.h | 92 + gfx/skia/skia/src/gpu/GrEffect.cpp | 96 - gfx/skia/skia/src/gpu/GrFontScaler.cpp | 164 +- gfx/skia/skia/src/gpu/GrFontScaler.h | 69 + gfx/skia/skia/src/gpu/GrFragmentProcessor.cpp | 378 ++ gfx/skia/skia/src/gpu/GrGeometryBuffer.h | 25 +- gfx/skia/skia/src/gpu/GrGeometryProcessor.h | 86 + gfx/skia/skia/{include => src}/gpu/GrGlyph.h | 43 +- gfx/skia/skia/src/gpu/GrGpu.cpp | 744 +-- gfx/skia/skia/src/gpu/GrGpu.h | 702 ++- gfx/skia/skia/src/gpu/GrGpuFactory.cpp | 50 +- gfx/skia/skia/src/gpu/GrGpuFactory.h | 24 + gfx/skia/skia/src/gpu/GrGpuResource.cpp | 190 +- .../skia/src/gpu/GrGpuResourceCacheAccess.h | 102 + gfx/skia/skia/src/gpu/GrGpuResourcePriv.h | 86 + gfx/skia/skia/src/gpu/GrGpuResourceRef.cpp | 117 + .../skia/src/gpu/GrImageIDTextureAdjuster.cpp | 98 + .../skia/src/gpu/GrImageIDTextureAdjuster.h | 69 + gfx/skia/skia/src/gpu/GrInOrderDrawBuffer.cpp | 1001 ---- gfx/skia/skia/src/gpu/GrInOrderDrawBuffer.h | 295 - gfx/skia/skia/src/gpu/GrIndexBuffer.h | 22 +- gfx/skia/skia/src/gpu/GrInvariantOutput.cpp | 32 + gfx/skia/skia/src/gpu/GrLayerAtlas.cpp | 170 + gfx/skia/skia/src/gpu/GrLayerAtlas.h | 158 + gfx/skia/skia/src/gpu/GrLayerCache.cpp | 481 +- gfx/skia/skia/src/gpu/GrLayerCache.h | 385 +- gfx/skia/skia/src/gpu/GrLayerHoister.cpp | 401 ++ gfx/skia/skia/src/gpu/GrLayerHoister.h | 124 + gfx/skia/skia/src/gpu/GrMemoryPool.cpp | 29 +- gfx/skia/skia/src/gpu/GrMemoryPool.h | 8 + gfx/skia/skia/src/gpu/GrNonAtomicRef.h | 49 + gfx/skia/skia/src/gpu/GrOrderedSet.h | 154 - gfx/skia/skia/src/gpu/GrOvalRenderer.cpp | 2263 +++++--- gfx/skia/skia/src/gpu/GrOvalRenderer.h | 78 +- gfx/skia/skia/src/gpu/GrPaint.cpp | 132 +- gfx/skia/skia/src/gpu/GrPath.cpp | 238 +- gfx/skia/skia/src/gpu/GrPath.h | 36 +- gfx/skia/skia/src/gpu/GrPathProcessor.cpp | 142 + gfx/skia/skia/src/gpu/GrPathProcessor.h | 57 + gfx/skia/skia/src/gpu/GrPathRange.cpp | 55 + gfx/skia/skia/src/gpu/GrPathRange.h | 145 +- gfx/skia/skia/src/gpu/GrPathRenderer.h | 285 +- gfx/skia/skia/src/gpu/GrPathRendererChain.cpp | 65 +- .../gpu/GrPathRendererChain.h | 38 +- gfx/skia/skia/src/gpu/GrPathRendering.cpp | 82 + gfx/skia/skia/src/gpu/GrPathRendering.h | 203 + gfx/skia/skia/src/gpu/GrPathUtils.cpp | 165 +- gfx/skia/skia/src/gpu/GrPathUtils.h | 23 +- .../skia/src/gpu/GrPendingProgramElement.h | 56 + gfx/skia/skia/src/gpu/GrPictureUtils.cpp | 275 - gfx/skia/skia/src/gpu/GrPictureUtils.h | 79 - gfx/skia/skia/src/gpu/GrPipeline.cpp | 235 + gfx/skia/skia/src/gpu/GrPipeline.h | 201 + gfx/skia/skia/src/gpu/GrPipelineBuilder.cpp | 97 + gfx/skia/skia/src/gpu/GrPipelineBuilder.h | 388 ++ gfx/skia/skia/src/gpu/GrPlotMgr.h | 73 - .../skia/src/gpu/GrPrimitiveProcessor.cpp | 68 + gfx/skia/skia/src/gpu/GrPrimitiveProcessor.h | 229 + gfx/skia/skia/src/gpu/GrProcOptInfo.cpp | 70 + gfx/skia/skia/src/gpu/GrProcOptInfo.h | 93 + gfx/skia/skia/src/gpu/GrProcessor.cpp | 133 + gfx/skia/skia/src/gpu/GrProcessorUnitTest.cpp | 23 + gfx/skia/skia/src/gpu/GrProgramDesc.h | 144 + gfx/skia/skia/src/gpu/GrProgramElement.cpp | 37 + gfx/skia/skia/src/gpu/GrQuad.h | 65 + gfx/skia/skia/src/gpu/GrRecordReplaceDraw.cpp | 230 + gfx/skia/skia/src/gpu/GrRecordReplaceDraw.h | 26 + gfx/skia/skia/src/gpu/GrRectanizer_pow2.cpp | 2 +- gfx/skia/skia/src/gpu/GrRectanizer_pow2.h | 6 +- .../skia/src/gpu/GrRectanizer_skyline.cpp | 2 +- gfx/skia/skia/src/gpu/GrRectanizer_skyline.h | 8 +- gfx/skia/skia/src/gpu/GrRedBlackTree.h | 948 ---- gfx/skia/skia/src/gpu/GrReducedClip.cpp | 338 +- gfx/skia/skia/src/gpu/GrReducedClip.h | 61 +- gfx/skia/skia/src/gpu/GrRenderTarget.cpp | 109 +- gfx/skia/skia/src/gpu/GrRenderTargetPriv.h | 50 + gfx/skia/skia/src/gpu/GrResourceCache.cpp | 1139 ++-- gfx/skia/skia/src/gpu/GrResourceCache.h | 673 +-- gfx/skia/skia/src/gpu/GrResourceProvider.cpp | 219 + gfx/skia/skia/src/gpu/GrResourceProvider.h | 162 + gfx/skia/skia/src/gpu/GrSWMaskHelper.cpp | 285 +- gfx/skia/skia/src/gpu/GrSWMaskHelper.h | 60 +- .../skia/src/gpu/GrSoftwarePathRenderer.cpp | 85 +- .../skia/src/gpu/GrSoftwarePathRenderer.h | 21 +- .../src/gpu/GrStencilAndCoverPathRenderer.cpp | 103 - .../src/gpu/GrStencilAndCoverPathRenderer.h | 55 - .../src/gpu/GrStencilAndCoverTextContext.cpp | 856 +-- .../src/gpu/GrStencilAndCoverTextContext.h | 147 +- gfx/skia/skia/src/gpu/GrStencilAttachment.cpp | 19 + ...rStencilBuffer.h => GrStencilAttachment.h} | 25 +- gfx/skia/skia/src/gpu/GrStencilBuffer.cpp | 47 - gfx/skia/skia/src/gpu/GrStrokeInfo.cpp | 94 + gfx/skia/skia/src/gpu/GrStrokeInfo.h | 172 +- gfx/skia/skia/src/gpu/GrSurface.cpp | 188 +- gfx/skia/skia/src/gpu/GrSurfacePriv.h | 71 + gfx/skia/skia/src/gpu/GrTBSearch.h | 44 - gfx/skia/skia/src/gpu/GrTHashTable.h | 215 - gfx/skia/skia/src/gpu/GrTRecorder.h | 390 ++ gfx/skia/skia/src/gpu/GrTemplates.h | 68 - gfx/skia/skia/src/gpu/GrTest.cpp | 356 +- gfx/skia/skia/src/gpu/GrTest.h | 19 +- gfx/skia/skia/src/gpu/GrTestUtils.cpp | 262 + gfx/skia/skia/src/gpu/GrTextBlobCache.cpp | 58 + gfx/skia/skia/src/gpu/GrTextBlobCache.h | 158 + gfx/skia/skia/src/gpu/GrTextContext.cpp | 257 +- gfx/skia/skia/src/gpu/GrTextContext.h | 80 +- gfx/skia/skia/src/gpu/GrTextStrike.cpp | 336 -- gfx/skia/skia/src/gpu/GrTextStrike.h | 134 - gfx/skia/skia/src/gpu/GrTextStrike_impl.h | 64 - gfx/skia/skia/src/gpu/GrTexture.cpp | 210 +- gfx/skia/skia/src/gpu/GrTextureAccess.cpp | 16 +- .../skia/src/gpu/GrTextureParamsAdjuster.cpp | 484 ++ .../skia/src/gpu/GrTextureParamsAdjuster.h | 203 + gfx/skia/skia/src/gpu/GrTexturePriv.h | 75 + gfx/skia/skia/src/gpu/GrTextureProvider.cpp | 135 + gfx/skia/skia/src/gpu/GrTraceMarker.cpp | 2 +- gfx/skia/skia/src/gpu/GrTraceMarker.h | 1 - gfx/skia/skia/src/gpu/GrTracing.h | 60 +- gfx/skia/skia/src/gpu/GrVertexBuffer.h | 22 +- gfx/skia/skia/src/gpu/GrVertices.h | 179 + gfx/skia/skia/src/gpu/GrXferProcessor.cpp | 219 + gfx/skia/skia/src/gpu/GrYUVProvider.cpp | 143 + gfx/skia/skia/src/gpu/GrYUVProvider.h | 69 + gfx/skia/skia/src/gpu/SkGpuDevice.cpp | 2389 ++++---- gfx/skia/skia/src/gpu/SkGpuDevice.h | 259 + .../skia/src/gpu/SkGpuDevice_drawTexture.cpp | 240 + gfx/skia/skia/src/gpu/SkGr.cpp | 877 +-- gfx/skia/skia/src/gpu/SkGrPixelRef.cpp | 199 +- gfx/skia/skia/src/gpu/SkGrPriv.h | 138 + .../gpu/batches/GrAAConvexPathRenderer.cpp | 1031 ++++ .../src/gpu/batches/GrAAConvexPathRenderer.h | 24 + .../src/gpu/batches/GrAAConvexTessellator.cpp | 1027 ++++ .../src/gpu/batches/GrAAConvexTessellator.h | 270 + .../batches/GrAADistanceFieldPathRenderer.cpp | 642 +++ .../batches/GrAADistanceFieldPathRenderer.h | 92 + .../src/gpu/batches/GrAAFillRectBatch.cpp | 421 ++ .../skia/src/gpu/batches/GrAAFillRectBatch.h | 54 + .../gpu/batches/GrAAHairLinePathRenderer.cpp | 1002 ++++ .../gpu/batches/GrAAHairLinePathRenderer.h | 31 + .../GrAALinearizingConvexPathRenderer.cpp | 357 ++ .../GrAALinearizingConvexPathRenderer.h | 24 + .../src/gpu/batches/GrAAStrokeRectBatch.cpp | 665 +++ .../src/gpu/batches/GrAAStrokeRectBatch.h | 43 + .../skia/src/gpu/batches/GrAtlasTextBatch.cpp | 575 ++ .../skia/src/gpu/batches/GrAtlasTextBatch.h | 229 + gfx/skia/skia/src/gpu/batches/GrBatch.cpp | 58 + gfx/skia/skia/src/gpu/batches/GrBatch.h | 161 + gfx/skia/skia/src/gpu/batches/GrClearBatch.h | 99 + .../src/gpu/batches/GrCopySurfaceBatch.cpp | 79 + .../skia/src/gpu/batches/GrCopySurfaceBatch.h | 67 + .../gpu/batches/GrDashLinePathRenderer.cpp | 26 + .../src/gpu/batches/GrDashLinePathRenderer.h | 29 + .../src/gpu/batches/GrDefaultPathRenderer.cpp | 773 +++ .../src/gpu/batches/GrDefaultPathRenderer.h | 46 + .../skia/src/gpu/batches/GrDiscardBatch.h | 52 + .../skia/src/gpu/batches/GrDrawAtlasBatch.cpp | 267 + .../skia/src/gpu/batches/GrDrawAtlasBatch.h | 75 + gfx/skia/skia/src/gpu/batches/GrDrawBatch.cpp | 35 + gfx/skia/skia/src/gpu/batches/GrDrawBatch.h | 106 + .../skia/src/gpu/batches/GrDrawPathBatch.cpp | 143 + .../skia/src/gpu/batches/GrDrawPathBatch.h | 184 + .../src/gpu/batches/GrDrawVerticesBatch.cpp | 327 ++ .../src/gpu/batches/GrDrawVerticesBatch.h | 82 + gfx/skia/skia/src/gpu/batches/GrNinePatch.cpp | 184 + gfx/skia/skia/src/gpu/batches/GrNinePatch.h | 24 + .../src/gpu/batches/GrNonAAFillRectBatch.cpp | 338 ++ .../src/gpu/batches/GrNonAAFillRectBatch.h | 39 + .../gpu/batches/GrNonAAStrokeRectBatch.cpp | 254 + .../src/gpu/batches/GrNonAAStrokeRectBatch.h | 35 + .../src/gpu/batches/GrRectBatchFactory.cpp | 30 + .../skia/src/gpu/batches/GrRectBatchFactory.h | 77 + .../batches/GrStencilAndCoverPathRenderer.cpp | 158 + .../batches/GrStencilAndCoverPathRenderer.h | 45 + .../skia/src/gpu/batches/GrStencilPathBatch.h | 78 + .../skia/src/gpu/batches/GrTInstanceBatch.h | 154 + .../batches/GrTessellatingPathRenderer.cpp | 1671 ++++++ .../gpu/batches/GrTessellatingPathRenderer.h | 33 + gfx/skia/skia/src/gpu/batches/GrTestBatch.h | 90 + .../skia/src/gpu/batches/GrVertexBatch.cpp | 86 + gfx/skia/skia/src/gpu/batches/GrVertexBatch.h | 86 + .../skia/src/gpu/effects/Gr1DKernelEffect.h | 9 +- .../skia/src/gpu/effects/GrBezierEffect.cpp | 797 ++- .../skia/src/gpu/effects/GrBezierEffect.h | 248 +- .../skia/src/gpu/effects/GrBicubicEffect.cpp | 176 +- .../skia/src/gpu/effects/GrBicubicEffect.h | 59 +- .../src/gpu/effects/GrBitmapTextGeoProc.cpp | 201 + .../src/gpu/effects/GrBitmapTextGeoProc.h | 66 + .../gpu/effects/GrConfigConversionEffect.cpp | 246 +- .../gpu/effects/GrConfigConversionEffect.h | 33 +- .../src/gpu/effects/GrConstColorProcessor.cpp | 135 + .../src/gpu/effects/GrConvexPolyEffect.cpp | 351 +- .../skia/src/gpu/effects/GrConvexPolyEffect.h | 55 +- .../src/gpu/effects/GrConvolutionEffect.cpp | 163 +- .../src/gpu/effects/GrConvolutionEffect.h | 67 +- .../src/gpu/effects/GrCoverageSetOpXP.cpp | 342 ++ .../effects/GrCustomCoordsTextureEffect.cpp | 107 - .../gpu/effects/GrCustomCoordsTextureEffect.h | 49 - .../skia/src/gpu/effects/GrCustomXfermode.cpp | 409 ++ .../skia/src/gpu/effects/GrDashingEffect.cpp | 1563 ++++-- .../skia/src/gpu/effects/GrDashingEffect.h | 28 +- .../skia/src/gpu/effects/GrDisableColorXP.cpp | 109 + .../skia/src/gpu/effects/GrDisableColorXP.h | 50 + .../gpu/effects/GrDistanceFieldGeoProc.cpp | 793 +++ .../src/gpu/effects/GrDistanceFieldGeoProc.h | 232 + .../effects/GrDistanceFieldTextureEffect.cpp | 503 -- .../effects/GrDistanceFieldTextureEffect.h | 121 - .../skia/src/gpu/effects/GrDitherEffect.cpp | 101 +- .../skia/src/gpu/effects/GrDitherEffect.h | 4 +- .../gpu/effects/GrMatrixConvolutionEffect.cpp | 357 +- .../gpu/effects/GrMatrixConvolutionEffect.h | 98 +- .../skia/src/gpu/effects/GrOvalEffect.cpp | 381 +- gfx/skia/skia/src/gpu/effects/GrOvalEffect.h | 4 +- .../gpu/effects/GrPorterDuffXferProcessor.cpp | 920 +++ .../skia/src/gpu/effects/GrRRectEffect.cpp | 564 +- gfx/skia/skia/src/gpu/effects/GrRRectEffect.h | 7 +- .../src/gpu/effects/GrSimpleTextureEffect.cpp | 78 +- .../src/gpu/effects/GrSimpleTextureEffect.h | 60 +- .../src/gpu/effects/GrSingleTextureEffect.cpp | 6 +- .../src/gpu/effects/GrSingleTextureEffect.h | 40 +- .../skia/src/gpu/effects/GrTextureDomain.cpp | 309 +- .../skia/src/gpu/effects/GrTextureDomain.h | 120 +- .../src/gpu/effects/GrTextureStripAtlas.cpp | 143 +- .../src/gpu/effects/GrTextureStripAtlas.h | 36 +- .../skia/src/gpu/effects/GrVertexEffect.h | 37 - .../effects/GrXfermodeFragmentProcessor.cpp | 312 ++ .../skia/src/gpu/effects/GrYUVtoRGBEffect.cpp | 193 +- .../skia/src/gpu/effects/GrYUVtoRGBEffect.h | 7 +- .../src/gpu/gl/GrGLAssembleGLESInterface.h | 286 - .../skia/src/gpu/gl/GrGLAssembleInterface.cpp | 578 +- .../skia/src/gpu/gl/GrGLAssembleInterface.h | 15 +- gfx/skia/skia/src/gpu/gl/GrGLBufferImpl.cpp | 178 +- gfx/skia/skia/src/gpu/gl/GrGLBufferImpl.h | 17 +- gfx/skia/skia/src/gpu/gl/GrGLCaps.cpp | 967 +++- gfx/skia/skia/src/gpu/gl/GrGLCaps.h | 176 +- gfx/skia/skia/src/gpu/gl/GrGLContext.cpp | 122 +- gfx/skia/skia/src/gpu/gl/GrGLContext.h | 77 +- .../gpu/gl/GrGLCreateNativeInterface_none.cpp | 2 +- .../src/gpu/gl/GrGLCreateNullInterface.cpp | 225 +- .../src/gpu/gl/GrGLDefaultInterface_none.cpp | 2 +- gfx/skia/skia/src/gpu/gl/GrGLDefines.h | 300 +- gfx/skia/skia/src/gpu/gl/GrGLEffect.h | 105 - gfx/skia/skia/src/gpu/gl/GrGLExtensions.cpp | 58 +- gfx/skia/skia/src/gpu/gl/GrGLGLSL.cpp | 50 + gfx/skia/skia/src/gpu/gl/GrGLGLSL.h | 25 + gfx/skia/skia/src/gpu/gl/GrGLGpu.cpp | 3406 ++++++++++++ gfx/skia/skia/src/gpu/gl/GrGLGpu.h | 537 ++ .../skia/src/gpu/gl/GrGLGpuProgramCache.cpp | 215 + gfx/skia/skia/src/gpu/gl/GrGLIndexBuffer.cpp | 18 +- gfx/skia/skia/src/gpu/gl/GrGLIndexBuffer.h | 27 +- gfx/skia/skia/src/gpu/gl/GrGLInterface.cpp | 671 ++- .../skia/src/gpu/gl/GrGLNameAllocator.cpp | 44 +- gfx/skia/skia/src/gpu/gl/GrGLNameAllocator.h | 2 +- .../skia/src/gpu/gl/GrGLNoOpInterface.cpp | 43 +- gfx/skia/skia/src/gpu/gl/GrGLNoOpInterface.h | 29 +- gfx/skia/skia/src/gpu/gl/GrGLPath.cpp | 277 +- gfx/skia/skia/src/gpu/gl/GrGLPath.h | 36 +- gfx/skia/skia/src/gpu/gl/GrGLPathRange.cpp | 108 +- gfx/skia/skia/src/gpu/gl/GrGLPathRange.h | 45 +- .../skia/src/gpu/gl/GrGLPathRendering.cpp | 298 + gfx/skia/skia/src/gpu/gl/GrGLPathRendering.h | 120 + gfx/skia/skia/src/gpu/gl/GrGLProgram.cpp | 323 +- gfx/skia/skia/src/gpu/gl/GrGLProgram.h | 172 +- .../src/gpu/gl/GrGLProgramDataManager.cpp | 301 + .../skia/src/gpu/gl/GrGLProgramDataManager.h | 112 + gfx/skia/skia/src/gpu/gl/GrGLProgramDesc.cpp | 394 +- gfx/skia/skia/src/gpu/gl/GrGLProgramDesc.h | 271 +- .../skia/src/gpu/gl/GrGLProgramEffects.cpp | 510 -- gfx/skia/skia/src/gpu/gl/GrGLProgramEffects.h | 335 -- gfx/skia/skia/src/gpu/gl/GrGLRenderTarget.cpp | 226 +- gfx/skia/skia/src/gpu/gl/GrGLRenderTarget.h | 109 +- gfx/skia/skia/src/gpu/gl/GrGLSL.cpp | 98 - .../skia/src/gpu/gl/GrGLShaderBuilder.cpp | 1106 ---- gfx/skia/skia/src/gpu/gl/GrGLShaderBuilder.h | 522 -- .../skia/src/gpu/gl/GrGLStencilAttachment.cpp | 44 + ...tencilBuffer.h => GrGLStencilAttachment.h} | 38 +- .../skia/src/gpu/gl/GrGLStencilBuffer.cpp | 39 - gfx/skia/skia/src/gpu/gl/GrGLTexture.cpp | 78 +- gfx/skia/skia/src/gpu/gl/GrGLTexture.h | 90 +- .../src/gpu/gl/GrGLTextureRenderTarget.cpp | 39 + .../skia/src/gpu/gl/GrGLTextureRenderTarget.h | 63 + gfx/skia/skia/src/gpu/gl/GrGLUniformHandle.h | 15 - .../skia/src/gpu/gl/GrGLUniformManager.cpp | 280 - gfx/skia/skia/src/gpu/gl/GrGLUniformManager.h | 120 - gfx/skia/skia/src/gpu/gl/GrGLUtil.cpp | 231 +- gfx/skia/skia/src/gpu/gl/GrGLUtil.h | 51 +- .../skia/src/gpu/gl/GrGLVaryingHandler.cpp | 31 + gfx/skia/skia/src/gpu/gl/GrGLVaryingHandler.h | 38 + gfx/skia/skia/src/gpu/gl/GrGLVertexArray.cpp | 55 +- gfx/skia/skia/src/gpu/gl/GrGLVertexArray.h | 39 +- gfx/skia/skia/src/gpu/gl/GrGLVertexBuffer.cpp | 18 +- gfx/skia/skia/src/gpu/gl/GrGLVertexBuffer.h | 27 +- gfx/skia/skia/src/gpu/gl/GrGLVertexEffect.h | 52 - gfx/skia/skia/src/gpu/gl/GrGpuGL.cpp | 3027 ---------- gfx/skia/skia/src/gpu/gl/GrGpuGL.h | 487 -- gfx/skia/skia/src/gpu/gl/GrGpuGL_program.cpp | 377 -- gfx/skia/skia/src/gpu/gl/SkGLContext.cpp | 154 + .../skia/src/gpu/gl/SkGLContextHelper.cpp | 136 - gfx/skia/skia/src/gpu/gl/SkNullGLContext.cpp | 554 +- .../GrGLCreateNativeInterface_android.cpp | 257 +- .../gl/android/SkNativeGLContext_android.cpp | 182 - .../gpu/gl/angle/GrGLCreateANGLEInterface.cpp | 205 +- .../src/gpu/gl/angle/SkANGLEGLContext.cpp | 237 +- .../gpu/gl/builders/GrGLProgramBuilder.cpp | 540 ++ .../src/gpu/gl/builders/GrGLProgramBuilder.h | 178 + .../src/gpu/gl/builders/GrGLSLPrettyPrint.cpp | 204 + .../gl/builders/GrGLShaderStringBuilder.cpp | 95 + .../gpu/gl/builders/GrGLShaderStringBuilder.h | 24 + .../SkCommandBufferGLContext.cpp | 311 ++ gfx/skia/skia/src/gpu/gl/debug/GrBufferObj.h | 4 +- gfx/skia/skia/src/gpu/gl/debug/GrDebugGL.cpp | 42 +- gfx/skia/skia/src/gpu/gl/debug/GrDebugGL.h | 15 +- gfx/skia/skia/src/gpu/gl/debug/GrFakeRefObj.h | 14 +- .../skia/src/gpu/gl/debug/GrFrameBufferObj.h | 20 +- .../gpu/gl/debug/GrGLCreateDebugInterface.cpp | 89 +- gfx/skia/skia/src/gpu/gl/debug/GrProgramObj.h | 2 +- .../skia/src/gpu/gl/debug/GrRenderBufferObj.h | 2 +- gfx/skia/skia/src/gpu/gl/debug/GrShaderObj.h | 2 +- gfx/skia/skia/src/gpu/gl/debug/GrTextureObj.h | 2 +- .../skia/src/gpu/gl/debug/GrTextureUnitObj.h | 2 +- .../src/gpu/gl/debug/SkDebugGLContext.cpp | 14 +- .../skia/src/gpu/gl/debug/SkDebugGLContext.h | 31 + .../gl/egl/GrGLCreateNativeInterface_egl.cpp | 30 + .../gl/egl/SkCreatePlatformGLContext_egl.cpp | 328 ++ .../gl/glx/GrGLCreateNativeInterface_glx.cpp | 27 + .../SkCreatePlatformGLContext_glx.cpp} | 292 +- .../gl/iOS/GrGLCreateNativeInterface_iOS.cpp | 206 +- .../gl/iOS/SkCreatePlatformGLContext_iOS.mm | 102 + .../src/gpu/gl/iOS/SkNativeGLContext_iOS.mm | 68 - .../gl/mac/GrGLCreateNativeInterface_mac.cpp | 10 +- .../gl/mac/SkCreatePlatformGLContext_mac.cpp | 124 + .../src/gpu/gl/mac/SkNativeGLContext_mac.cpp | 84 - .../gpu/gl/mesa/GrGLCreateMesaInterface.cpp | 10 +- .../skia/src/gpu/gl/mesa/SkMesaGLContext.cpp | 101 +- .../skia/src/gpu/gl/mesa/SkMesaGLContext.h | 48 + .../nacl/SkCreatePlatformGLContext_nacl.cpp} | 10 +- .../gpu/gl/nacl/SkNativeGLContext_nacl.cpp | 37 - .../unix/GrGLCreateNativeInterface_unix.cpp | 44 - .../gl/win/GrGLCreateNativeInterface_win.cpp | 41 +- ....cpp => SkCreatePlatformGLContext_win.cpp} | 149 +- gfx/skia/skia/src/gpu/glsl/GrGLSL.cpp | 56 + gfx/skia/skia/src/gpu/{gl => glsl}/GrGLSL.h | 55 +- gfx/skia/skia/src/gpu/glsl/GrGLSLBlend.cpp | 482 ++ gfx/skia/skia/src/gpu/glsl/GrGLSLBlend.h | 28 + gfx/skia/skia/src/gpu/glsl/GrGLSLCaps.cpp | 77 + gfx/skia/skia/src/gpu/glsl/GrGLSLCaps.h | 163 + .../src/gpu/glsl/GrGLSLFragmentProcessor.cpp | 108 + .../src/gpu/glsl/GrGLSLFragmentProcessor.h | 123 + .../gpu/glsl/GrGLSLFragmentShaderBuilder.cpp | 262 + .../gpu/glsl/GrGLSLFragmentShaderBuilder.h | 202 + .../src/gpu/glsl/GrGLSLGeometryProcessor.cpp | 160 + .../src/gpu/glsl/GrGLSLGeometryProcessor.h | 120 + .../gpu/glsl/GrGLSLGeometryShaderBuilder.cpp | 20 + .../gpu/glsl/GrGLSLGeometryShaderBuilder.h | 27 + .../src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp | 47 + .../src/gpu/glsl/GrGLSLPrimitiveProcessor.h | 109 + .../skia/src/gpu/glsl/GrGLSLProcessorTypes.h | 20 + .../src/gpu/glsl/GrGLSLProgramBuilder.cpp | 39 + .../skia/src/gpu/glsl/GrGLSLProgramBuilder.h | 176 + .../src/gpu/glsl/GrGLSLProgramDataManager.h | 80 + .../skia/src/gpu/glsl/GrGLSLShaderBuilder.cpp | 205 + .../skia/src/gpu/glsl/GrGLSLShaderBuilder.h | 197 + .../GrGLSLShaderVar.h} | 222 +- .../skia/src/gpu/glsl/GrGLSLTextureSampler.h | 39 + gfx/skia/skia/src/gpu/glsl/GrGLSLUtil.cpp | 52 + gfx/skia/skia/src/gpu/glsl/GrGLSLUtil.h | 19 + gfx/skia/skia/src/gpu/glsl/GrGLSLVarying.cpp | 132 + gfx/skia/skia/src/gpu/glsl/GrGLSLVarying.h | 136 + .../gpu/glsl/GrGLSLVertexShaderBuilder.cpp | 62 + .../src/gpu/glsl/GrGLSLVertexShaderBuilder.h | 31 + .../skia/src/gpu/glsl/GrGLSLXferProcessor.cpp | 89 + .../skia/src/gpu/glsl/GrGLSLXferProcessor.h | 101 + .../skia/src/gpu/{gl => glsl}/GrGLSL_impl.h | 0 gfx/skia/skia/src/image/SkImage.cpp | 432 +- gfx/skia/skia/src/image/SkImagePriv.cpp | 68 - gfx/skia/skia/src/image/SkImagePriv.h | 44 +- gfx/skia/skia/src/image/SkImageShader.cpp | 134 + gfx/skia/skia/src/image/SkImageShader.h | 43 + gfx/skia/skia/src/image/SkImage_Base.h | 66 +- gfx/skia/skia/src/image/SkImage_Codec.cpp | 75 - gfx/skia/skia/src/image/SkImage_Generator.cpp | 102 + gfx/skia/skia/src/image/SkImage_Gpu.cpp | 435 +- gfx/skia/skia/src/image/SkImage_Gpu.h | 63 + gfx/skia/skia/src/image/SkImage_Raster.cpp | 284 +- gfx/skia/skia/src/image/SkReadPixelsRec.h | 41 + gfx/skia/skia/src/image/SkSurface.cpp | 149 +- gfx/skia/skia/src/image/SkSurface_Base.h | 44 +- gfx/skia/skia/src/image/SkSurface_Gpu.cpp | 233 +- gfx/skia/skia/src/image/SkSurface_Gpu.h | 40 + gfx/skia/skia/src/image/SkSurface_Raster.cpp | 106 +- .../src/images/SkDecodingImageGenerator.cpp | 154 +- gfx/skia/skia/src/images/SkForceLinking.cpp | 9 +- gfx/skia/skia/src/images/SkImageDecoder.cpp | 177 +- .../images/SkImageDecoder_FactoryDefault.cpp | 4 +- .../SkImageDecoder_FactoryRegistrar.cpp | 10 +- .../skia/src/images/SkImageDecoder_astc.cpp | 203 + .../skia/src/images/SkImageDecoder_ktx.cpp | 124 +- .../skia/src/images/SkImageDecoder_libbmp.cpp | 26 +- .../skia/src/images/SkImageDecoder_libgif.cpp | 85 +- .../skia/src/images/SkImageDecoder_libico.cpp | 204 +- .../src/images/SkImageDecoder_libjpeg.cpp | 689 +-- .../skia/src/images/SkImageDecoder_libpng.cpp | 460 +- .../src/images/SkImageDecoder_libwebp.cpp | 195 +- .../skia/src/images/SkImageDecoder_pkm.cpp | 37 +- .../skia/src/images/SkImageDecoder_wbmp.cpp | 26 +- gfx/skia/skia/src/images/SkImageEncoder.cpp | 14 +- .../src/images/SkImageEncoder_Factory.cpp | 6 +- .../skia/src/images/SkImageEncoder_argb.cpp | 11 +- gfx/skia/skia/src/images/SkJpegUtility.cpp | 18 +- gfx/skia/skia/src/images/SkJpegUtility.h | 3 +- gfx/skia/skia/src/images/SkMovie.cpp | 4 +- gfx/skia/skia/src/images/SkMovie_gif.cpp | 49 +- .../skia/src/images/SkScaledBitmapSampler.cpp | 95 +- .../skia/src/images/SkScaledBitmapSampler.h | 4 +- gfx/skia/skia/src/images/bmpdecoderhelper.cpp | 2 +- gfx/skia/skia/src/images/bmpdecoderhelper.h | 2 +- gfx/skia/skia/src/lazy/SkCachingPixelRef.cpp | 97 - gfx/skia/skia/src/lazy/SkCachingPixelRef.h | 63 - .../skia/src/lazy/SkDiscardableMemoryPool.cpp | 90 +- .../skia/src/lazy/SkDiscardableMemoryPool.h | 3 +- .../skia/src/lazy/SkDiscardablePixelRef.cpp | 99 +- .../skia/src/lazy/SkDiscardablePixelRef.h | 34 +- gfx/skia/skia/src/opts/Sk4px_NEON.h | 170 + gfx/skia/skia/src/opts/Sk4px_SSE2.h | 179 + gfx/skia/skia/src/opts/Sk4px_none.h | 140 + .../src/opts/SkBitmapFilter_opts_SSE2.cpp | 144 +- .../skia/src/opts/SkBitmapFilter_opts_SSE2.h | 9 +- .../src/opts/SkBitmapProcState_arm_neon.cpp | 23 +- .../src/opts/SkBitmapProcState_filter_neon.h | 2 - .../src/opts/SkBitmapProcState_matrix_neon.h | 31 +- .../src/opts/SkBitmapProcState_opts_SSE2.cpp | 48 +- .../src/opts/SkBitmapProcState_opts_SSE2.h | 2 - .../src/opts/SkBitmapProcState_opts_SSSE3.cpp | 71 +- .../src/opts/SkBitmapProcState_opts_SSSE3.h | 7 + .../src/opts/SkBitmapProcState_opts_arm.cpp | 207 +- .../opts/SkBitmapProcState_opts_mips_dsp.cpp | 36 +- .../src/opts/SkBitmapProcState_opts_none.cpp | 1 - gfx/skia/skia/src/opts/SkBlitMask_opts.h | 206 + .../skia/src/opts/SkBlitMask_opts_arm.cpp | 28 +- .../src/opts/SkBlitMask_opts_arm_neon.cpp | 203 +- .../skia/src/opts/SkBlitMask_opts_arm_neon.h | 9 +- .../skia/src/opts/SkBlitMask_opts_none.cpp | 10 +- .../skia/src/opts/SkBlitRect_opts_SSE2.cpp | 132 - gfx/skia/skia/src/opts/SkBlitRect_opts_SSE2.h | 21 - gfx/skia/skia/src/opts/SkBlitRow_opts.h | 35 + .../skia/src/opts/SkBlitRow_opts_SSE2.cpp | 460 +- gfx/skia/skia/src/opts/SkBlitRow_opts_SSE2.h | 7 +- .../skia/src/opts/SkBlitRow_opts_SSE4.cpp | 71 + gfx/skia/skia/src/opts/SkBlitRow_opts_SSE4.h | 19 +- .../skia/src/opts/SkBlitRow_opts_SSE4_asm.S | 473 -- .../src/opts/SkBlitRow_opts_SSE4_x64_asm.S | 470 -- gfx/skia/skia/src/opts/SkBlitRow_opts_arm.cpp | 381 +- .../skia/src/opts/SkBlitRow_opts_arm_neon.cpp | 425 +- .../skia/src/opts/SkBlitRow_opts_arm_neon.h | 6 +- .../skia/src/opts/SkBlitRow_opts_mips_dsp.cpp | 51 +- .../skia/src/opts/SkBlitRow_opts_none.cpp | 18 +- .../skia/src/opts/SkBlurImageFilter_opts.h | 318 ++ gfx/skia/skia/src/opts/SkBlurImage_opts.h | 20 - .../skia/src/opts/SkBlurImage_opts_SSE2.cpp | 108 - .../skia/src/opts/SkBlurImage_opts_SSE2.h | 18 - .../skia/src/opts/SkBlurImage_opts_SSE4.cpp | 123 - .../skia/src/opts/SkBlurImage_opts_SSE4.h | 18 - .../skia/src/opts/SkBlurImage_opts_arm.cpp | 25 - .../skia/src/opts/SkBlurImage_opts_neon.cpp | 188 - .../skia/src/opts/SkBlurImage_opts_neon.h | 13 - .../skia/src/opts/SkBlurImage_opts_none.cpp | 15 - .../skia/src/opts/SkColorCubeFilter_opts.h | 84 + gfx/skia/skia/src/opts/SkColor_opts_SSE2.h | 66 +- gfx/skia/skia/src/opts/SkColor_opts_neon.h | 7 + gfx/skia/skia/src/opts/SkFloatingPoint_opts.h | 35 + gfx/skia/skia/src/opts/SkMath_opts_SSE2.h | 51 - gfx/skia/skia/src/opts/SkMatrix_opts.h | 106 + .../src/opts/SkMorphologyImageFilter_opts.h | 137 + gfx/skia/skia/src/opts/SkMorphology_opts.h | 22 - .../skia/src/opts/SkMorphology_opts_SSE2.cpp | 81 - .../skia/src/opts/SkMorphology_opts_SSE2.h | 22 - .../skia/src/opts/SkMorphology_opts_arm.cpp | 34 - .../skia/src/opts/SkMorphology_opts_neon.cpp | 80 - .../skia/src/opts/SkMorphology_opts_neon.h | 15 - .../skia/src/opts/SkMorphology_opts_none.cpp | 12 - gfx/skia/skia/src/opts/SkNx_avx.h | 90 + gfx/skia/skia/src/opts/SkNx_neon.h | 337 ++ gfx/skia/skia/src/opts/SkNx_sse.h | 304 + gfx/skia/skia/src/opts/SkOpts_avx.cpp | 17 + gfx/skia/skia/src/opts/SkOpts_neon.cpp | 51 + gfx/skia/skia/src/opts/SkOpts_sse41.cpp | 19 + gfx/skia/skia/src/opts/SkOpts_ssse3.cpp | 20 + gfx/skia/skia/src/opts/SkPx_neon.h | 188 + gfx/skia/skia/src/opts/SkPx_none.h | 111 + gfx/skia/skia/src/opts/SkPx_sse.h | 155 + .../skia/src/opts/SkTextureCompression_opts.h | 17 - .../opts/SkTextureCompression_opts_arm.cpp | 38 - .../opts/SkTextureCompression_opts_neon.cpp | 239 - .../src/opts/SkTextureCompression_opts_neon.h | 14 - .../opts/SkTextureCompression_opts_none.cpp | 13 - .../skia/src/opts/SkTextureCompressor_opts.h | 267 + gfx/skia/skia/src/opts/SkUtils_opts.h | 110 + gfx/skia/skia/src/opts/SkUtils_opts_SSE2.cpp | 99 - gfx/skia/skia/src/opts/SkUtils_opts_SSE2.h | 17 - gfx/skia/skia/src/opts/SkUtils_opts_arm.cpp | 57 - gfx/skia/skia/src/opts/SkUtils_opts_none.cpp | 22 - gfx/skia/skia/src/opts/SkXfermode_opts.h | 339 ++ .../skia/src/opts/SkXfermode_opts_SSE2.cpp | 819 --- gfx/skia/skia/src/opts/SkXfermode_opts_SSE2.h | 38 - .../skia/src/opts/SkXfermode_opts_arm.cpp | 26 - .../src/opts/SkXfermode_opts_arm_neon.cpp | 1028 ---- .../skia/src/opts/SkXfermode_opts_arm_neon.h | 35 - .../skia/src/opts/SkXfermode_opts_none.cpp | 17 - gfx/skia/skia/src/opts/memset.arm.S | 111 - gfx/skia/skia/src/opts/memset16_neon.S | 143 - gfx/skia/skia/src/opts/memset32_neon.S | 113 - gfx/skia/skia/src/opts/opts_check_x86.cpp | 253 +- .../skia/src/pathops/SkAddIntersections.cpp | 357 +- .../skia/src/pathops/SkAddIntersections.h | 8 +- .../src/pathops/SkDConicLineIntersection.cpp | 363 ++ .../skia/src/pathops/SkDCubicIntersection.cpp | 698 --- .../src/pathops/SkDCubicLineIntersection.cpp | 106 +- gfx/skia/skia/src/pathops/SkDCubicToQuads.cpp | 158 +- .../skia/src/pathops/SkDLineIntersection.cpp | 106 +- gfx/skia/skia/src/pathops/SkDQuadImplicit.cpp | 117 - gfx/skia/skia/src/pathops/SkDQuadImplicit.h | 39 - .../skia/src/pathops/SkDQuadIntersection.cpp | 555 -- .../src/pathops/SkDQuadLineIntersection.cpp | 123 +- .../skia/src/pathops/SkIntersectionHelper.h | 94 +- gfx/skia/skia/src/pathops/SkIntersections.cpp | 153 +- gfx/skia/skia/src/pathops/SkIntersections.h | 143 +- gfx/skia/skia/src/pathops/SkOpAngle.cpp | 825 ++- gfx/skia/skia/src/pathops/SkOpAngle.h | 195 +- gfx/skia/skia/src/pathops/SkOpBuilder.cpp | 173 + gfx/skia/skia/src/pathops/SkOpCoincidence.cpp | 676 +++ gfx/skia/skia/src/pathops/SkOpCoincidence.h | 126 + gfx/skia/skia/src/pathops/SkOpContour.cpp | 778 +-- gfx/skia/skia/src/pathops/SkOpContour.h | 595 +- gfx/skia/skia/src/pathops/SkOpCubicHull.cpp | 150 + gfx/skia/skia/src/pathops/SkOpEdgeBuilder.cpp | 142 +- gfx/skia/skia/src/pathops/SkOpEdgeBuilder.h | 47 +- gfx/skia/skia/src/pathops/SkOpSegment.cpp | 4949 ++++------------- gfx/skia/skia/src/pathops/SkOpSegment.h | 754 ++- gfx/skia/skia/src/pathops/SkOpSpan.cpp | 385 ++ gfx/skia/skia/src/pathops/SkOpSpan.h | 520 +- gfx/skia/skia/src/pathops/SkOpTAllocator.h | 33 + gfx/skia/skia/src/pathops/SkPathOpsBounds.cpp | 40 - gfx/skia/skia/src/pathops/SkPathOpsBounds.h | 29 +- gfx/skia/skia/src/pathops/SkPathOpsCommon.cpp | 774 +-- gfx/skia/skia/src/pathops/SkPathOpsCommon.h | 29 +- gfx/skia/skia/src/pathops/SkPathOpsConic.cpp | 166 + gfx/skia/skia/src/pathops/SkPathOpsConic.h | 123 + gfx/skia/skia/src/pathops/SkPathOpsCubic.cpp | 407 +- gfx/skia/skia/src/pathops/SkPathOpsCubic.h | 102 +- gfx/skia/skia/src/pathops/SkPathOpsCurve.cpp | 39 + gfx/skia/skia/src/pathops/SkPathOpsCurve.h | 267 +- gfx/skia/skia/src/pathops/SkPathOpsDebug.cpp | 2108 +++++-- gfx/skia/skia/src/pathops/SkPathOpsDebug.h | 223 +- gfx/skia/skia/src/pathops/SkPathOpsLine.cpp | 50 +- gfx/skia/skia/src/pathops/SkPathOpsLine.h | 17 +- gfx/skia/skia/src/pathops/SkPathOpsOp.cpp | 488 +- gfx/skia/skia/src/pathops/SkPathOpsPoint.cpp | 5 - gfx/skia/skia/src/pathops/SkPathOpsPoint.h | 80 +- gfx/skia/skia/src/pathops/SkPathOpsQuad.cpp | 180 +- gfx/skia/skia/src/pathops/SkPathOpsQuad.h | 51 +- gfx/skia/skia/src/pathops/SkPathOpsRect.cpp | 73 +- gfx/skia/skia/src/pathops/SkPathOpsRect.h | 48 +- .../skia/src/pathops/SkPathOpsSimplify.cpp | 227 +- gfx/skia/skia/src/pathops/SkPathOpsTSect.cpp | 50 + gfx/skia/skia/src/pathops/SkPathOpsTSect.h | 2237 ++++++++ .../skia/src/pathops/SkPathOpsTightBounds.cpp | 22 +- .../skia/src/pathops/SkPathOpsTriangle.cpp | 51 - gfx/skia/skia/src/pathops/SkPathOpsTriangle.h | 20 - gfx/skia/skia/src/pathops/SkPathOpsTypes.cpp | 27 +- gfx/skia/skia/src/pathops/SkPathOpsTypes.h | 161 +- .../skia/src/pathops/SkPathOpsWinding.cpp | 407 ++ gfx/skia/skia/src/pathops/SkPathWriter.cpp | 18 + gfx/skia/skia/src/pathops/SkPathWriter.h | 1 + gfx/skia/skia/src/pathops/SkQuarticRoot.cpp | 168 - gfx/skia/skia/src/pathops/SkQuarticRoot.h | 16 - gfx/skia/skia/src/pathops/SkReduceOrder.cpp | 39 +- gfx/skia/skia/src/pathops/SkReduceOrder.h | 3 +- gfx/skia/skia/src/pdf/SkDeflate.cpp | 119 + gfx/skia/skia/src/pdf/SkDeflate.h | 45 + gfx/skia/skia/src/pdf/SkJpegInfo.cpp | 121 + gfx/skia/skia/src/pdf/SkJpegInfo.h | 31 + gfx/skia/skia/src/pdf/SkPDFBitmap.cpp | 490 ++ gfx/skia/skia/src/pdf/SkPDFBitmap.h | 21 + gfx/skia/skia/src/pdf/SkPDFCanon.cpp | 151 + gfx/skia/skia/src/pdf/SkPDFCanon.h | 117 + gfx/skia/skia/src/pdf/SkPDFCatalog.cpp | 215 - gfx/skia/skia/src/pdf/SkPDFCatalog.h | 137 - gfx/skia/skia/src/pdf/SkPDFDevice.cpp | 1390 ++--- gfx/skia/skia/src/pdf/SkPDFDevice.h | 319 ++ .../skia/src/pdf/SkPDFDeviceFlattener.cpp | 154 - gfx/skia/skia/src/pdf/SkPDFDeviceFlattener.h | 53 - gfx/skia/skia/src/pdf/SkPDFDocument.cpp | 351 -- gfx/skia/skia/src/pdf/SkPDFFont.cpp | 536 +- gfx/skia/skia/src/pdf/SkPDFFont.h | 65 +- gfx/skia/skia/src/pdf/SkPDFFontImpl.h | 34 +- gfx/skia/skia/src/pdf/SkPDFFormXObject.cpp | 45 +- gfx/skia/skia/src/pdf/SkPDFFormXObject.h | 13 +- gfx/skia/skia/src/pdf/SkPDFGraphicState.cpp | 374 +- gfx/skia/skia/src/pdf/SkPDFGraphicState.h | 85 +- gfx/skia/skia/src/pdf/SkPDFImage.cpp | 631 --- gfx/skia/skia/src/pdf/SkPDFImage.h | 98 - gfx/skia/skia/src/pdf/SkPDFMetadata.cpp | 350 ++ gfx/skia/skia/src/pdf/SkPDFMetadata.h | 33 + gfx/skia/skia/src/pdf/SkPDFPage.cpp | 158 - gfx/skia/skia/src/pdf/SkPDFPage.h | 109 - gfx/skia/skia/src/pdf/SkPDFResourceDict.cpp | 121 +- gfx/skia/skia/src/pdf/SkPDFResourceDict.h | 63 +- gfx/skia/skia/src/pdf/SkPDFShader.cpp | 607 +- gfx/skia/skia/src/pdf/SkPDFShader.h | 94 +- gfx/skia/skia/src/pdf/SkPDFStream.cpp | 139 +- gfx/skia/skia/src/pdf/SkPDFStream.h | 73 +- gfx/skia/skia/src/pdf/SkPDFTypes.cpp | 911 +-- gfx/skia/skia/src/pdf/SkPDFTypes.h | 598 +- gfx/skia/skia/src/pdf/SkPDFUtils.cpp | 189 +- gfx/skia/skia/src/pdf/SkPDFUtils.h | 8 +- gfx/skia/skia/src/pdf/SkTSet.h | 356 -- gfx/skia/skia/src/pipe/SkGPipePriv.h | 46 +- gfx/skia/skia/src/pipe/SkGPipeRead.cpp | 267 +- gfx/skia/skia/src/pipe/SkGPipeWrite.cpp | 626 ++- .../src/pipe/utils/SamplePipeControllers.cpp | 13 +- .../src/pipe/utils/SamplePipeControllers.h | 20 +- gfx/skia/skia/src/ports/SkAtomics_sync.h | 55 - gfx/skia/skia/src/ports/SkAtomics_win.h | 54 - gfx/skia/skia/src/ports/SkBarriers_arm.h | 36 - gfx/skia/skia/src/ports/SkBarriers_tsan.h | 31 - gfx/skia/skia/src/ports/SkBarriers_x86.h | 39 - gfx/skia/skia/src/ports/SkDebug_android.cpp | 26 +- gfx/skia/skia/src/ports/SkDebug_nacl.cpp | 38 - gfx/skia/skia/src/ports/SkDebug_stdio.cpp | 4 +- gfx/skia/skia/src/ports/SkDebug_win.cpp | 8 +- .../src/ports/SkDiscardableMemory_none.cpp | 1 + .../ports/SkFontConfigInterface_android.cpp | 743 --- .../ports/SkFontConfigInterface_direct.cpp | 235 +- .../src/ports/SkFontConfigInterface_direct.h | 43 + .../SkFontConfigInterface_direct_factory.cpp | 20 + .../SkFontConfigInterface_direct_google3.cpp | 34 + .../SkFontConfigInterface_direct_google3.h | 26 + ...ConfigInterface_direct_google3_factory.cpp | 20 + .../src/ports/SkFontConfigParser_android.cpp | 349 -- .../src/ports/SkFontConfigParser_android.h | 62 - .../skia/src/ports/SkFontConfigTypeface.h | 40 +- .../skia/src/ports/SkFontHost_FreeType.cpp | 962 ++-- .../src/ports/SkFontHost_FreeType_common.cpp | 32 +- .../src/ports/SkFontHost_FreeType_common.h | 59 +- .../skia/src/ports/SkFontHost_android_old.cpp | 585 -- gfx/skia/skia/src/ports/SkFontHost_cairo.cpp | 92 +- .../skia/src/ports/SkFontHost_fontconfig.cpp | 179 +- gfx/skia/skia/src/ports/SkFontHost_linux.cpp | 407 -- gfx/skia/skia/src/ports/SkFontHost_mac.cpp | 1186 ++-- gfx/skia/skia/src/ports/SkFontHost_win.cpp | 501 +- gfx/skia/skia/src/ports/SkFontMgr_android.cpp | 495 +- .../src/ports/SkFontMgr_android_factory.cpp | 47 + .../src/ports/SkFontMgr_android_parser.cpp | 799 +++ .../skia/src/ports/SkFontMgr_android_parser.h | 218 + gfx/skia/skia/src/ports/SkFontMgr_custom.cpp | 508 ++ .../SkFontMgr_custom_directory_factory.cpp | 17 + .../SkFontMgr_custom_embedded_factory.cpp | 17 + .../skia/src/ports/SkFontMgr_default_dw.cpp | 6 - .../skia/src/ports/SkFontMgr_default_gdi.cpp | 6 - ...t_none.cpp => SkFontMgr_empty_factory.cpp} | 6 +- .../skia/src/ports/SkFontMgr_fontconfig.cpp | 882 +++ .../ports/SkFontMgr_fontconfig_factory.cpp | 14 + gfx/skia/skia/src/ports/SkFontMgr_win_dw.cpp | 457 +- .../src/ports/SkFontMgr_win_dw_factory.cpp | 18 + .../src/ports/SkFontMgr_win_gdi_factory.cpp | 18 + .../ports/SkGlobalInitialization_chromium.cpp | 140 +- .../ports/SkGlobalInitialization_default.cpp | 128 +- gfx/skia/skia/src/ports/SkImageDecoder_CG.cpp | 108 +- .../skia/src/ports/SkImageDecoder_WIC.cpp | 42 +- .../skia/src/ports/SkImageDecoder_empty.cpp | 55 +- .../skia/src/ports/SkImageGenerator_none.cpp | 12 + .../skia/src/ports/SkImageGenerator_skia.cpp | 105 + gfx/skia/skia/src/ports/SkMemory_malloc.cpp | 8 +- gfx/skia/skia/src/ports/SkMutex_pthread.h | 101 - gfx/skia/skia/src/ports/SkMutex_win.h | 79 - gfx/skia/skia/src/ports/SkOSFile_none.cpp | 30 - gfx/skia/skia/src/ports/SkOSFile_posix.cpp | 115 +- gfx/skia/skia/src/ports/SkOSFile_stdio.cpp | 109 +- gfx/skia/skia/src/ports/SkOSFile_win.cpp | 151 +- gfx/skia/skia/src/ports/SkOSLibrary.h | 16 + gfx/skia/skia/src/ports/SkOSLibrary_posix.cpp | 22 + gfx/skia/skia/src/ports/SkOSLibrary_win.cpp | 22 + .../src/ports/SkRemotableFontMgr_win_dw.cpp | 130 +- .../skia/src/ports/SkScalerContext_win_dw.cpp | 329 +- .../skia/src/ports/SkScalerContext_win_dw.h | 25 +- gfx/skia/skia/src/ports/SkTLS_none.cpp | 2 +- gfx/skia/skia/src/ports/SkTLS_pthread.cpp | 2 +- gfx/skia/skia/src/ports/SkTLS_win.cpp | 12 +- gfx/skia/skia/src/ports/SkTime_Unix.cpp | 15 +- gfx/skia/skia/src/ports/SkTime_win.cpp | 34 +- gfx/skia/skia/src/ports/SkTypeface_win_dw.cpp | 176 +- gfx/skia/skia/src/ports/SkTypeface_win_dw.h | 67 +- gfx/skia/skia/src/ports/SkXMLParser_empty.cpp | 23 - gfx/skia/skia/src/sfnt/SkIBMFamilyClass.h | 2 +- gfx/skia/skia/src/sfnt/SkOTTableTypes.h | 5 +- gfx/skia/skia/src/sfnt/SkOTTable_OS_2.h | 12 +- gfx/skia/skia/src/sfnt/SkOTTable_OS_2_V0.h | 2 +- gfx/skia/skia/src/sfnt/SkOTTable_OS_2_V1.h | 2 +- gfx/skia/skia/src/sfnt/SkOTTable_OS_2_V2.h | 2 +- gfx/skia/skia/src/sfnt/SkOTTable_OS_2_V3.h | 2 +- gfx/skia/skia/src/sfnt/SkOTTable_OS_2_V4.h | 2 +- gfx/skia/skia/src/sfnt/SkOTTable_OS_2_VA.h | 2 +- gfx/skia/skia/src/sfnt/SkOTTable_gasp.h | 4 +- gfx/skia/skia/src/sfnt/SkOTTable_head.h | 4 +- gfx/skia/skia/src/sfnt/SkOTTable_hhea.h | 4 +- gfx/skia/skia/src/sfnt/SkOTTable_maxp_CFF.h | 4 +- gfx/skia/skia/src/sfnt/SkOTTable_maxp_TT.h | 4 +- gfx/skia/skia/src/sfnt/SkOTTable_name.cpp | 2 +- gfx/skia/skia/src/sfnt/SkOTTable_name.h | 10 +- gfx/skia/skia/src/sfnt/SkOTTable_post.h | 4 +- gfx/skia/skia/src/sfnt/SkOTUtils.cpp | 28 +- gfx/skia/skia/src/sfnt/SkOTUtils.h | 12 +- gfx/skia/skia/src/sfnt/SkPanose.h | 2 +- gfx/skia/skia/src/sfnt/SkSFNTHeader.h | 4 +- gfx/skia/skia/src/sfnt/SkTTCFHeader.h | 2 +- gfx/skia/skia/src/svg/SkSVGCanvas.cpp | 17 + gfx/skia/skia/src/svg/SkSVGDevice.cpp | 818 +++ gfx/skia/skia/src/svg/SkSVGDevice.h | 76 + gfx/skia/skia/src/svg/{ => parser}/SkSVG.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGCircle.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGCircle.h | 0 .../src/svg/{ => parser}/SkSVGClipPath.cpp | 2 +- .../skia/src/svg/{ => parser}/SkSVGClipPath.h | 0 .../skia/src/svg/{ => parser}/SkSVGDefs.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGDefs.h | 0 .../src/svg/{ => parser}/SkSVGElements.cpp | 4 +- .../skia/src/svg/{ => parser}/SkSVGElements.h | 0 .../src/svg/{ => parser}/SkSVGEllipse.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGEllipse.h | 0 .../svg/{ => parser}/SkSVGFeColorMatrix.cpp | 0 .../src/svg/{ => parser}/SkSVGFeColorMatrix.h | 0 .../skia/src/svg/{ => parser}/SkSVGFilter.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGFilter.h | 0 gfx/skia/skia/src/svg/{ => parser}/SkSVGG.cpp | 0 gfx/skia/skia/src/svg/{ => parser}/SkSVGG.h | 0 .../src/svg/{ => parser}/SkSVGGradient.cpp | 2 +- .../skia/src/svg/{ => parser}/SkSVGGradient.h | 0 .../skia/src/svg/{ => parser}/SkSVGGroup.cpp | 4 +- .../skia/src/svg/{ => parser}/SkSVGGroup.h | 0 .../skia/src/svg/{ => parser}/SkSVGImage.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGImage.h | 0 .../skia/src/svg/{ => parser}/SkSVGLine.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGLine.h | 0 .../svg/{ => parser}/SkSVGLinearGradient.cpp | 0 .../svg/{ => parser}/SkSVGLinearGradient.h | 0 .../skia/src/svg/{ => parser}/SkSVGMask.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGMask.h | 0 .../src/svg/{ => parser}/SkSVGMetadata.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGMetadata.h | 0 .../src/svg/{ => parser}/SkSVGPaintState.cpp | 10 +- .../skia/src/svg/{ => parser}/SkSVGParser.cpp | 20 +- .../skia/src/svg/{ => parser}/SkSVGPath.cpp | 2 +- .../skia/src/svg/{ => parser}/SkSVGPath.h | 0 .../src/svg/{ => parser}/SkSVGPolygon.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGPolygon.h | 0 .../src/svg/{ => parser}/SkSVGPolyline.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGPolyline.h | 0 .../svg/{ => parser}/SkSVGRadialGradient.cpp | 0 .../svg/{ => parser}/SkSVGRadialGradient.h | 0 .../skia/src/svg/{ => parser}/SkSVGRect.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGRect.h | 0 .../skia/src/svg/{ => parser}/SkSVGSVG.cpp | 7 +- gfx/skia/skia/src/svg/{ => parser}/SkSVGSVG.h | 0 .../skia/src/svg/{ => parser}/SkSVGStop.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGStop.h | 0 .../skia/src/svg/{ => parser}/SkSVGSymbol.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGSymbol.h | 0 .../skia/src/svg/{ => parser}/SkSVGText.cpp | 0 .../skia/src/svg/{ => parser}/SkSVGText.h | 0 .../skia/src/svg/{ => parser}/SkSVGUse.cpp | 0 gfx/skia/skia/src/svg/{ => parser}/SkSVGUse.h | 0 gfx/skia/skia/src/utils/SkBase64.cpp | 4 +- gfx/skia/skia/src/utils/SkBase64.h | 2 +- gfx/skia/skia/src/utils/SkBitSet.cpp | 29 +- gfx/skia/skia/src/utils/SkBitSet.h | 15 +- .../src/utils/SkBitmapSourceDeserializer.cpp | 34 + .../src/utils/SkBitmapSourceDeserializer.h | 21 + gfx/skia/skia/src/utils/SkBoundaryPatch.cpp | 4 +- gfx/skia/skia/src/utils/SkCamera.cpp | 10 +- gfx/skia/skia/src/utils/SkCanvasStack.h | 16 +- .../skia/src/utils/SkCanvasStateUtils.cpp | 46 +- gfx/skia/skia/src/utils/SkCondVar.cpp | 68 - gfx/skia/skia/src/utils/SkCullPoints.cpp | 4 +- gfx/skia/skia/src/utils/SkDashPath.cpp | 14 +- gfx/skia/skia/src/utils/SkDashPathPriv.h | 4 +- gfx/skia/skia/src/utils/SkDeferredCanvas.cpp | 926 --- gfx/skia/skia/src/utils/SkDumpCanvas.cpp | 173 +- gfx/skia/skia/src/utils/SkEventTracer.cpp | 53 +- .../skia/src/utils/SkFrontBufferedStream.cpp | 63 +- .../src/utils/SkGatherPixelRefsAndRects.cpp | 25 - .../src/utils/SkGatherPixelRefsAndRects.h | 326 -- .../skia/src/utils/SkImageGeneratorUtils.cpp | 134 + .../skia/src/utils/SkImageGeneratorUtils.h | 29 + gfx/skia/skia/src/utils/SkInterpolator.cpp | 23 +- gfx/skia/skia/src/utils/SkLayer.cpp | 16 +- gfx/skia/skia/src/utils/SkLua.cpp | 730 ++- gfx/skia/skia/src/utils/SkLuaCanvas.cpp | 69 +- gfx/skia/skia/src/utils/SkMD5.h | 10 +- gfx/skia/skia/src/utils/SkMatrix44.cpp | 132 +- gfx/skia/skia/src/utils/SkMeshUtils.cpp | 10 +- gfx/skia/skia/src/utils/SkNWayCanvas.cpp | 116 +- gfx/skia/skia/src/utils/SkNinePatch.cpp | 14 +- gfx/skia/skia/src/utils/SkNullCanvas.cpp | 2 +- gfx/skia/skia/src/utils/SkOSFile.cpp | 222 +- gfx/skia/skia/src/utils/SkPDFRasterizer.cpp | 86 - gfx/skia/skia/src/utils/SkPDFRasterizer.h | 21 - .../skia/src/utils/SkPaintFilterCanvas.cpp | 170 + gfx/skia/skia/src/utils/SkParse.cpp | 20 +- gfx/skia/skia/src/utils/SkParseColor.cpp | 22 +- gfx/skia/skia/src/utils/SkParsePath.cpp | 16 +- gfx/skia/skia/src/utils/SkPatchGrid.cpp | 189 + gfx/skia/skia/src/utils/SkPatchGrid.h | 144 + gfx/skia/skia/src/utils/SkPatchUtils.cpp | 331 ++ gfx/skia/skia/src/utils/SkPatchUtils.h | 121 + gfx/skia/skia/src/utils/SkPathUtils.cpp | 152 - gfx/skia/skia/src/utils/SkPictureUtils.cpp | 220 - gfx/skia/skia/src/utils/SkProxyCanvas.cpp | 170 - gfx/skia/skia/src/utils/SkRTConf.cpp | 53 +- .../SkInstCnt.cpp => utils/SkRunnable.h} | 10 +- gfx/skia/skia/src/utils/SkSHA1.h | 4 +- gfx/skia/skia/src/utils/SkTFitsIn.h | 60 +- gfx/skia/skia/src/utils/SkTLogic.h | 110 - .../skia/src/{views => utils}/SkTextBox.cpp | 74 +- .../skia/src/utils/SkTextureCompressor.cpp | 217 +- gfx/skia/skia/src/utils/SkTextureCompressor.h | 81 +- .../src/utils/SkTextureCompressor_ASTC.cpp | 1852 +++++- .../skia/src/utils/SkTextureCompressor_ASTC.h | 11 +- .../src/utils/SkTextureCompressor_Blitter.h | 733 +++ .../src/utils/SkTextureCompressor_LATC.cpp | 309 +- .../skia/src/utils/SkTextureCompressor_LATC.h | 11 +- .../src/utils/SkTextureCompressor_R11EAC.cpp | 568 +- .../src/utils/SkTextureCompressor_R11EAC.h | 11 +- .../src/utils/SkTextureCompressor_Utils.h | 68 + gfx/skia/skia/src/utils/SkThreadUtils.h | 9 +- .../skia/src/utils/SkThreadUtils_pthread.cpp | 10 +- .../src/utils/SkThreadUtils_pthread_linux.cpp | 46 - .../src/utils/SkThreadUtils_pthread_mach.cpp | 30 - gfx/skia/skia/src/utils/SkThreadUtils_win.cpp | 59 +- .../skia/src/utils/SkWhitelistChecksums.cpp | 50 + .../skia/src/utils/SkWhitelistTypefaces.cpp | 268 + .../src/utils/android/SkAndroidSDKCanvas.cpp | 374 ++ .../src/utils/android/SkAndroidSDKCanvas.h | 112 + .../skia/src/utils/debugger/SkDebugCanvas.cpp | 455 +- .../skia/src/utils/debugger/SkDebugCanvas.h | 194 +- .../skia/src/utils/debugger/SkDrawCommand.cpp | 620 ++- .../skia/src/utils/debugger/SkDrawCommand.h | 391 +- .../src/utils/debugger/SkObjectParser.cpp | 56 +- .../skia/src/utils/debugger/SkObjectParser.h | 12 +- gfx/skia/skia/src/utils/ios/SkFontHost_iOS.mm | 262 - .../skia/src/utils/ios/SkImageDecoder_iOS.mm | 65 - gfx/skia/skia/src/utils/ios/SkOSFile_iOS.mm | 98 - .../skia/src/utils/ios/SkStream_NSData.mm | 44 - .../skia/src/utils/mac/SkCreateCGImageRef.cpp | 47 +- gfx/skia/skia/src/utils/mac/SkStream_mac.cpp | 24 +- .../skia/src/utils/win/SkAutoCoInitialize.cpp | 7 +- gfx/skia/skia/src/utils/win/SkDWrite.cpp | 42 +- gfx/skia/skia/src/utils/win/SkDWrite.h | 37 +- .../src/utils/win/SkDWriteFontFileStream.cpp | 45 +- .../src/utils/win/SkDWriteFontFileStream.h | 28 +- .../src/utils/win/SkDWriteGeometrySink.cpp | 7 +- .../skia/src/utils/win/SkDWriteGeometrySink.h | 20 +- gfx/skia/skia/src/utils/win/SkHRESULT.cpp | 15 +- gfx/skia/skia/src/utils/win/SkIStream.cpp | 29 +- .../{include/utils => src/utils/win}/SkWGL.h | 0 gfx/skia/skia/src/utils/win/SkWGL_win.cpp | 82 +- gfx/skia/skia/src/views/SkEvent.cpp | 44 +- gfx/skia/skia/src/views/SkEventSink.cpp | 28 +- gfx/skia/skia/src/views/SkOSMenu.cpp | 18 +- gfx/skia/skia/src/views/SkParsePaint.cpp | 16 +- gfx/skia/skia/src/views/SkProgressView.cpp | 22 +- gfx/skia/skia/src/views/SkStackViewLayout.cpp | 8 +- gfx/skia/skia/src/views/SkTagList.cpp | 6 +- gfx/skia/skia/src/views/SkTagList.h | 2 +- gfx/skia/skia/src/views/SkTouchGesture.cpp | 8 +- gfx/skia/skia/src/views/SkView.cpp | 126 +- gfx/skia/skia/src/views/SkViewInflate.cpp | 18 +- gfx/skia/skia/src/views/SkViewPriv.cpp | 12 +- gfx/skia/skia/src/views/SkWidgets.cpp | 28 +- gfx/skia/skia/src/views/SkWindow.cpp | 89 +- .../skia/src/views/animated/SkBorderView.cpp | 4 +- .../skia/src/views/animated/SkImageView.cpp | 20 +- .../src/views/animated/SkProgressBarView.cpp | 4 +- .../src/views/animated/SkScrollBarView.cpp | 4 +- .../src/views/animated/SkStaticTextView.cpp | 14 +- .../skia/src/views/animated/SkWidgetViews.cpp | 22 +- .../skia/src/views/mac/SampleApp-Info.plist | 34 - gfx/skia/skia/src/views/mac/SampleApp.xib | 3962 ------------- .../skia/src/views/mac/SampleAppDelegate.h | 24 - .../skia/src/views/mac/SampleAppDelegate.mm | 16 - gfx/skia/skia/src/views/mac/SkNSView.h | 5 + gfx/skia/skia/src/views/mac/SkNSView.mm | 48 +- .../skia/src/views/mac/SkOSWindow_Mac.cpp | 542 -- gfx/skia/skia/src/views/mac/SkOSWindow_Mac.mm | 16 +- gfx/skia/skia/src/views/mac/SkSampleNSView.mm | 5 - gfx/skia/skia/src/views/mac/skia_mac.mm | 114 +- .../skia/src/views/sdl/SkOSWindow_SDL.cpp | 442 +- .../skia/src/views/unix/SkOSWindow_Unix.cpp | 161 +- .../views/unix/XkeysToSkKeys.h | 0 .../{include => src}/views/unix/keysym2ucs.h | 0 gfx/skia/skia/src/views/unix/skia_unix.cpp | 2 +- .../skia/src/views/win/SkOSWindow_win.cpp | 234 +- gfx/skia/skia/src/views/win/skia_win.cpp | 269 +- gfx/skia/skia/src/xml/SkBML_XMLParser.cpp | 2 +- gfx/skia/skia/src/xml/SkDOM.cpp | 158 +- gfx/skia/skia/src/xml/SkJS.cpp | 228 - gfx/skia/skia/src/xml/SkJSDisplayable.cpp | 452 -- gfx/skia/skia/src/xml/SkXMLParser.cpp | 17 +- gfx/skia/skia/src/xml/SkXMLPullParser.cpp | 10 +- gfx/skia/skia/src/xml/SkXMLWriter.cpp | 60 +- 1862 files changed, 166314 insertions(+), 122058 deletions(-) create mode 100644 gfx/skia/skia/include/android/SkBRDAllocator.h create mode 100644 gfx/skia/skia/include/android/SkBitmapRegionDecoder.h create mode 100644 gfx/skia/skia/include/c/sk_canvas.h create mode 100644 gfx/skia/skia/include/c/sk_data.h create mode 100644 gfx/skia/skia/include/c/sk_image.h create mode 100644 gfx/skia/skia/include/c/sk_maskfilter.h create mode 100644 gfx/skia/skia/include/c/sk_matrix.h create mode 100644 gfx/skia/skia/include/c/sk_paint.h create mode 100644 gfx/skia/skia/include/c/sk_path.h create mode 100644 gfx/skia/skia/include/c/sk_picture.h create mode 100644 gfx/skia/skia/include/c/sk_shader.h create mode 100644 gfx/skia/skia/include/c/sk_surface.h create mode 100644 gfx/skia/skia/include/c/sk_types.h create mode 100644 gfx/skia/skia/include/codec/SkAndroidCodec.h create mode 100644 gfx/skia/skia/include/codec/SkCodec.h create mode 100644 gfx/skia/skia/include/codec/SkEncodedFormat.h delete mode 100644 gfx/skia/skia/include/core/SkDeviceProperties.h delete mode 100644 gfx/skia/skia/include/core/SkDrawPictureCallback.h create mode 100644 gfx/skia/skia/include/core/SkDrawable.h delete mode 100644 gfx/skia/skia/include/core/SkDynamicAnnotations.h create mode 100644 gfx/skia/skia/include/core/SkFilterQuality.h delete mode 100644 gfx/skia/skia/include/core/SkFlattenableBuffers.h rename gfx/skia/skia/include/{ports => core}/SkFontStyle.h (93%) delete mode 100644 gfx/skia/skia/include/core/SkInstCnt.h create mode 100644 gfx/skia/skia/include/core/SkMultiPictureDraw.h delete mode 100644 gfx/skia/skia/include/core/SkPaintOptionsAndroid.h delete mode 100644 gfx/skia/skia/include/core/SkPatch.h create mode 100644 gfx/skia/skia/include/core/SkPixelSerializer.h create mode 100644 gfx/skia/skia/include/core/SkPixmap.h create mode 100644 gfx/skia/skia/include/core/SkPngChunkReader.h create mode 100644 gfx/skia/skia/include/core/SkPoint3.h create mode 100644 gfx/skia/skia/include/core/SkRSXform.h create mode 100644 gfx/skia/skia/include/core/SkSurfaceProps.h create mode 100644 gfx/skia/skia/include/core/SkTextBlob.h delete mode 100644 gfx/skia/skia/include/core/SkThread.h create mode 100644 gfx/skia/skia/include/core/SkTraceMemoryDump.h create mode 100644 gfx/skia/skia/include/effects/SkArcToPathEffect.h delete mode 100644 gfx/skia/skia/include/effects/SkAvoidXfermode.h delete mode 100644 gfx/skia/skia/include/effects/SkBitmapSource.h create mode 100644 gfx/skia/skia/include/effects/SkColorCubeFilter.h create mode 100644 gfx/skia/skia/include/effects/SkImageSource.h create mode 100644 gfx/skia/skia/include/effects/SkModeColorFilter.h delete mode 100644 gfx/skia/skia/include/effects/SkPorterDuff.h delete mode 100644 gfx/skia/skia/include/effects/SkStippleMaskFilter.h delete mode 100644 gfx/skia/skia/include/effects/SkTransparentShader.h delete mode 100644 gfx/skia/skia/include/gpu/GrBackendEffectFactory.h create mode 100644 gfx/skia/skia/include/gpu/GrBlend.h create mode 100644 gfx/skia/skia/include/gpu/GrCaps.h create mode 100644 gfx/skia/skia/include/gpu/GrClip.h delete mode 100644 gfx/skia/skia/include/gpu/GrClipData.h delete mode 100644 gfx/skia/skia/include/gpu/GrContextFactory.h create mode 100644 gfx/skia/skia/include/gpu/GrContextOptions.h create mode 100644 gfx/skia/skia/include/gpu/GrDrawContext.h delete mode 100644 gfx/skia/skia/include/gpu/GrDrawEffect.h delete mode 100644 gfx/skia/skia/include/gpu/GrEffect.h delete mode 100644 gfx/skia/skia/include/gpu/GrEffectStage.h delete mode 100644 gfx/skia/skia/include/gpu/GrEffectUnitTest.h delete mode 100644 gfx/skia/skia/include/gpu/GrFontScaler.h create mode 100644 gfx/skia/skia/include/gpu/GrFragmentProcessor.h create mode 100644 gfx/skia/skia/include/gpu/GrGpuResourceRef.h create mode 100644 gfx/skia/skia/include/gpu/GrInvariantOutput.h create mode 100644 gfx/skia/skia/include/gpu/GrProcessor.h create mode 100644 gfx/skia/skia/include/gpu/GrProcessorUnitTest.h create mode 100644 gfx/skia/skia/include/gpu/GrProgramElement.h create mode 100644 gfx/skia/skia/include/gpu/GrResourceKey.h create mode 100644 gfx/skia/skia/include/gpu/GrShaderVar.h delete mode 100644 gfx/skia/skia/include/gpu/GrTBackendEffectFactory.h create mode 100644 gfx/skia/skia/include/gpu/GrTestUtils.h create mode 100644 gfx/skia/skia/include/gpu/GrTextureParams.h create mode 100644 gfx/skia/skia/include/gpu/GrTextureProvider.h delete mode 100644 gfx/skia/skia/include/gpu/GrUserConfig.h create mode 100644 gfx/skia/skia/include/gpu/GrXferProcessor.h delete mode 100644 gfx/skia/skia/include/gpu/SkGpuDevice.h create mode 100644 gfx/skia/skia/include/gpu/effects/GrConstColorProcessor.h create mode 100644 gfx/skia/skia/include/gpu/effects/GrCoverageSetOpXP.h create mode 100644 gfx/skia/skia/include/gpu/effects/GrCustomXfermode.h create mode 100644 gfx/skia/skia/include/gpu/effects/GrPorterDuffXferProcessor.h create mode 100644 gfx/skia/skia/include/gpu/effects/GrXfermodeFragmentProcessor.h create mode 100644 gfx/skia/skia/include/gpu/gl/GrGLSLPrettyPrint.h create mode 100644 gfx/skia/skia/include/gpu/gl/GrGLTypes.h delete mode 100644 gfx/skia/skia/include/gpu/gl/SkANGLEGLContext.h delete mode 100644 gfx/skia/skia/include/gpu/gl/SkDebugGLContext.h create mode 100644 gfx/skia/skia/include/gpu/gl/SkGLContext.h delete mode 100644 gfx/skia/skia/include/gpu/gl/SkGLContextHelper.h delete mode 100644 gfx/skia/skia/include/gpu/gl/SkMesaGLContext.h delete mode 100644 gfx/skia/skia/include/gpu/gl/SkNativeGLContext.h create mode 100644 gfx/skia/skia/include/gpu/gl/angle/SkANGLEGLContext.h create mode 100644 gfx/skia/skia/include/gpu/gl/command_buffer/SkCommandBufferGLContext.h delete mode 100644 gfx/skia/skia/include/pdf/SkPDFDevice.h delete mode 100644 gfx/skia/skia/include/pdf/SkPDFDocument.h create mode 100644 gfx/skia/skia/include/ports/SkAtomics_atomic.h create mode 100644 gfx/skia/skia/include/ports/SkAtomics_std.h create mode 100644 gfx/skia/skia/include/ports/SkAtomics_sync.h create mode 100644 gfx/skia/skia/include/ports/SkFontMgr_android.h create mode 100644 gfx/skia/skia/include/ports/SkFontMgr_custom.h create mode 100644 gfx/skia/skia/include/ports/SkFontMgr_fontconfig.h delete mode 100644 gfx/skia/skia/include/ports/SkTypeface_android.h create mode 100644 gfx/skia/skia/include/private/SkAtomics.h create mode 100644 gfx/skia/skia/include/private/SkChecksum.h rename gfx/skia/skia/include/{core => private}/SkFloatBits.h (98%) rename gfx/skia/skia/include/{core => private}/SkFloatingPoint.h (60%) create mode 100644 gfx/skia/skia/include/private/SkGpuFenceSync.h create mode 100644 gfx/skia/skia/include/private/SkMiniRecorder.h create mode 100644 gfx/skia/skia/include/private/SkMutex.h rename gfx/skia/skia/include/{core => private}/SkOnce.h (70%) create mode 100644 gfx/skia/skia/include/private/SkOncePtr.h create mode 100644 gfx/skia/skia/include/private/SkRecords.h create mode 100644 gfx/skia/skia/include/private/SkSemaphore.h create mode 100644 gfx/skia/skia/include/private/SkSpinlock.h create mode 100644 gfx/skia/skia/include/private/SkTHash.h create mode 100644 gfx/skia/skia/include/private/SkTLogic.h rename gfx/skia/skia/include/{core => private}/SkTemplates.h (69%) create mode 100644 gfx/skia/skia/include/private/SkThreadID.h create mode 100644 gfx/skia/skia/include/private/SkUniquePtr.h create mode 100644 gfx/skia/skia/include/private/SkUtility.h rename gfx/skia/skia/include/{core => private}/SkWeakRefCnt.h (97%) delete mode 100644 gfx/skia/skia/include/record/SkRecording.h create mode 100644 gfx/skia/skia/include/svg/SkSVGCanvas.h rename gfx/skia/skia/include/svg/{ => parser}/SkSVGAttribute.h (86%) rename gfx/skia/skia/include/svg/{ => parser}/SkSVGBase.h (100%) rename gfx/skia/skia/include/svg/{ => parser}/SkSVGPaintState.h (100%) rename gfx/skia/skia/include/svg/{ => parser}/SkSVGParser.h (99%) rename gfx/skia/skia/include/svg/{ => parser}/SkSVGTypes.h (100%) delete mode 100644 gfx/skia/skia/include/utils/SkCondVar.h delete mode 100644 gfx/skia/skia/include/utils/SkDeferredCanvas.h create mode 100644 gfx/skia/skia/include/utils/SkPaintFilterCanvas.h delete mode 100644 gfx/skia/skia/include/utils/SkPathUtils.h delete mode 100644 gfx/skia/skia/include/utils/SkProxyCanvas.h delete mode 100644 gfx/skia/skia/include/utils/SkRunnable.h rename gfx/skia/skia/include/{views => utils}/SkTextBox.h (86%) delete mode 100644 gfx/skia/skia/include/utils/SkThreadPool.h delete mode 100644 gfx/skia/skia/include/utils/ios/SkStream_NSData.h delete mode 100644 gfx/skia/skia/include/views/SkOSWindow_NaCl.h delete mode 100644 gfx/skia/skia/include/views/android/AndroidKeyToSkKey.h delete mode 100644 gfx/skia/skia/include/xml/SkJS.h create mode 100644 gfx/skia/skia/src/android/SkBitmapRegionCanvas.cpp create mode 100644 gfx/skia/skia/src/android/SkBitmapRegionCanvas.h create mode 100644 gfx/skia/skia/src/android/SkBitmapRegionCodec.cpp create mode 100644 gfx/skia/skia/src/android/SkBitmapRegionCodec.h create mode 100644 gfx/skia/skia/src/android/SkBitmapRegionDecoder.cpp create mode 100644 gfx/skia/skia/src/android/SkBitmapRegionDecoderPriv.h rename gfx/skia/skia/src/animator/{SkDrawable.cpp => SkADrawable.cpp} (51%) rename gfx/skia/skia/src/animator/{SkDrawable.h => SkADrawable.h} (79%) delete mode 100644 gfx/skia/skia/src/animator/SkDrawTransparentShader.cpp delete mode 100644 gfx/skia/skia/src/animator/SkDrawTransparentShader.h create mode 100644 gfx/skia/skia/src/c/sk_c_from_to.h create mode 100644 gfx/skia/skia/src/c/sk_paint.cpp create mode 100644 gfx/skia/skia/src/c/sk_surface.cpp create mode 100644 gfx/skia/skia/src/c/sk_types_priv.h create mode 100644 gfx/skia/skia/src/codec/SkAndroidCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkBmpCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkBmpCodec.h create mode 100644 gfx/skia/skia/src/codec/SkBmpMaskCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkBmpMaskCodec.h create mode 100644 gfx/skia/skia/src/codec/SkBmpRLECodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkBmpRLECodec.h create mode 100644 gfx/skia/skia/src/codec/SkBmpStandardCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkBmpStandardCodec.h create mode 100644 gfx/skia/skia/src/codec/SkCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkCodecPriv.h create mode 100644 gfx/skia/skia/src/codec/SkCodec_libgif.cpp create mode 100644 gfx/skia/skia/src/codec/SkCodec_libgif.h create mode 100644 gfx/skia/skia/src/codec/SkCodec_libico.cpp create mode 100644 gfx/skia/skia/src/codec/SkCodec_libico.h create mode 100644 gfx/skia/skia/src/codec/SkCodec_libpng.cpp create mode 100644 gfx/skia/skia/src/codec/SkCodec_libpng.h create mode 100644 gfx/skia/skia/src/codec/SkCodec_wbmp.cpp create mode 100644 gfx/skia/skia/src/codec/SkCodec_wbmp.h create mode 100644 gfx/skia/skia/src/codec/SkJpegCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkJpegCodec.h create mode 100644 gfx/skia/skia/src/codec/SkJpegDecoderMgr.cpp create mode 100644 gfx/skia/skia/src/codec/SkJpegDecoderMgr.h create mode 100644 gfx/skia/skia/src/codec/SkJpegUtility_codec.cpp create mode 100644 gfx/skia/skia/src/codec/SkJpegUtility_codec.h create mode 100644 gfx/skia/skia/src/codec/SkMaskSwizzler.cpp create mode 100644 gfx/skia/skia/src/codec/SkMaskSwizzler.h create mode 100644 gfx/skia/skia/src/codec/SkMasks.cpp create mode 100644 gfx/skia/skia/src/codec/SkMasks.h create mode 100644 gfx/skia/skia/src/codec/SkSampledCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkSampledCodec.h create mode 100644 gfx/skia/skia/src/codec/SkSampler.cpp create mode 100644 gfx/skia/skia/src/codec/SkSampler.h create mode 100644 gfx/skia/skia/src/codec/SkSwizzler.cpp create mode 100644 gfx/skia/skia/src/codec/SkSwizzler.h create mode 100644 gfx/skia/skia/src/codec/SkWebpAdapterCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkWebpAdapterCodec.h create mode 100644 gfx/skia/skia/src/codec/SkWebpCodec.cpp create mode 100644 gfx/skia/skia/src/codec/SkWebpCodec.h create mode 100644 gfx/skia/skia/src/core/Sk4px.h rename gfx/skia/skia/{include => src}/core/SkAdvancedTypefaceMetrics.h (86%) delete mode 100644 gfx/skia/skia/src/core/SkBBoxHierarchyRecord.cpp delete mode 100644 gfx/skia/skia/src/core/SkBBoxHierarchyRecord.h delete mode 100644 gfx/skia/skia/src/core/SkBBoxRecord.cpp delete mode 100644 gfx/skia/skia/src/core/SkBBoxRecord.h create mode 100644 gfx/skia/skia/src/core/SkBigPicture.cpp create mode 100644 gfx/skia/skia/src/core/SkBigPicture.h create mode 100644 gfx/skia/skia/src/core/SkBitmapCache.cpp create mode 100644 gfx/skia/skia/src/core/SkBitmapCache.h create mode 100644 gfx/skia/skia/src/core/SkBitmapController.cpp create mode 100644 gfx/skia/skia/src/core/SkBitmapController.h create mode 100644 gfx/skia/skia/src/core/SkBitmapProvider.cpp create mode 100644 gfx/skia/skia/src/core/SkBitmapProvider.h delete mode 100644 gfx/skia/skia/src/core/SkBitmap_scroll.cpp create mode 100644 gfx/skia/skia/src/core/SkCachedData.cpp create mode 100644 gfx/skia/skia/src/core/SkCachedData.h create mode 100644 gfx/skia/skia/src/core/SkCanvasPriv.h create mode 100644 gfx/skia/skia/src/core/SkChecksum.cpp delete mode 100644 gfx/skia/skia/src/core/SkChecksum.h rename gfx/skia/skia/{include => src}/core/SkColorShader.h (52%) delete mode 100644 gfx/skia/skia/src/core/SkDeviceImageFilterProxy.h create mode 100644 gfx/skia/skia/src/core/SkDrawable.cpp rename gfx/skia/skia/{include => src}/core/SkEndian.h (97%) create mode 100644 gfx/skia/skia/src/core/SkFindAndPlaceGlyph.h delete mode 100644 gfx/skia/skia/src/core/SkFlate.cpp delete mode 100644 gfx/skia/skia/src/core/SkFlate.h delete mode 100644 gfx/skia/skia/src/core/SkFloat.cpp delete mode 100644 gfx/skia/skia/src/core/SkFloat.h create mode 100644 gfx/skia/skia/src/core/SkFontMgr.cpp create mode 100644 gfx/skia/skia/src/core/SkFontStyle.cpp create mode 100644 gfx/skia/skia/src/core/SkForceCPlusPlusLinking.cpp mode change 100755 => 100644 gfx/skia/skia/src/core/SkGlyphCache.cpp create mode 100644 gfx/skia/skia/src/core/SkHalf.cpp create mode 100644 gfx/skia/skia/src/core/SkHalf.h create mode 100644 gfx/skia/skia/src/core/SkImageCacherator.cpp create mode 100644 gfx/skia/skia/src/core/SkImageCacherator.h create mode 100644 gfx/skia/skia/src/core/SkLayerInfo.h delete mode 100644 gfx/skia/skia/src/core/SkLazyFnPtr.h delete mode 100644 gfx/skia/skia/src/core/SkLazyPtr.h create mode 100644 gfx/skia/skia/src/core/SkLight.h create mode 100644 gfx/skia/skia/src/core/SkLightingShader.cpp create mode 100644 gfx/skia/skia/src/core/SkLightingShader.h create mode 100644 gfx/skia/skia/src/core/SkLocalMatrixImageFilter.cpp create mode 100644 gfx/skia/skia/src/core/SkLocalMatrixImageFilter.h create mode 100644 gfx/skia/skia/src/core/SkMaskCache.cpp create mode 100644 gfx/skia/skia/src/core/SkMaskCache.h delete mode 100644 gfx/skia/skia/src/core/SkMatrixClipStateMgr.cpp delete mode 100644 gfx/skia/skia/src/core/SkMatrixClipStateMgr.h rename gfx/skia/skia/src/{effects => core}/SkMatrixImageFilter.cpp (64%) rename gfx/skia/skia/{include/effects => src/core}/SkMatrixImageFilter.h (71%) create mode 100644 gfx/skia/skia/src/core/SkMiniRecorder.cpp create mode 100644 gfx/skia/skia/src/core/SkMultiPictureDraw.cpp create mode 100644 gfx/skia/skia/src/core/SkNextID.h create mode 100644 gfx/skia/skia/src/core/SkNinePatchIter.cpp create mode 100644 gfx/skia/skia/src/core/SkNinePatchIter.h create mode 100644 gfx/skia/skia/src/core/SkNx.h create mode 100644 gfx/skia/skia/src/core/SkOpts.cpp create mode 100644 gfx/skia/skia/src/core/SkOpts.h delete mode 100644 gfx/skia/skia/src/core/SkPaintOptionsAndroid.cpp delete mode 100644 gfx/skia/skia/src/core/SkPatch.cpp delete mode 100644 gfx/skia/skia/src/core/SkPathHeap.cpp delete mode 100644 gfx/skia/skia/src/core/SkPathHeap.h create mode 100644 gfx/skia/skia/src/core/SkPathPriv.h create mode 100644 gfx/skia/skia/src/core/SkPictureCommon.h create mode 100644 gfx/skia/skia/src/core/SkPictureContentInfo.cpp create mode 100644 gfx/skia/skia/src/core/SkPictureContentInfo.h create mode 100644 gfx/skia/skia/src/core/SkPictureImageGenerator.cpp delete mode 100644 gfx/skia/skia/src/core/SkPictureRangePlayback.cpp delete mode 100644 gfx/skia/skia/src/core/SkPictureRangePlayback.h delete mode 100644 gfx/skia/skia/src/core/SkPictureReplacementPlayback.cpp delete mode 100644 gfx/skia/skia/src/core/SkPictureReplacementPlayback.h delete mode 100644 gfx/skia/skia/src/core/SkPictureStateTree.cpp delete mode 100644 gfx/skia/skia/src/core/SkPictureStateTree.h create mode 100644 gfx/skia/skia/src/core/SkPixmap.cpp create mode 100644 gfx/skia/skia/src/core/SkPoint3.cpp delete mode 100644 gfx/skia/skia/src/core/SkProcSpriteBlitter.cpp create mode 100644 gfx/skia/skia/src/core/SkPx.h delete mode 100644 gfx/skia/skia/src/core/SkQuadTree.cpp delete mode 100644 gfx/skia/skia/src/core/SkQuadTree.h create mode 100644 gfx/skia/skia/src/core/SkRWBuffer.cpp create mode 100644 gfx/skia/skia/src/core/SkRWBuffer.h rename gfx/skia/skia/{include => src}/core/SkReadBuffer.h (92%) rename gfx/skia/skia/{include => src}/core/SkReader32.h (88%) create mode 100644 gfx/skia/skia/src/core/SkRecord.cpp delete mode 100644 gfx/skia/skia/src/core/SkRecordAnalysis.cpp delete mode 100644 gfx/skia/skia/src/core/SkRecordAnalysis.h delete mode 100644 gfx/skia/skia/src/core/SkRecording.cpp create mode 100644 gfx/skia/skia/src/core/SkRecords.cpp delete mode 100644 gfx/skia/skia/src/core/SkRecords.h create mode 100644 gfx/skia/skia/src/core/SkRemote.cpp create mode 100644 gfx/skia/skia/src/core/SkRemote.h create mode 100644 gfx/skia/skia/src/core/SkRemote_protocol.h create mode 100644 gfx/skia/skia/src/core/SkResourceCache.cpp create mode 100644 gfx/skia/skia/src/core/SkResourceCache.h delete mode 100644 gfx/skia/skia/src/core/SkScaledImageCache.cpp delete mode 100644 gfx/skia/skia/src/core/SkScaledImageCache.h create mode 100644 gfx/skia/skia/src/core/SkSemaphore.cpp create mode 100644 gfx/skia/skia/src/core/SkSharedMutex.cpp create mode 100644 gfx/skia/skia/src/core/SkSharedMutex.h delete mode 100644 gfx/skia/skia/src/core/SkSinTable.h create mode 100644 gfx/skia/skia/src/core/SkSpinlock.cpp create mode 100644 gfx/skia/skia/src/core/SkSurfacePriv.h create mode 100644 gfx/skia/skia/src/core/SkTDPQueue.h delete mode 100644 gfx/skia/skia/src/core/SkTInternalSList.h delete mode 100644 gfx/skia/skia/src/core/SkTObjectPool.h delete mode 100644 gfx/skia/skia/src/core/SkTRefArray.h create mode 100644 gfx/skia/skia/src/core/SkTTopoSort.h create mode 100644 gfx/skia/skia/src/core/SkTaskGroup.cpp create mode 100644 gfx/skia/skia/src/core/SkTaskGroup.h create mode 100644 gfx/skia/skia/src/core/SkTextBlob.cpp create mode 100644 gfx/skia/skia/src/core/SkTextBlobRunIterator.h create mode 100644 gfx/skia/skia/src/core/SkThreadID.cpp delete mode 100644 gfx/skia/skia/src/core/SkThreadPriv.h delete mode 100644 gfx/skia/skia/src/core/SkTileGrid.cpp delete mode 100644 gfx/skia/skia/src/core/SkTileGrid.h create mode 100644 gfx/skia/skia/src/core/SkTime.cpp create mode 100644 gfx/skia/skia/src/core/SkTraceEventCommon.h create mode 100644 gfx/skia/skia/src/core/SkVarAlloc.cpp create mode 100644 gfx/skia/skia/src/core/SkVarAlloc.h create mode 100644 gfx/skia/skia/src/core/SkXfermodeInterpretation.cpp create mode 100644 gfx/skia/skia/src/core/SkXfermodeInterpretation.h create mode 100644 gfx/skia/skia/src/core/SkYUVPlanesCache.cpp create mode 100644 gfx/skia/skia/src/core/SkYUVPlanesCache.h create mode 100644 gfx/skia/skia/src/doc/SkDocument_PDF_None.cpp create mode 100644 gfx/skia/skia/src/doc/SkDocument_XPS.cpp create mode 100644 gfx/skia/skia/src/doc/SkDocument_XPS_None.cpp create mode 100644 gfx/skia/skia/src/effects/GrCircleBlurFragmentProcessor.cpp create mode 100644 gfx/skia/skia/src/effects/GrCircleBlurFragmentProcessor.h create mode 100644 gfx/skia/skia/src/effects/SkArcToPathEffect.cpp create mode 100644 gfx/skia/skia/src/effects/SkArithmeticMode_gpu.cpp create mode 100644 gfx/skia/skia/src/effects/SkArithmeticMode_gpu.h delete mode 100644 gfx/skia/skia/src/effects/SkAvoidXfermode.cpp delete mode 100644 gfx/skia/skia/src/effects/SkBitmapSource.cpp create mode 100644 gfx/skia/skia/src/effects/SkColorCubeFilter.cpp mode change 100755 => 100644 gfx/skia/skia/src/effects/SkColorFilterImageFilter.cpp create mode 100644 gfx/skia/skia/src/effects/SkImageSource.cpp delete mode 100644 gfx/skia/skia/src/effects/SkPorterDuff.cpp delete mode 100644 gfx/skia/skia/src/effects/SkStippleMaskFilter.cpp delete mode 100644 gfx/skia/skia/src/effects/SkTransparentShader.cpp rename gfx/skia/skia/src/effects/gradients/{SkBitmapCache.cpp => SkGradientBitmapCache.cpp} (75%) rename gfx/skia/skia/src/effects/gradients/{SkBitmapCache.h => SkGradientBitmapCache.h} (69%) delete mode 100644 gfx/skia/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp delete mode 100644 gfx/skia/skia/src/effects/gradients/SkTwoPointRadialGradient.h create mode 100644 gfx/skia/skia/src/fonts/SkRandomScalerContext.cpp create mode 100644 gfx/skia/skia/src/fonts/SkRandomScalerContext.h delete mode 100644 gfx/skia/skia/src/gpu/GrAAConvexPathRenderer.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrAAConvexPathRenderer.h delete mode 100644 gfx/skia/skia/src/gpu/GrAAHairLinePathRenderer.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrAAHairLinePathRenderer.h delete mode 100644 gfx/skia/skia/src/gpu/GrAARectRenderer.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrAARectRenderer.h delete mode 100644 gfx/skia/skia/src/gpu/GrAddPathRenderers_default.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrAllocPool.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrAllocPool.h delete mode 100644 gfx/skia/skia/src/gpu/GrAtlas.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrAtlas.h create mode 100644 gfx/skia/skia/src/gpu/GrAtlasTextBlob.cpp create mode 100644 gfx/skia/skia/src/gpu/GrAtlasTextBlob.h create mode 100644 gfx/skia/skia/src/gpu/GrAtlasTextContext.cpp create mode 100644 gfx/skia/skia/src/gpu/GrAtlasTextContext.h create mode 100644 gfx/skia/skia/src/gpu/GrAutoLocaleSetter.h create mode 100644 gfx/skia/skia/src/gpu/GrBatchAtlas.cpp create mode 100644 gfx/skia/skia/src/gpu/GrBatchAtlas.h create mode 100644 gfx/skia/skia/src/gpu/GrBatchFlushState.cpp create mode 100644 gfx/skia/skia/src/gpu/GrBatchFlushState.h create mode 100644 gfx/skia/skia/src/gpu/GrBatchFontCache.cpp create mode 100644 gfx/skia/skia/src/gpu/GrBatchFontCache.h create mode 100644 gfx/skia/skia/src/gpu/GrBatchTest.cpp create mode 100644 gfx/skia/skia/src/gpu/GrBatchTest.h delete mode 100644 gfx/skia/skia/src/gpu/GrBinHashKey.h delete mode 100755 gfx/skia/skia/src/gpu/GrBitmapTextContext.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrBitmapTextContext.h delete mode 100644 gfx/skia/skia/src/gpu/GrBlend.h create mode 100644 gfx/skia/skia/src/gpu/GrBlurUtils.cpp create mode 100644 gfx/skia/skia/src/gpu/GrBlurUtils.h delete mode 100644 gfx/skia/skia/src/gpu/GrCacheID.cpp create mode 100644 gfx/skia/skia/src/gpu/GrCaps.cpp create mode 100644 gfx/skia/skia/src/gpu/GrClip.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrClipData.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrClipMaskCache.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrClipMaskCache.h mode change 100755 => 100644 gfx/skia/skia/src/gpu/GrContext.cpp create mode 100755 gfx/skia/skia/src/gpu/GrContextFactory.cpp create mode 100644 gfx/skia/skia/src/gpu/GrContextFactory.h create mode 100644 gfx/skia/skia/src/gpu/GrCoordTransform.cpp create mode 100644 gfx/skia/skia/src/gpu/GrDefaultGeoProcFactory.cpp create mode 100644 gfx/skia/skia/src/gpu/GrDefaultGeoProcFactory.h delete mode 100644 gfx/skia/skia/src/gpu/GrDefaultPathRenderer.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrDefaultPathRenderer.h delete mode 100755 gfx/skia/skia/src/gpu/GrDistanceFieldTextContext.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrDistanceFieldTextContext.h create mode 100644 gfx/skia/skia/src/gpu/GrDrawContext.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrDrawState.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrDrawState.h delete mode 100644 gfx/skia/skia/src/gpu/GrDrawTargetCaps.h create mode 100644 gfx/skia/skia/src/gpu/GrDrawingManager.cpp create mode 100644 gfx/skia/skia/src/gpu/GrDrawingManager.h delete mode 100644 gfx/skia/skia/src/gpu/GrEffect.cpp create mode 100644 gfx/skia/skia/src/gpu/GrFontScaler.h create mode 100644 gfx/skia/skia/src/gpu/GrFragmentProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/GrGeometryProcessor.h rename gfx/skia/skia/{include => src}/gpu/GrGlyph.h (62%) create mode 100644 gfx/skia/skia/src/gpu/GrGpuFactory.h create mode 100644 gfx/skia/skia/src/gpu/GrGpuResourceCacheAccess.h create mode 100644 gfx/skia/skia/src/gpu/GrGpuResourcePriv.h create mode 100644 gfx/skia/skia/src/gpu/GrGpuResourceRef.cpp create mode 100644 gfx/skia/skia/src/gpu/GrImageIDTextureAdjuster.cpp create mode 100644 gfx/skia/skia/src/gpu/GrImageIDTextureAdjuster.h delete mode 100644 gfx/skia/skia/src/gpu/GrInOrderDrawBuffer.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrInOrderDrawBuffer.h create mode 100644 gfx/skia/skia/src/gpu/GrInvariantOutput.cpp create mode 100644 gfx/skia/skia/src/gpu/GrLayerAtlas.cpp create mode 100644 gfx/skia/skia/src/gpu/GrLayerAtlas.h create mode 100644 gfx/skia/skia/src/gpu/GrLayerHoister.cpp create mode 100644 gfx/skia/skia/src/gpu/GrLayerHoister.h create mode 100644 gfx/skia/skia/src/gpu/GrNonAtomicRef.h delete mode 100644 gfx/skia/skia/src/gpu/GrOrderedSet.h create mode 100644 gfx/skia/skia/src/gpu/GrPathProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/GrPathProcessor.h create mode 100644 gfx/skia/skia/src/gpu/GrPathRange.cpp rename gfx/skia/skia/{include => src}/gpu/GrPathRendererChain.h (70%) create mode 100644 gfx/skia/skia/src/gpu/GrPathRendering.cpp create mode 100644 gfx/skia/skia/src/gpu/GrPathRendering.h create mode 100644 gfx/skia/skia/src/gpu/GrPendingProgramElement.h delete mode 100644 gfx/skia/skia/src/gpu/GrPictureUtils.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrPictureUtils.h create mode 100644 gfx/skia/skia/src/gpu/GrPipeline.cpp create mode 100644 gfx/skia/skia/src/gpu/GrPipeline.h create mode 100644 gfx/skia/skia/src/gpu/GrPipelineBuilder.cpp create mode 100644 gfx/skia/skia/src/gpu/GrPipelineBuilder.h delete mode 100644 gfx/skia/skia/src/gpu/GrPlotMgr.h create mode 100644 gfx/skia/skia/src/gpu/GrPrimitiveProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/GrPrimitiveProcessor.h create mode 100644 gfx/skia/skia/src/gpu/GrProcOptInfo.cpp create mode 100644 gfx/skia/skia/src/gpu/GrProcOptInfo.h create mode 100644 gfx/skia/skia/src/gpu/GrProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/GrProcessorUnitTest.cpp create mode 100644 gfx/skia/skia/src/gpu/GrProgramDesc.h create mode 100644 gfx/skia/skia/src/gpu/GrProgramElement.cpp create mode 100644 gfx/skia/skia/src/gpu/GrQuad.h create mode 100644 gfx/skia/skia/src/gpu/GrRecordReplaceDraw.cpp create mode 100644 gfx/skia/skia/src/gpu/GrRecordReplaceDraw.h mode change 100755 => 100644 gfx/skia/skia/src/gpu/GrRectanizer_skyline.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrRedBlackTree.h create mode 100644 gfx/skia/skia/src/gpu/GrRenderTargetPriv.h create mode 100644 gfx/skia/skia/src/gpu/GrResourceProvider.cpp create mode 100644 gfx/skia/skia/src/gpu/GrResourceProvider.h delete mode 100644 gfx/skia/skia/src/gpu/GrStencilAndCoverPathRenderer.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrStencilAndCoverPathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/GrStencilAttachment.cpp rename gfx/skia/skia/src/gpu/{GrStencilBuffer.h => GrStencilAttachment.h} (72%) delete mode 100644 gfx/skia/skia/src/gpu/GrStencilBuffer.cpp create mode 100644 gfx/skia/skia/src/gpu/GrStrokeInfo.cpp create mode 100644 gfx/skia/skia/src/gpu/GrSurfacePriv.h delete mode 100644 gfx/skia/skia/src/gpu/GrTBSearch.h delete mode 100644 gfx/skia/skia/src/gpu/GrTHashTable.h create mode 100644 gfx/skia/skia/src/gpu/GrTRecorder.h delete mode 100644 gfx/skia/skia/src/gpu/GrTemplates.h create mode 100644 gfx/skia/skia/src/gpu/GrTestUtils.cpp create mode 100644 gfx/skia/skia/src/gpu/GrTextBlobCache.cpp create mode 100644 gfx/skia/skia/src/gpu/GrTextBlobCache.h delete mode 100644 gfx/skia/skia/src/gpu/GrTextStrike.cpp delete mode 100644 gfx/skia/skia/src/gpu/GrTextStrike.h delete mode 100644 gfx/skia/skia/src/gpu/GrTextStrike_impl.h create mode 100644 gfx/skia/skia/src/gpu/GrTextureParamsAdjuster.cpp create mode 100644 gfx/skia/skia/src/gpu/GrTextureParamsAdjuster.h create mode 100644 gfx/skia/skia/src/gpu/GrTexturePriv.h create mode 100644 gfx/skia/skia/src/gpu/GrTextureProvider.cpp create mode 100644 gfx/skia/skia/src/gpu/GrVertices.h create mode 100644 gfx/skia/skia/src/gpu/GrXferProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/GrYUVProvider.cpp create mode 100644 gfx/skia/skia/src/gpu/GrYUVProvider.h create mode 100644 gfx/skia/skia/src/gpu/SkGpuDevice.h create mode 100644 gfx/skia/skia/src/gpu/SkGpuDevice_drawTexture.cpp create mode 100644 gfx/skia/skia/src/gpu/SkGrPriv.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAConvexPathRenderer.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAConvexPathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAConvexTessellator.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAConvexTessellator.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp create mode 100755 gfx/skia/skia/src/gpu/batches/GrAADistanceFieldPathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAFillRectBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAFillRectBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAHairLinePathRenderer.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAHairLinePathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrAALinearizingConvexPathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAStrokeRectBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrAAStrokeRectBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrAtlasTextBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrAtlasTextBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrClearBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrCopySurfaceBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrCopySurfaceBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrDashLinePathRenderer.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrDashLinePathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrDefaultPathRenderer.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrDefaultPathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrDiscardBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrDrawAtlasBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrDrawAtlasBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrDrawBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrDrawBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrDrawPathBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrDrawPathBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrDrawVerticesBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrDrawVerticesBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrNinePatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrNinePatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrNonAAFillRectBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrNonAAFillRectBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrNonAAStrokeRectBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrNonAAStrokeRectBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrRectBatchFactory.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrRectBatchFactory.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrStencilAndCoverPathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrStencilPathBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrTInstanceBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrTessellatingPathRenderer.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrTessellatingPathRenderer.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrTestBatch.h create mode 100644 gfx/skia/skia/src/gpu/batches/GrVertexBatch.cpp create mode 100644 gfx/skia/skia/src/gpu/batches/GrVertexBatch.h create mode 100644 gfx/skia/skia/src/gpu/effects/GrBitmapTextGeoProc.cpp create mode 100644 gfx/skia/skia/src/gpu/effects/GrBitmapTextGeoProc.h create mode 100644 gfx/skia/skia/src/gpu/effects/GrConstColorProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/effects/GrCoverageSetOpXP.cpp delete mode 100644 gfx/skia/skia/src/gpu/effects/GrCustomCoordsTextureEffect.cpp delete mode 100644 gfx/skia/skia/src/gpu/effects/GrCustomCoordsTextureEffect.h create mode 100644 gfx/skia/skia/src/gpu/effects/GrCustomXfermode.cpp create mode 100644 gfx/skia/skia/src/gpu/effects/GrDisableColorXP.cpp create mode 100644 gfx/skia/skia/src/gpu/effects/GrDisableColorXP.h create mode 100644 gfx/skia/skia/src/gpu/effects/GrDistanceFieldGeoProc.cpp create mode 100644 gfx/skia/skia/src/gpu/effects/GrDistanceFieldGeoProc.h delete mode 100755 gfx/skia/skia/src/gpu/effects/GrDistanceFieldTextureEffect.cpp delete mode 100644 gfx/skia/skia/src/gpu/effects/GrDistanceFieldTextureEffect.h create mode 100644 gfx/skia/skia/src/gpu/effects/GrPorterDuffXferProcessor.cpp delete mode 100644 gfx/skia/skia/src/gpu/effects/GrVertexEffect.h create mode 100644 gfx/skia/skia/src/gpu/effects/GrXfermodeFragmentProcessor.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLAssembleGLESInterface.h delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLEffect.h create mode 100755 gfx/skia/skia/src/gpu/gl/GrGLGLSL.cpp create mode 100755 gfx/skia/skia/src/gpu/gl/GrGLGLSL.h create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLGpu.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLGpu.h create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLGpuProgramCache.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLPathRendering.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLPathRendering.h create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLProgramDataManager.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLProgramDataManager.h delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLProgramEffects.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLProgramEffects.h delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLSL.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLShaderBuilder.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLShaderBuilder.h create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLStencilAttachment.cpp rename gfx/skia/skia/src/gpu/gl/{GrGLStencilBuffer.h => GrGLStencilAttachment.h} (53%) delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLStencilBuffer.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLTextureRenderTarget.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLTextureRenderTarget.h delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLUniformHandle.h delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLUniformManager.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLUniformManager.h create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLVaryingHandler.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/GrGLVaryingHandler.h delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGLVertexEffect.h delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGpuGL.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGpuGL.h delete mode 100644 gfx/skia/skia/src/gpu/gl/GrGpuGL_program.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/SkGLContext.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/SkGLContextHelper.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/android/SkNativeGLContext_android.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/builders/GrGLProgramBuilder.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/builders/GrGLProgramBuilder.h create mode 100644 gfx/skia/skia/src/gpu/gl/builders/GrGLSLPrettyPrint.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/builders/GrGLShaderStringBuilder.h create mode 100644 gfx/skia/skia/src/gpu/gl/command_buffer/SkCommandBufferGLContext.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/debug/SkDebugGLContext.h create mode 100644 gfx/skia/skia/src/gpu/gl/egl/GrGLCreateNativeInterface_egl.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/egl/SkCreatePlatformGLContext_egl.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/glx/GrGLCreateNativeInterface_glx.cpp rename gfx/skia/skia/src/gpu/gl/{unix/SkNativeGLContext_unix.cpp => glx/SkCreatePlatformGLContext_glx.cpp} (57%) create mode 100644 gfx/skia/skia/src/gpu/gl/iOS/SkCreatePlatformGLContext_iOS.mm delete mode 100644 gfx/skia/skia/src/gpu/gl/iOS/SkNativeGLContext_iOS.mm create mode 100644 gfx/skia/skia/src/gpu/gl/mac/SkCreatePlatformGLContext_mac.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/mac/SkNativeGLContext_mac.cpp create mode 100644 gfx/skia/skia/src/gpu/gl/mesa/SkMesaGLContext.h rename gfx/skia/skia/src/{utils/SkThreadUtils_pthread_other.cpp => gpu/gl/nacl/SkCreatePlatformGLContext_nacl.cpp} (55%) delete mode 100644 gfx/skia/skia/src/gpu/gl/nacl/SkNativeGLContext_nacl.cpp delete mode 100644 gfx/skia/skia/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp rename gfx/skia/skia/src/gpu/gl/win/{SkNativeGLContext_win.cpp => SkCreatePlatformGLContext_win.cpp} (58%) create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSL.cpp rename gfx/skia/skia/src/gpu/{gl => glsl}/GrGLSL.h (86%) create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLBlend.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLBlend.h create mode 100755 gfx/skia/skia/src/gpu/glsl/GrGLSLCaps.cpp create mode 100755 gfx/skia/skia/src/gpu/glsl/GrGLSLCaps.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLFragmentProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLFragmentProcessor.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLGeometryProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLGeometryProcessor.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLGeometryShaderBuilder.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLGeometryShaderBuilder.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLPrimitiveProcessor.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLProcessorTypes.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLProgramBuilder.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLProgramBuilder.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLProgramDataManager.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLShaderBuilder.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLShaderBuilder.h rename gfx/skia/skia/src/gpu/{gl/GrGLShaderVar.h => glsl/GrGLSLShaderVar.h} (53%) create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLTextureSampler.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLUtil.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLUtil.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLVarying.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLVarying.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLVertexShaderBuilder.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLVertexShaderBuilder.h create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLXferProcessor.cpp create mode 100644 gfx/skia/skia/src/gpu/glsl/GrGLSLXferProcessor.h rename gfx/skia/skia/src/gpu/{gl => glsl}/GrGLSL_impl.h (100%) delete mode 100644 gfx/skia/skia/src/image/SkImagePriv.cpp create mode 100644 gfx/skia/skia/src/image/SkImageShader.cpp create mode 100644 gfx/skia/skia/src/image/SkImageShader.h delete mode 100644 gfx/skia/skia/src/image/SkImage_Codec.cpp create mode 100644 gfx/skia/skia/src/image/SkImage_Generator.cpp create mode 100644 gfx/skia/skia/src/image/SkImage_Gpu.h create mode 100644 gfx/skia/skia/src/image/SkReadPixelsRec.h create mode 100644 gfx/skia/skia/src/image/SkSurface_Gpu.h create mode 100644 gfx/skia/skia/src/images/SkImageDecoder_astc.cpp delete mode 100644 gfx/skia/skia/src/lazy/SkCachingPixelRef.cpp delete mode 100644 gfx/skia/skia/src/lazy/SkCachingPixelRef.h create mode 100644 gfx/skia/skia/src/opts/Sk4px_NEON.h create mode 100644 gfx/skia/skia/src/opts/Sk4px_SSE2.h create mode 100644 gfx/skia/skia/src/opts/Sk4px_none.h create mode 100644 gfx/skia/skia/src/opts/SkBlitMask_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkBlitRect_opts_SSE2.cpp delete mode 100644 gfx/skia/skia/src/opts/SkBlitRect_opts_SSE2.h create mode 100644 gfx/skia/skia/src/opts/SkBlitRow_opts.h create mode 100644 gfx/skia/skia/src/opts/SkBlitRow_opts_SSE4.cpp delete mode 100644 gfx/skia/skia/src/opts/SkBlitRow_opts_SSE4_asm.S delete mode 100644 gfx/skia/skia/src/opts/SkBlitRow_opts_SSE4_x64_asm.S create mode 100644 gfx/skia/skia/src/opts/SkBlurImageFilter_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts_SSE2.cpp delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts_SSE2.h delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts_SSE4.cpp delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts_SSE4.h delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts_arm.cpp delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts_neon.cpp delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts_neon.h delete mode 100644 gfx/skia/skia/src/opts/SkBlurImage_opts_none.cpp create mode 100644 gfx/skia/skia/src/opts/SkColorCubeFilter_opts.h create mode 100644 gfx/skia/skia/src/opts/SkFloatingPoint_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkMath_opts_SSE2.h create mode 100644 gfx/skia/skia/src/opts/SkMatrix_opts.h create mode 100644 gfx/skia/skia/src/opts/SkMorphologyImageFilter_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkMorphology_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkMorphology_opts_SSE2.cpp delete mode 100644 gfx/skia/skia/src/opts/SkMorphology_opts_SSE2.h delete mode 100644 gfx/skia/skia/src/opts/SkMorphology_opts_arm.cpp delete mode 100644 gfx/skia/skia/src/opts/SkMorphology_opts_neon.cpp delete mode 100644 gfx/skia/skia/src/opts/SkMorphology_opts_neon.h delete mode 100644 gfx/skia/skia/src/opts/SkMorphology_opts_none.cpp create mode 100644 gfx/skia/skia/src/opts/SkNx_avx.h create mode 100644 gfx/skia/skia/src/opts/SkNx_neon.h create mode 100644 gfx/skia/skia/src/opts/SkNx_sse.h create mode 100644 gfx/skia/skia/src/opts/SkOpts_avx.cpp create mode 100644 gfx/skia/skia/src/opts/SkOpts_neon.cpp create mode 100644 gfx/skia/skia/src/opts/SkOpts_sse41.cpp create mode 100644 gfx/skia/skia/src/opts/SkOpts_ssse3.cpp create mode 100644 gfx/skia/skia/src/opts/SkPx_neon.h create mode 100644 gfx/skia/skia/src/opts/SkPx_none.h create mode 100644 gfx/skia/skia/src/opts/SkPx_sse.h delete mode 100644 gfx/skia/skia/src/opts/SkTextureCompression_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkTextureCompression_opts_arm.cpp delete mode 100644 gfx/skia/skia/src/opts/SkTextureCompression_opts_neon.cpp delete mode 100644 gfx/skia/skia/src/opts/SkTextureCompression_opts_neon.h delete mode 100644 gfx/skia/skia/src/opts/SkTextureCompression_opts_none.cpp create mode 100644 gfx/skia/skia/src/opts/SkTextureCompressor_opts.h create mode 100644 gfx/skia/skia/src/opts/SkUtils_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkUtils_opts_SSE2.cpp delete mode 100644 gfx/skia/skia/src/opts/SkUtils_opts_SSE2.h delete mode 100644 gfx/skia/skia/src/opts/SkUtils_opts_arm.cpp delete mode 100644 gfx/skia/skia/src/opts/SkUtils_opts_none.cpp create mode 100644 gfx/skia/skia/src/opts/SkXfermode_opts.h delete mode 100644 gfx/skia/skia/src/opts/SkXfermode_opts_SSE2.cpp delete mode 100644 gfx/skia/skia/src/opts/SkXfermode_opts_SSE2.h delete mode 100644 gfx/skia/skia/src/opts/SkXfermode_opts_arm.cpp delete mode 100644 gfx/skia/skia/src/opts/SkXfermode_opts_arm_neon.cpp delete mode 100644 gfx/skia/skia/src/opts/SkXfermode_opts_arm_neon.h delete mode 100644 gfx/skia/skia/src/opts/SkXfermode_opts_none.cpp delete mode 100644 gfx/skia/skia/src/opts/memset.arm.S delete mode 100644 gfx/skia/skia/src/opts/memset16_neon.S delete mode 100644 gfx/skia/skia/src/opts/memset32_neon.S create mode 100644 gfx/skia/skia/src/pathops/SkDConicLineIntersection.cpp delete mode 100644 gfx/skia/skia/src/pathops/SkDCubicIntersection.cpp delete mode 100644 gfx/skia/skia/src/pathops/SkDQuadImplicit.cpp delete mode 100644 gfx/skia/skia/src/pathops/SkDQuadImplicit.h delete mode 100644 gfx/skia/skia/src/pathops/SkDQuadIntersection.cpp create mode 100644 gfx/skia/skia/src/pathops/SkOpBuilder.cpp create mode 100755 gfx/skia/skia/src/pathops/SkOpCoincidence.cpp create mode 100644 gfx/skia/skia/src/pathops/SkOpCoincidence.h create mode 100644 gfx/skia/skia/src/pathops/SkOpCubicHull.cpp create mode 100755 gfx/skia/skia/src/pathops/SkOpSpan.cpp create mode 100644 gfx/skia/skia/src/pathops/SkOpTAllocator.h delete mode 100644 gfx/skia/skia/src/pathops/SkPathOpsBounds.cpp create mode 100644 gfx/skia/skia/src/pathops/SkPathOpsConic.cpp create mode 100644 gfx/skia/skia/src/pathops/SkPathOpsConic.h create mode 100644 gfx/skia/skia/src/pathops/SkPathOpsCurve.cpp create mode 100644 gfx/skia/skia/src/pathops/SkPathOpsTSect.cpp create mode 100644 gfx/skia/skia/src/pathops/SkPathOpsTSect.h delete mode 100644 gfx/skia/skia/src/pathops/SkPathOpsTriangle.cpp delete mode 100644 gfx/skia/skia/src/pathops/SkPathOpsTriangle.h create mode 100644 gfx/skia/skia/src/pathops/SkPathOpsWinding.cpp delete mode 100644 gfx/skia/skia/src/pathops/SkQuarticRoot.cpp delete mode 100644 gfx/skia/skia/src/pathops/SkQuarticRoot.h create mode 100644 gfx/skia/skia/src/pdf/SkDeflate.cpp create mode 100644 gfx/skia/skia/src/pdf/SkDeflate.h create mode 100644 gfx/skia/skia/src/pdf/SkJpegInfo.cpp create mode 100644 gfx/skia/skia/src/pdf/SkJpegInfo.h create mode 100644 gfx/skia/skia/src/pdf/SkPDFBitmap.cpp create mode 100644 gfx/skia/skia/src/pdf/SkPDFBitmap.h create mode 100644 gfx/skia/skia/src/pdf/SkPDFCanon.cpp create mode 100644 gfx/skia/skia/src/pdf/SkPDFCanon.h delete mode 100644 gfx/skia/skia/src/pdf/SkPDFCatalog.cpp delete mode 100644 gfx/skia/skia/src/pdf/SkPDFCatalog.h create mode 100644 gfx/skia/skia/src/pdf/SkPDFDevice.h delete mode 100644 gfx/skia/skia/src/pdf/SkPDFDeviceFlattener.cpp delete mode 100644 gfx/skia/skia/src/pdf/SkPDFDeviceFlattener.h delete mode 100644 gfx/skia/skia/src/pdf/SkPDFDocument.cpp delete mode 100644 gfx/skia/skia/src/pdf/SkPDFImage.cpp delete mode 100644 gfx/skia/skia/src/pdf/SkPDFImage.h create mode 100644 gfx/skia/skia/src/pdf/SkPDFMetadata.cpp create mode 100644 gfx/skia/skia/src/pdf/SkPDFMetadata.h delete mode 100644 gfx/skia/skia/src/pdf/SkPDFPage.cpp delete mode 100644 gfx/skia/skia/src/pdf/SkPDFPage.h delete mode 100644 gfx/skia/skia/src/pdf/SkTSet.h delete mode 100644 gfx/skia/skia/src/ports/SkAtomics_sync.h delete mode 100644 gfx/skia/skia/src/ports/SkAtomics_win.h delete mode 100644 gfx/skia/skia/src/ports/SkBarriers_arm.h delete mode 100644 gfx/skia/skia/src/ports/SkBarriers_tsan.h delete mode 100644 gfx/skia/skia/src/ports/SkBarriers_x86.h delete mode 100644 gfx/skia/skia/src/ports/SkDebug_nacl.cpp delete mode 100644 gfx/skia/skia/src/ports/SkFontConfigInterface_android.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontConfigInterface_direct.h create mode 100644 gfx/skia/skia/src/ports/SkFontConfigInterface_direct_factory.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontConfigInterface_direct_google3.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontConfigInterface_direct_google3.h create mode 100644 gfx/skia/skia/src/ports/SkFontConfigInterface_direct_google3_factory.cpp delete mode 100644 gfx/skia/skia/src/ports/SkFontConfigParser_android.cpp delete mode 100644 gfx/skia/skia/src/ports/SkFontConfigParser_android.h delete mode 100644 gfx/skia/skia/src/ports/SkFontHost_android_old.cpp delete mode 100644 gfx/skia/skia/src/ports/SkFontHost_linux.cpp mode change 100755 => 100644 gfx/skia/skia/src/ports/SkFontHost_mac.cpp mode change 100755 => 100644 gfx/skia/skia/src/ports/SkFontHost_win.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_android_factory.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_android_parser.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_android_parser.h create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_custom.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_custom_directory_factory.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_custom_embedded_factory.cpp delete mode 100644 gfx/skia/skia/src/ports/SkFontMgr_default_dw.cpp delete mode 100644 gfx/skia/skia/src/ports/SkFontMgr_default_gdi.cpp rename gfx/skia/skia/src/ports/{SkFontHost_none.cpp => SkFontMgr_empty_factory.cpp} (67%) create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_fontconfig.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_fontconfig_factory.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_win_dw_factory.cpp create mode 100644 gfx/skia/skia/src/ports/SkFontMgr_win_gdi_factory.cpp create mode 100644 gfx/skia/skia/src/ports/SkImageGenerator_none.cpp create mode 100644 gfx/skia/skia/src/ports/SkImageGenerator_skia.cpp delete mode 100644 gfx/skia/skia/src/ports/SkMutex_pthread.h delete mode 100644 gfx/skia/skia/src/ports/SkMutex_win.h delete mode 100644 gfx/skia/skia/src/ports/SkOSFile_none.cpp create mode 100644 gfx/skia/skia/src/ports/SkOSLibrary.h create mode 100644 gfx/skia/skia/src/ports/SkOSLibrary_posix.cpp create mode 100644 gfx/skia/skia/src/ports/SkOSLibrary_win.cpp delete mode 100644 gfx/skia/skia/src/ports/SkXMLParser_empty.cpp create mode 100644 gfx/skia/skia/src/svg/SkSVGCanvas.cpp create mode 100644 gfx/skia/skia/src/svg/SkSVGDevice.cpp create mode 100644 gfx/skia/skia/src/svg/SkSVGDevice.h rename gfx/skia/skia/src/svg/{ => parser}/SkSVG.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGCircle.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGCircle.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGClipPath.cpp (96%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGClipPath.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGDefs.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGDefs.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGElements.cpp (94%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGElements.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGEllipse.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGEllipse.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGFeColorMatrix.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGFeColorMatrix.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGFilter.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGFilter.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGG.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGG.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGGradient.cpp (99%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGGradient.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGGroup.cpp (94%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGGroup.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGImage.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGImage.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGLine.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGLine.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGLinearGradient.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGLinearGradient.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGMask.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGMask.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGMetadata.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGMetadata.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGPaintState.cpp (98%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGParser.cpp (96%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGPath.cpp (97%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGPath.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGPolygon.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGPolygon.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGPolyline.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGPolyline.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGRadialGradient.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGRadialGradient.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGRect.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGRect.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGSVG.cpp (90%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGSVG.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGStop.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGStop.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGSymbol.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGSymbol.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGText.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGText.h (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGUse.cpp (100%) rename gfx/skia/skia/src/svg/{ => parser}/SkSVGUse.h (100%) create mode 100644 gfx/skia/skia/src/utils/SkBitmapSourceDeserializer.cpp create mode 100644 gfx/skia/skia/src/utils/SkBitmapSourceDeserializer.h delete mode 100644 gfx/skia/skia/src/utils/SkCondVar.cpp delete mode 100644 gfx/skia/skia/src/utils/SkDeferredCanvas.cpp delete mode 100644 gfx/skia/skia/src/utils/SkGatherPixelRefsAndRects.cpp delete mode 100644 gfx/skia/skia/src/utils/SkGatherPixelRefsAndRects.h create mode 100644 gfx/skia/skia/src/utils/SkImageGeneratorUtils.cpp create mode 100644 gfx/skia/skia/src/utils/SkImageGeneratorUtils.h delete mode 100644 gfx/skia/skia/src/utils/SkPDFRasterizer.cpp delete mode 100644 gfx/skia/skia/src/utils/SkPDFRasterizer.h create mode 100644 gfx/skia/skia/src/utils/SkPaintFilterCanvas.cpp create mode 100644 gfx/skia/skia/src/utils/SkPatchGrid.cpp create mode 100644 gfx/skia/skia/src/utils/SkPatchGrid.h create mode 100644 gfx/skia/skia/src/utils/SkPatchUtils.cpp create mode 100644 gfx/skia/skia/src/utils/SkPatchUtils.h delete mode 100644 gfx/skia/skia/src/utils/SkPathUtils.cpp delete mode 100644 gfx/skia/skia/src/utils/SkPictureUtils.cpp delete mode 100644 gfx/skia/skia/src/utils/SkProxyCanvas.cpp rename gfx/skia/skia/src/{core/SkInstCnt.cpp => utils/SkRunnable.h} (52%) delete mode 100644 gfx/skia/skia/src/utils/SkTLogic.h rename gfx/skia/skia/src/{views => utils}/SkTextBox.cpp (77%) create mode 100644 gfx/skia/skia/src/utils/SkTextureCompressor_Blitter.h create mode 100755 gfx/skia/skia/src/utils/SkTextureCompressor_Utils.h delete mode 100644 gfx/skia/skia/src/utils/SkThreadUtils_pthread_linux.cpp delete mode 100644 gfx/skia/skia/src/utils/SkThreadUtils_pthread_mach.cpp create mode 100644 gfx/skia/skia/src/utils/SkWhitelistChecksums.cpp create mode 100644 gfx/skia/skia/src/utils/SkWhitelistTypefaces.cpp create mode 100644 gfx/skia/skia/src/utils/android/SkAndroidSDKCanvas.cpp create mode 100644 gfx/skia/skia/src/utils/android/SkAndroidSDKCanvas.h delete mode 100755 gfx/skia/skia/src/utils/ios/SkFontHost_iOS.mm delete mode 100755 gfx/skia/skia/src/utils/ios/SkImageDecoder_iOS.mm delete mode 100755 gfx/skia/skia/src/utils/ios/SkOSFile_iOS.mm delete mode 100755 gfx/skia/skia/src/utils/ios/SkStream_NSData.mm rename gfx/skia/skia/{include/utils => src/utils/win}/SkWGL.h (100%) delete mode 100644 gfx/skia/skia/src/views/mac/SampleApp-Info.plist delete mode 100644 gfx/skia/skia/src/views/mac/SampleApp.xib delete mode 100644 gfx/skia/skia/src/views/mac/SampleAppDelegate.h delete mode 100644 gfx/skia/skia/src/views/mac/SampleAppDelegate.mm delete mode 100644 gfx/skia/skia/src/views/mac/SkOSWindow_Mac.cpp rename gfx/skia/skia/{include => src}/views/unix/XkeysToSkKeys.h (100%) rename gfx/skia/skia/{include => src}/views/unix/keysym2ucs.h (100%) delete mode 100644 gfx/skia/skia/src/xml/SkJS.cpp delete mode 100644 gfx/skia/skia/src/xml/SkJSDisplayable.cpp diff --git a/gfx/skia/skia/include/android/SkBRDAllocator.h b/gfx/skia/skia/include/android/SkBRDAllocator.h new file mode 100644 index 000000000000..3ca30c9b4119 --- /dev/null +++ b/gfx/skia/skia/include/android/SkBRDAllocator.h @@ -0,0 +1,29 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBRDAllocator_DEFINED +#define SkBRDAllocator_DEFINED + +#include "SkBitmap.h" +#include "SkCodec.h" + +/** + * Abstract subclass of SkBitmap's allocator. + * Allows the allocator to indicate if the memory it allocates + * is zero initialized. + */ +class SkBRDAllocator : public SkBitmap::Allocator { +public: + + /** + * Indicates if the memory allocated by this allocator is + * zero initialized. + */ + virtual SkCodec::ZeroInitialized zeroInit() const = 0; +}; + +#endif // SkBRDAllocator_DEFINED diff --git a/gfx/skia/skia/include/android/SkBitmapRegionDecoder.h b/gfx/skia/skia/include/android/SkBitmapRegionDecoder.h new file mode 100644 index 000000000000..575ad9dc01a1 --- /dev/null +++ b/gfx/skia/skia/include/android/SkBitmapRegionDecoder.h @@ -0,0 +1,90 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBitmapRegionDecoder_DEFINED +#define SkBitmapRegionDecoder_DEFINED + +#include "SkBitmap.h" +#include "SkBRDAllocator.h" +#include "SkEncodedFormat.h" +#include "SkStream.h" + +/* + * This class aims to provide an interface to test multiple implementations of + * SkBitmapRegionDecoder. + */ +class SkBitmapRegionDecoder { +public: + + enum Strategy { + kCanvas_Strategy, // Draw to the canvas, uses SkCodec + kAndroidCodec_Strategy, // Uses SkAndroidCodec for scaling and subsetting + }; + + /* + * @param data Refs the data while this object exists, unrefs on destruction + * @param strategy Strategy used for scaling and subsetting + * @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure + */ + static SkBitmapRegionDecoder* Create( + SkData* data, Strategy strategy); + + /* + * @param stream Takes ownership of the stream + * @param strategy Strategy used for scaling and subsetting + * @return Tries to create an SkBitmapRegionDecoder, returns NULL on failure + */ + static SkBitmapRegionDecoder* Create( + SkStreamRewindable* stream, Strategy strategy); + + /* + * Decode a scaled region of the encoded image stream + * + * @param bitmap Container for decoded pixels. It is assumed that the pixels + * are initially unallocated and will be allocated by this function. + * @param allocator Allocator for the pixels. If this is NULL, the default + * allocator (HeapAllocator) will be used. + * @param desiredSubset Subset of the original image to decode. + * @param sampleSize An integer downscaling factor for the decode. + * @param colorType Preferred output colorType. + * New implementations should return NULL if they do not support + * decoding to this color type. + * The old kOriginal_Strategy will decode to a default color type + * if this color type is unsupported. + * @param requireUnpremul If the image is not opaque, we will use this to determine the + * alpha type to use. + * + */ + virtual bool decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocator, + const SkIRect& desiredSubset, int sampleSize, + SkColorType colorType, bool requireUnpremul) = 0; + /* + * @param Requested destination color type + * @return true if we support the requested color type and false otherwise + */ + virtual bool conversionSupported(SkColorType colorType) = 0; + + virtual SkEncodedFormat getEncodedFormat() = 0; + + int width() const { return fWidth; } + int height() const { return fHeight; } + + virtual ~SkBitmapRegionDecoder() {} + +protected: + + SkBitmapRegionDecoder(int width, int height) + : fWidth(width) + , fHeight(height) + {} + +private: + const int fWidth; + const int fHeight; +}; + +#endif diff --git a/gfx/skia/skia/include/c/sk_canvas.h b/gfx/skia/skia/include/c/sk_canvas.h new file mode 100644 index 000000000000..f6c0d4e1c143 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_canvas.h @@ -0,0 +1,154 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_canvas_DEFINED +#define sk_canvas_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Save the current matrix and clip on the canvas. When the + balancing call to sk_canvas_restore() is made, the previous matrix + and clip are restored. +*/ +SK_API void sk_canvas_save(sk_canvas_t*); +/** + This behaves the same as sk_canvas_save(), but in addition it + allocates an offscreen surface. All drawing calls are directed + there, and only when the balancing call to sk_canvas_restore() is + made is that offscreen transfered to the canvas (or the previous + layer). + + @param sk_rect_t* (may be null) This rect, if non-null, is used as + a hint to limit the size of the offscreen, and + thus drawing may be clipped to it, though that + clipping is not guaranteed to happen. If exact + clipping is desired, use sk_canvas_clip_rect(). + @param sk_paint_t* (may be null) The paint is copied, and is applied + to the offscreen when sk_canvas_restore() is + called. +*/ +SK_API void sk_canvas_save_layer(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*); +/** + This call balances a previous call to sk_canvas_save() or + sk_canvas_save_layer(), and is used to remove all modifications to + the matrix and clip state since the last save call. It is an + error to call sk_canvas_restore() more times than save and + save_layer were called. +*/ +SK_API void sk_canvas_restore(sk_canvas_t*); + +/** + Preconcat the current coordinate transformation matrix with the + specified translation. +*/ +SK_API void sk_canvas_translate(sk_canvas_t*, float dx, float dy); +/** + Preconcat the current coordinate transformation matrix with the + specified scale. +*/ +SK_API void sk_canvas_scale(sk_canvas_t*, float sx, float sy); +/** + Preconcat the current coordinate transformation matrix with the + specified rotation in degrees. +*/ +SK_API void sk_canvas_rotate_degrees(sk_canvas_t*, float degrees); +/** + Preconcat the current coordinate transformation matrix with the + specified rotation in radians. +*/ +SK_API void sk_canvas_rotate_radians(sk_canvas_t*, float radians); +/** + Preconcat the current coordinate transformation matrix with the + specified skew. +*/ +SK_API void sk_canvas_skew(sk_canvas_t*, float sx, float sy); +/** + Preconcat the current coordinate transformation matrix with the + specified matrix. +*/ +SK_API void sk_canvas_concat(sk_canvas_t*, const sk_matrix_t*); + +/** + Modify the current clip with the specified rectangle. The new + current clip will be the intersection of the old clip and the + rectange. +*/ +SK_API void sk_canvas_clip_rect(sk_canvas_t*, const sk_rect_t*); +/** + Modify the current clip with the specified path. The new + current clip will be the intersection of the old clip and the + path. +*/ +SK_API void sk_canvas_clip_path(sk_canvas_t*, const sk_path_t*); + +/** + Fill the entire canvas (restricted to the current clip) with the + specified paint. +*/ +SK_API void sk_canvas_draw_paint(sk_canvas_t*, const sk_paint_t*); +/** + Draw the specified rectangle using the specified paint. The + rectangle will be filled or stroked based on the style in the + paint. +*/ +SK_API void sk_canvas_draw_rect(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*); +/** + Draw the specified oval using the specified paint. The oval will be + filled or framed based on the style in the paint +*/ +SK_API void sk_canvas_draw_oval(sk_canvas_t*, const sk_rect_t*, const sk_paint_t*); +/** + Draw the specified path using the specified paint. The path will be + filled or framed based on the style in the paint +*/ +SK_API void sk_canvas_draw_path(sk_canvas_t*, const sk_path_t*, const sk_paint_t*); +/** + Draw the specified image, with its top/left corner at (x,y), using + the specified paint, transformed by the current matrix. + + @param sk_paint_t* (may be NULL) the paint used to draw the image. +*/ +SK_API void sk_canvas_draw_image(sk_canvas_t*, const sk_image_t*, + float x, float y, const sk_paint_t*); +/** + Draw the specified image, scaling and translating so that it fills + the specified dst rect. If the src rect is non-null, only that + subset of the image is transformed and drawn. + + @param sk_paint_t* (may be NULL) The paint used to draw the image. +*/ +SK_API void sk_canvas_draw_image_rect(sk_canvas_t*, const sk_image_t*, + const sk_rect_t* src, + const sk_rect_t* dst, const sk_paint_t*); + +/** + Draw the picture into this canvas (replay the pciture's drawing commands). + + @param sk_matrix_t* If non-null, apply that matrix to the CTM when + drawing this picture. This is logically + equivalent to: save, concat, draw_picture, + restore. + + @param sk_paint_t* If non-null, draw the picture into a temporary + buffer, and then apply the paint's alpha, + colorfilter, imagefilter, and xfermode to that + buffer as it is drawn to the canvas. This is + logically equivalent to save_layer(paint), + draw_picture, restore. +*/ +SK_API void sk_canvas_draw_picture(sk_canvas_t*, const sk_picture_t*, + const sk_matrix_t*, const sk_paint_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_data.h b/gfx/skia/skia/include/c/sk_data.h new file mode 100644 index 000000000000..90333bba5f77 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_data.h @@ -0,0 +1,70 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_data_DEFINED +#define sk_data_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Returns a new empty sk_data_t. This call must be balanced with a call to + sk_data_unref(). +*/ +SK_API sk_data_t* sk_data_new_empty(); +/** + Returns a new sk_data_t by copying the specified source data. + This call must be balanced with a call to sk_data_unref(). +*/ +SK_API sk_data_t* sk_data_new_with_copy(const void* src, size_t length); +/** + Pass ownership of the given memory to a new sk_data_t, which will + call free() when the refernce count of the data goes to zero. For + example: + size_t length = 1024; + void* buffer = malloc(length); + memset(buffer, 'X', length); + sk_data_t* data = sk_data_new_from_malloc(buffer, length); + This call must be balanced with a call to sk_data_unref(). +*/ +SK_API sk_data_t* sk_data_new_from_malloc(const void* memory, size_t length); +/** + Returns a new sk_data_t using a subset of the data in the + specified source sk_data_t. This call must be balanced with a + call to sk_data_unref(). +*/ +SK_API sk_data_t* sk_data_new_subset(const sk_data_t* src, size_t offset, size_t length); + +/** + Increment the reference count on the given sk_data_t. Must be + balanced by a call to sk_data_unref(). +*/ +SK_API void sk_data_ref(const sk_data_t*); +/** + Decrement the reference count. If the reference count is 1 before + the decrement, then release both the memory holding the sk_data_t + and the memory it is managing. New sk_data_t are created with a + reference count of 1. +*/ +SK_API void sk_data_unref(const sk_data_t*); + +/** + Returns the number of bytes stored. +*/ +SK_API size_t sk_data_get_size(const sk_data_t*); +/** + Returns the pointer to the data. + */ +SK_API const void* sk_data_get_data(const sk_data_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_image.h b/gfx/skia/skia/include/c/sk_image.h new file mode 100644 index 000000000000..e90649d75d49 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_image.h @@ -0,0 +1,71 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_image_DEFINED +#define sk_image_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + * Return a new image that has made a copy of the provided pixels, or NULL on failure. + * Balance with a call to sk_image_unref(). + */ +SK_API sk_image_t* sk_image_new_raster_copy(const sk_imageinfo_t*, const void* pixels, size_t rowBytes); + +/** + * If the specified data can be interpreted as a compressed image (e.g. PNG or JPEG) then this + * returns an image. If the encoded data is not supported, returns NULL. + * + * On success, the encoded data may be processed immediately, or it may be ref()'d for later + * use. + */ +SK_API sk_image_t* sk_image_new_from_encoded(const sk_data_t* encoded, const sk_irect_t* subset); + +/** + * Encode the image's pixels and return the result as a new PNG in a + * sk_data_t, which the caller must manage: call sk_data_unref() when + * they are done. + * + * If the image type cannot be encoded, this will return NULL. + */ +SK_API sk_data_t* sk_image_encode(const sk_image_t*); + +/** + * Increment the reference count on the given sk_image_t. Must be + * balanced by a call to sk_image_unref(). +*/ +SK_API void sk_image_ref(const sk_image_t*); +/** + * Decrement the reference count. If the reference count is 1 before + * the decrement, then release both the memory holding the sk_image_t + * and the memory it is managing. New sk_image_t are created with a + reference count of 1. +*/ +SK_API void sk_image_unref(const sk_image_t*); + +/** + * Return the width of the sk_image_t/ + */ +SK_API int sk_image_get_width(const sk_image_t*); +/** + * Return the height of the sk_image_t/ + */ +SK_API int sk_image_get_height(const sk_image_t*); + +/** + * Returns a non-zero value unique among all images. + */ +SK_API uint32_t sk_image_get_unique_id(const sk_image_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_maskfilter.h b/gfx/skia/skia/include/c/sk_maskfilter.h new file mode 100644 index 000000000000..5c22a063914f --- /dev/null +++ b/gfx/skia/skia/include/c/sk_maskfilter.h @@ -0,0 +1,47 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_maskfilter_DEFINED +#define sk_maskfilter_DEFINED + +#include "sk_types.h" + +typedef enum { + NORMAL_SK_BLUR_STYLE, //!< fuzzy inside and outside + SOLID_SK_BLUR_STYLE, //!< solid inside, fuzzy outside + OUTER_SK_BLUR_STYLE, //!< nothing inside, fuzzy outside + INNER_SK_BLUR_STYLE, //!< fuzzy inside, nothing outside +} sk_blurstyle_t; + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Increment the reference count on the given sk_maskfilter_t. Must be + balanced by a call to sk_maskfilter_unref(). +*/ +void sk_maskfilter_ref(sk_maskfilter_t*); +/** + Decrement the reference count. If the reference count is 1 before + the decrement, then release both the memory holding the + sk_maskfilter_t and any other associated resources. New + sk_maskfilter_t are created with a reference count of 1. +*/ +void sk_maskfilter_unref(sk_maskfilter_t*); + +/** + Create a blur maskfilter. + @param sk_blurstyle_t The SkBlurStyle to use + @param sigma Standard deviation of the Gaussian blur to apply. Must be > 0. +*/ +sk_maskfilter_t* sk_maskfilter_new_blur(sk_blurstyle_t, float sigma); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_matrix.h b/gfx/skia/skia/include/c/sk_matrix.h new file mode 100644 index 000000000000..83f0122b00a8 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_matrix.h @@ -0,0 +1,49 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_matrix_DEFINED +#define sk_matrix_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** Set the matrix to identity */ +void sk_matrix_set_identity(sk_matrix_t*); + +/** Set the matrix to translate by (tx, ty). */ +void sk_matrix_set_translate(sk_matrix_t*, float tx, float ty); +/** + Preconcats the matrix with the specified translation. + M' = M * T(dx, dy) +*/ +void sk_matrix_pre_translate(sk_matrix_t*, float tx, float ty); +/** + Postconcats the matrix with the specified translation. + M' = T(dx, dy) * M +*/ +void sk_matrix_post_translate(sk_matrix_t*, float tx, float ty); + +/** Set the matrix to scale by sx and sy. */ +void sk_matrix_set_scale(sk_matrix_t*, float sx, float sy); +/** + Preconcats the matrix with the specified scale. + M' = M * S(sx, sy) +*/ +void sk_matrix_pre_scale(sk_matrix_t*, float sx, float sy); +/** + Postconcats the matrix with the specified scale. + M' = S(sx, sy) * M +*/ +void sk_matrix_post_scale(sk_matrix_t*, float sx, float sy); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_paint.h b/gfx/skia/skia/include/c/sk_paint.h new file mode 100644 index 000000000000..e0886ad34965 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_paint.h @@ -0,0 +1,145 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_paint_DEFINED +#define sk_paint_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Create a new paint with default settings: + antialias : false + stroke : false + stroke width : 0.0f (hairline) + stroke miter : 4.0f + stroke cap : BUTT_SK_STROKE_CAP + stroke join : MITER_SK_STROKE_JOIN + color : opaque black + shader : NULL + maskfilter : NULL + xfermode_mode : SRCOVER_SK_XFERMODE_MODE +*/ +SK_API sk_paint_t* sk_paint_new(); +/** + Release the memory storing the sk_paint_t and unref() all + associated objects. +*/ +SK_API void sk_paint_delete(sk_paint_t*); + +/** + Return true iff the paint has antialiasing enabled. +*/ +SK_API bool sk_paint_is_antialias(const sk_paint_t*); +/** + Set to true to enable antialiasing, false to disable it on this + sk_paint_t. +*/ +SK_API void sk_paint_set_antialias(sk_paint_t*, bool); + +/** + Return the paint's curent drawing color. +*/ +SK_API sk_color_t sk_paint_get_color(const sk_paint_t*); +/** + Set the paint's curent drawing color. +*/ +SK_API void sk_paint_set_color(sk_paint_t*, sk_color_t); + +/* stroke settings */ + +/** + Return true iff stroking is enabled rather than filling on this + sk_paint_t. +*/ +SK_API bool sk_paint_is_stroke(const sk_paint_t*); +/** + Set to true to enable stroking rather than filling with this + sk_paint_t. +*/ +SK_API void sk_paint_set_stroke(sk_paint_t*, bool); + +/** + Return the width for stroking. A value of 0 strokes in hairline mode. + */ +SK_API float sk_paint_get_stroke_width(const sk_paint_t*); +/** + Set the width for stroking. A value of 0 strokes in hairline mode + (always draw 1-pixel wide, regardless of the matrix). + */ +SK_API void sk_paint_set_stroke_width(sk_paint_t*, float width); + +/** + Return the paint's stroke miter value. This is used to control the + behavior of miter joins when the joins angle is sharp. +*/ +SK_API float sk_paint_get_stroke_miter(const sk_paint_t*); +/** + Set the paint's stroke miter value. This is used to control the + behavior of miter joins when the joins angle is sharp. This value + must be >= 0. +*/ +SK_API void sk_paint_set_stroke_miter(sk_paint_t*, float miter); + +typedef enum { + BUTT_SK_STROKE_CAP, + ROUND_SK_STROKE_CAP, + SQUARE_SK_STROKE_CAP +} sk_stroke_cap_t; + +/** + Return the paint's stroke cap type, controlling how the start and + end of stroked lines and paths are treated. +*/ +SK_API sk_stroke_cap_t sk_paint_get_stroke_cap(const sk_paint_t*); +/** + Set the paint's stroke cap type, controlling how the start and + end of stroked lines and paths are treated. +*/ +SK_API void sk_paint_set_stroke_cap(sk_paint_t*, sk_stroke_cap_t); + +typedef enum { + MITER_SK_STROKE_JOIN, + ROUND_SK_STROKE_JOIN, + BEVEL_SK_STROKE_JOIN +} sk_stroke_join_t; + +/** + Return the paint's stroke join type, specifies the treatment that + is applied to corners in paths and rectangles + */ +SK_API sk_stroke_join_t sk_paint_get_stroke_join(const sk_paint_t*); +/** + Set the paint's stroke join type, specifies the treatment that + is applied to corners in paths and rectangles + */ +SK_API void sk_paint_set_stroke_join(sk_paint_t*, sk_stroke_join_t); + +/** + * Set the paint's shader to the specified parameter. This will automatically call unref() on + * any previous value, and call ref() on the new value. + */ +SK_API void sk_paint_set_shader(sk_paint_t*, sk_shader_t*); + +/** + * Set the paint's maskfilter to the specified parameter. This will automatically call unref() on + * any previous value, and call ref() on the new value. + */ +SK_API void sk_paint_set_maskfilter(sk_paint_t*, sk_maskfilter_t*); + +/** + * Set the paint's xfermode to the specified parameter. + */ +SK_API void sk_paint_set_xfermode_mode(sk_paint_t*, sk_xfermode_mode_t); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_path.h b/gfx/skia/skia/include/c/sk_path.h new file mode 100644 index 000000000000..6b4e83d3b2a6 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_path.h @@ -0,0 +1,84 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_path_DEFINED +#define sk_path_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +typedef enum { + CW_SK_PATH_DIRECTION, + CCW_SK_PATH_DIRECTION, +} sk_path_direction_t; + +/** Create a new, empty path. */ +SK_API sk_path_t* sk_path_new(); +/** Release the memory used by a sk_path_t. */ +SK_API void sk_path_delete(sk_path_t*); + +/** Set the beginning of the next contour to the point (x,y). */ +SK_API void sk_path_move_to(sk_path_t*, float x, float y); +/** + Add a line from the last point to the specified point (x,y). If no + sk_path_move_to() call has been made for this contour, the first + point is automatically set to (0,0). +*/ +SK_API void sk_path_line_to(sk_path_t*, float x, float y); +/** + Add a quadratic bezier from the last point, approaching control + point (x0,y0), and ending at (x1,y1). If no sk_path_move_to() call + has been made for this contour, the first point is automatically + set to (0,0). +*/ +SK_API void sk_path_quad_to(sk_path_t*, float x0, float y0, float x1, float y1); +/** + Add a conic curve from the last point, approaching control point + (x0,y01), and ending at (x1,y1) with weight w. If no + sk_path_move_to() call has been made for this contour, the first + point is automatically set to (0,0). +*/ +SK_API void sk_path_conic_to(sk_path_t*, float x0, float y0, float x1, float y1, float w); +/** + Add a cubic bezier from the last point, approaching control points + (x0,y0) and (x1,y1), and ending at (x2,y2). If no + sk_path_move_to() call has been made for this contour, the first + point is automatically set to (0,0). +*/ +SK_API void sk_path_cubic_to(sk_path_t*, + float x0, float y0, + float x1, float y1, + float x2, float y2); +/** + Close the current contour. If the current point is not equal to the + first point of the contour, a line segment is automatically added. +*/ +SK_API void sk_path_close(sk_path_t*); + +/** + Add a closed rectangle contour to the path. +*/ +SK_API void sk_path_add_rect(sk_path_t*, const sk_rect_t*, sk_path_direction_t); +/** + Add a closed oval contour to the path +*/ +SK_API void sk_path_add_oval(sk_path_t*, const sk_rect_t*, sk_path_direction_t); + +/** + * If the path is empty, return false and set the rect parameter to [0, 0, 0, 0]. + * else return true and set the rect parameter to the bounds of the control-points + * of the path. + */ +SK_API bool sk_path_get_bounds(const sk_path_t*, sk_rect_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_picture.h b/gfx/skia/skia/include/c/sk_picture.h new file mode 100644 index 000000000000..338b7d906ac8 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_picture.h @@ -0,0 +1,70 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_picture_DEFINED +#define sk_picture_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Create a new sk_picture_recorder_t. Its resources should be + released with a call to sk_picture_recorder_delete(). +*/ +sk_picture_recorder_t* sk_picture_recorder_new(); +/** + Release the memory and other resources used by this + sk_picture_recorder_t. +*/ +void sk_picture_recorder_delete(sk_picture_recorder_t*); + +/** + Returns the canvas that records the drawing commands + + @param sk_rect_t* the cull rect used when recording this + picture. Any drawing the falls outside of this + rect is undefined, and may be drawn or it may not. +*/ +sk_canvas_t* sk_picture_recorder_begin_recording(sk_picture_recorder_t*, const sk_rect_t*); +/** + Signal that the caller is done recording. This invalidates the + canvas returned by begin_recording. Ownership of the sk_picture_t + is passed to the caller, who must call sk_picture_unref() when + they are done using it. The returned picture is immutable. +*/ +sk_picture_t* sk_picture_recorder_end_recording(sk_picture_recorder_t*); + +/** + Increment the reference count on the given sk_picture_t. Must be + balanced by a call to sk_picture_unref(). +*/ +void sk_picture_ref(sk_picture_t*); +/** + Decrement the reference count. If the reference count is 1 before + the decrement, then release both the memory holding the + sk_picture_t and any resouces it may be managing. New + sk_picture_t are created with a reference count of 1. +*/ +void sk_picture_unref(sk_picture_t*); + +/** + Returns a non-zero value unique among all pictures. + */ +uint32_t sk_picture_get_unique_id(sk_picture_t*); + +/** + Return the cull rect specified when this picture was recorded. +*/ +sk_rect_t sk_picture_get_bounds(sk_picture_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_shader.h b/gfx/skia/skia/include/c/sk_shader.h new file mode 100644 index 000000000000..702cda7fd454 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_shader.h @@ -0,0 +1,143 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_shader_DEFINED +#define sk_shader_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +void sk_shader_ref(sk_shader_t*); +void sk_shader_unref(sk_shader_t*); + +typedef enum { + CLAMP_SK_SHADER_TILEMODE, + REPEAT_SK_SHADER_TILEMODE, + MIRROR_SK_SHADER_TILEMODE, +} sk_shader_tilemode_t; + +/** + Returns a shader that generates a linear gradient between the two + specified points. + + @param points The start and end points for the gradient. + @param colors The array[count] of colors, to be distributed between + the two points + @param colorPos May be NULL. array[count] of SkScalars, or NULL, of + the relative position of each corresponding color + in the colors array. If this is NULL, the the + colors are distributed evenly between the start + and end point. If this is not null, the values + must begin with 0, end with 1.0, and intermediate + values must be strictly increasing. + @param colorCount Must be >=2. The number of colors (and pos if not + NULL) entries. + @param mode The tiling mode +*/ +sk_shader_t* sk_shader_new_linear_gradient(const sk_point_t points[2], + const sk_color_t colors[], + const float colorPos[], + int colorCount, + sk_shader_tilemode_t tileMode, + const sk_matrix_t* localMatrix); + + +/** + Returns a shader that generates a radial gradient given the center + and radius. + + @param center The center of the circle for this gradient + @param radius Must be positive. The radius of the circle for this + gradient + @param colors The array[count] of colors, to be distributed + between the center and edge of the circle + @param colorPos May be NULL. The array[count] of the relative + position of each corresponding color in the colors + array. If this is NULL, the the colors are + distributed evenly between the center and edge of + the circle. If this is not null, the values must + begin with 0, end with 1.0, and intermediate + values must be strictly increasing. + @param count Must be >= 2. The number of colors (and pos if not + NULL) entries + @param tileMode The tiling mode + @param localMatrix May be NULL +*/ +sk_shader_t* sk_shader_new_radial_gradient(const sk_point_t* center, + float radius, + const sk_color_t colors[], + const float colorPos[], + int colorCount, + sk_shader_tilemode_t tileMode, + const sk_matrix_t* localMatrix); + +/** + Returns a shader that generates a sweep gradient given a center. + + @param center The coordinates of the center of the sweep + @param colors The array[count] of colors, to be distributed around + the center. + @param colorPos May be NULL. The array[count] of the relative + position of each corresponding color in the colors + array. If this is NULL, the the colors are + distributed evenly between the center and edge of + the circle. If this is not null, the values must + begin with 0, end with 1.0, and intermediate + values must be strictly increasing. + @param colorCount Must be >= 2. The number of colors (and pos if + not NULL) entries + @param localMatrix May be NULL +*/ +sk_shader_t* sk_shader_new_sweep_gradient(const sk_point_t* center, + const sk_color_t colors[], + const float colorPos[], + int colorCount, + const sk_matrix_t* localMatrix); + +/** + Returns a shader that generates a conical gradient given two circles, or + returns NULL if the inputs are invalid. The gradient interprets the + two circles according to the following HTML spec. + http://dev.w3.org/html5/2dcontext/#dom-context-2d-createradialgradient + + Returns a shader that generates a sweep gradient given a center. + + @param start, startRadius Defines the first circle. + @param end, endRadius Defines the first circle. + @param colors The array[count] of colors, to be distributed between + the two circles. + @param colorPos May be NULL. The array[count] of the relative + position of each corresponding color in the colors + array. If this is NULL, the the colors are + distributed evenly between the two circles. If + this is not null, the values must begin with 0, + end with 1.0, and intermediate values must be + strictly increasing. + @param colorCount Must be >= 2. The number of colors (and pos if + not NULL) entries + @param tileMode The tiling mode + @param localMatrix May be NULL + +*/ +sk_shader_t* sk_shader_new_two_point_conical_gradient( + const sk_point_t* start, + float startRadius, + const sk_point_t* end, + float endRadius, + const sk_color_t colors[], + const float colorPos[], + int colorCount, + sk_shader_tilemode_t tileMode, + const sk_matrix_t* localMatrix); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_surface.h b/gfx/skia/skia/include/c/sk_surface.h new file mode 100644 index 000000000000..d634185eec5c --- /dev/null +++ b/gfx/skia/skia/include/c/sk_surface.h @@ -0,0 +1,73 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_surface_DEFINED +#define sk_surface_DEFINED + +#include "sk_types.h" + +SK_C_PLUS_PLUS_BEGIN_GUARD + +/** + Return a new surface, with the memory for the pixels automatically + allocated. If the requested surface cannot be created, or the + request is not a supported configuration, NULL will be returned. + + @param sk_imageinfo_t* Specify the width, height, color type, and + alpha type for the surface. + + @param sk_surfaceprops_t* If not NULL, specify additional non-default + properties of the surface. +*/ +SK_API sk_surface_t* sk_surface_new_raster(const sk_imageinfo_t*, const sk_surfaceprops_t*); + +/** + Create a new surface which will draw into the specified pixels + with the specified rowbytes. If the requested surface cannot be + created, or the request is not a supported configuration, NULL + will be returned. + + @param sk_imageinfo_t* Specify the width, height, color type, and + alpha type for the surface. + @param void* pixels Specify the location in memory where the + destination pixels are. This memory must + outlast this surface. + @param size_t rowBytes Specify the difference, in bytes, between + each adjacent row. Should be at least + (width * sizeof(one pixel)). + @param sk_surfaceprops_t* If not NULL, specify additional non-default + properties of the surface. +*/ +SK_API sk_surface_t* sk_surface_new_raster_direct(const sk_imageinfo_t*, + void* pixels, size_t rowBytes, + const sk_surfaceprops_t* props); + +/** + Decrement the reference count. If the reference count is 1 before + the decrement, then release both the memory holding the + sk_surface_t and any pixel memory it may be managing. New + sk_surface_t are created with a reference count of 1. +*/ +SK_API void sk_surface_unref(sk_surface_t*); + +/** + * Return the canvas associated with this surface. Note: the canvas is owned by the surface, + * so the returned object is only valid while the owning surface is valid. + */ +SK_API sk_canvas_t* sk_surface_get_canvas(sk_surface_t*); + +/** + * Call sk_image_unref() when the returned image is no longer used. + */ +SK_API sk_image_t* sk_surface_new_image_snapshot(sk_surface_t*); + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/c/sk_types.h b/gfx/skia/skia/include/c/sk_types.h new file mode 100644 index 000000000000..41dd2715b064 --- /dev/null +++ b/gfx/skia/skia/include/c/sk_types.h @@ -0,0 +1,205 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +// EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL +// DO NOT USE -- FOR INTERNAL TESTING ONLY + +#ifndef sk_types_DEFINED +#define sk_types_DEFINED + +#include +#include + +#ifdef __cplusplus + #define SK_C_PLUS_PLUS_BEGIN_GUARD extern "C" { + #define SK_C_PLUS_PLUS_END_GUARD } +#else + #include + #define SK_C_PLUS_PLUS_BEGIN_GUARD + #define SK_C_PLUS_PLUS_END_GUARD +#endif + +#ifndef SK_API +#define SK_API +#endif + +/////////////////////////////////////////////////////////////////////////////////////// + +SK_C_PLUS_PLUS_BEGIN_GUARD + +typedef uint32_t sk_color_t; + +/* This macro assumes all arguments are >=0 and <=255. */ +#define sk_color_set_argb(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#define sk_color_get_a(c) (((c) >> 24) & 0xFF) +#define sk_color_get_r(c) (((c) >> 16) & 0xFF) +#define sk_color_get_g(c) (((c) >> 8) & 0xFF) +#define sk_color_get_b(c) (((c) >> 0) & 0xFF) + +typedef enum { + UNKNOWN_SK_COLORTYPE, + RGBA_8888_SK_COLORTYPE, + BGRA_8888_SK_COLORTYPE, + ALPHA_8_SK_COLORTYPE, +} sk_colortype_t; + +typedef enum { + OPAQUE_SK_ALPHATYPE, + PREMUL_SK_ALPHATYPE, + UNPREMUL_SK_ALPHATYPE, +} sk_alphatype_t; + +typedef enum { + INTERSECT_SK_CLIPTYPE, + DIFFERENCE_SK_CLIPTYPE, +} sk_cliptype_t; + +typedef enum { + UNKNOWN_SK_PIXELGEOMETRY, + RGB_H_SK_PIXELGEOMETRY, + BGR_H_SK_PIXELGEOMETRY, + RGB_V_SK_PIXELGEOMETRY, + BGR_V_SK_PIXELGEOMETRY, +} sk_pixelgeometry_t; + +/** + Return the default sk_colortype_t; this is operating-system dependent. +*/ +SK_API sk_colortype_t sk_colortype_get_default_8888(); + +typedef struct { + int32_t width; + int32_t height; + sk_colortype_t colorType; + sk_alphatype_t alphaType; +} sk_imageinfo_t; + +typedef struct { + sk_pixelgeometry_t pixelGeometry; +} sk_surfaceprops_t; + +typedef struct { + float x; + float y; +} sk_point_t; + +typedef struct { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +} sk_irect_t; + +typedef struct { + float left; + float top; + float right; + float bottom; +} sk_rect_t; + +typedef struct { + float mat[9]; +} sk_matrix_t; + +/** + A sk_canvas_t encapsulates all of the state about drawing into a + destination This includes a reference to the destination itself, + and a stack of matrix/clip values. +*/ +typedef struct sk_canvas_t sk_canvas_t; +/** + A sk_data_ holds an immutable data buffer. +*/ +typedef struct sk_data_t sk_data_t; +/** + A sk_image_t is an abstraction for drawing a rectagle of pixels. + The content of the image is always immutable, though the actual + storage may change, if for example that image can be re-created via + encoded data or other means. +*/ +typedef struct sk_image_t sk_image_t; +/** + A sk_maskfilter_t is an object that perform transformations on an + alpha-channel mask before drawing it; it may be installed into a + sk_paint_t. Each time a primitive is drawn, it is first + scan-converted into a alpha mask, which os handed to the + maskfilter, which may create a new mask is to render into the + destination. + */ +typedef struct sk_maskfilter_t sk_maskfilter_t; +/** + A sk_paint_t holds the style and color information about how to + draw geometries, text and bitmaps. +*/ +typedef struct sk_paint_t sk_paint_t; +/** + A sk_path_t encapsulates compound (multiple contour) geometric + paths consisting of straight line segments, quadratic curves, and + cubic curves. +*/ +typedef struct sk_path_t sk_path_t; +/** + A sk_picture_t holds recorded canvas drawing commands to be played + back at a later time. +*/ +typedef struct sk_picture_t sk_picture_t; +/** + A sk_picture_recorder_t holds a sk_canvas_t that records commands + to create a sk_picture_t. +*/ +typedef struct sk_picture_recorder_t sk_picture_recorder_t; +/** + A sk_shader_t specifies the source color(s) for what is being drawn. If a + paint has no shader, then the paint's color is used. If the paint + has a shader, then the shader's color(s) are use instead, but they + are modulated by the paint's alpha. +*/ +typedef struct sk_shader_t sk_shader_t; +/** + A sk_surface_t holds the destination for drawing to a canvas. For + raster drawing, the destination is an array of pixels in memory. + For GPU drawing, the destination is a texture or a framebuffer. +*/ +typedef struct sk_surface_t sk_surface_t; + +typedef enum { + CLEAR_SK_XFERMODE_MODE, + SRC_SK_XFERMODE_MODE, + DST_SK_XFERMODE_MODE, + SRCOVER_SK_XFERMODE_MODE, + DSTOVER_SK_XFERMODE_MODE, + SRCIN_SK_XFERMODE_MODE, + DSTIN_SK_XFERMODE_MODE, + SRCOUT_SK_XFERMODE_MODE, + DSTOUT_SK_XFERMODE_MODE, + SRCATOP_SK_XFERMODE_MODE, + DSTATOP_SK_XFERMODE_MODE, + XOR_SK_XFERMODE_MODE, + PLUS_SK_XFERMODE_MODE, + MODULATE_SK_XFERMODE_MODE, + SCREEN_SK_XFERMODE_MODE, + OVERLAY_SK_XFERMODE_MODE, + DARKEN_SK_XFERMODE_MODE, + LIGHTEN_SK_XFERMODE_MODE, + COLORDODGE_SK_XFERMODE_MODE, + COLORBURN_SK_XFERMODE_MODE, + HARDLIGHT_SK_XFERMODE_MODE, + SOFTLIGHT_SK_XFERMODE_MODE, + DIFFERENCE_SK_XFERMODE_MODE, + EXCLUSION_SK_XFERMODE_MODE, + MULTIPLY_SK_XFERMODE_MODE, + HUE_SK_XFERMODE_MODE, + SATURATION_SK_XFERMODE_MODE, + COLOR_SK_XFERMODE_MODE, + LUMINOSITY_SK_XFERMODE_MODE, +} sk_xfermode_mode_t; + +////////////////////////////////////////////////////////////////////////////////////////// + +SK_C_PLUS_PLUS_END_GUARD + +#endif diff --git a/gfx/skia/skia/include/codec/SkAndroidCodec.h b/gfx/skia/skia/include/codec/SkAndroidCodec.h new file mode 100644 index 000000000000..f979886a43ec --- /dev/null +++ b/gfx/skia/skia/include/codec/SkAndroidCodec.h @@ -0,0 +1,230 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkAndroidCodec_DEFINED +#define SkAndroidCodec_DEFINED + +#include "SkCodec.h" +#include "SkEncodedFormat.h" +#include "SkStream.h" +#include "SkTypes.h" + +/** + * Abstract interface defining image codec functionality that is necessary for + * Android. + */ +class SkAndroidCodec : SkNoncopyable { +public: + /** + * If this stream represents an encoded image that we know how to decode, + * return an SkAndroidCodec that can decode it. Otherwise return NULL. + * + * The SkPngChunkReader handles unknown chunks in PNGs. + * See SkCodec.h for more details. + * + * If NULL is returned, the stream is deleted immediately. Otherwise, the + * SkCodec takes ownership of it, and will delete it when done with it. + */ + static SkAndroidCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL); + + /** + * If this data represents an encoded image that we know how to decode, + * return an SkAndroidCodec that can decode it. Otherwise return NULL. + * + * The SkPngChunkReader handles unknown chunks in PNGs. + * See SkCodec.h for more details. + * + * Will take a ref if it returns a codec, else will not affect the data. + */ + static SkAndroidCodec* NewFromData(SkData*, SkPngChunkReader* = NULL); + + virtual ~SkAndroidCodec() {} + + + const SkImageInfo& getInfo() const { return fInfo; } + + /** + * Format of the encoded data. + */ + SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); } + + /** + * Returns the dimensions of the scaled output image, for an input + * sampleSize. + * + * When the sample size divides evenly into the original dimensions, the + * scaled output dimensions will simply be equal to the original + * dimensions divided by the sample size. + * + * When the sample size does not divide even into the original + * dimensions, the codec may round up or down, depending on what is most + * efficient to decode. + * + * Finally, the codec will always recommend a non-zero output, so the output + * dimension will always be one if the sampleSize is greater than the + * original dimension. + */ + SkISize getSampledDimensions(int sampleSize) const; + + /** + * Return (via desiredSubset) a subset which can decoded from this codec, + * or false if the input subset is invalid. + * + * @param desiredSubset in/out parameter + * As input, a desired subset of the original bounds + * (as specified by getInfo). + * As output, if true is returned, desiredSubset may + * have been modified to a subset which is + * supported. Although a particular change may have + * been made to desiredSubset to create something + * supported, it is possible other changes could + * result in a valid subset. If false is returned, + * desiredSubset's value is undefined. + * @return true If the input desiredSubset is valid. + * desiredSubset may be modified to a subset + * supported by the codec. + * false If desiredSubset is invalid (NULL or not fully + * contained within the image). + */ + bool getSupportedSubset(SkIRect* desiredSubset) const; + // TODO: Rename SkCodec::getValidSubset() to getSupportedSubset() + + /** + * Returns the dimensions of the scaled, partial output image, for an + * input sampleSize and subset. + * + * @param sampleSize Factor to scale down by. + * @param subset Must be a valid subset of the original image + * dimensions and a subset supported by SkAndroidCodec. + * getSubset() can be used to obtain a subset supported + * by SkAndroidCodec. + * @return Size of the scaled partial image. Or zero size + * if either of the inputs is invalid. + */ + SkISize getSampledSubsetDimensions(int sampleSize, const SkIRect& subset) const; + + /** + * Additional options to pass to getAndroidPixels(). + */ + // FIXME: It's a bit redundant to name these AndroidOptions when this class is already + // called SkAndroidCodec. On the other hand, it's may be a bit confusing to call + // these Options when SkCodec has a slightly different set of Options. Maybe these + // should be DecodeOptions or SamplingOptions? + struct AndroidOptions { + AndroidOptions() + : fZeroInitialized(SkCodec::kNo_ZeroInitialized) + , fSubset(nullptr) + , fColorPtr(nullptr) + , fColorCount(nullptr) + , fSampleSize(1) + {} + + /** + * Indicates is destination pixel memory is zero initialized. + */ + SkCodec::ZeroInitialized fZeroInitialized; + + /** + * If not NULL, represents a subset of the original image to decode. + * + * Must be within the bounds returned by getInfo(). + * + * If the EncodedFormat is kWEBP_SkEncodedFormat, the top and left + * values must be even. + */ + SkIRect* fSubset; + + /** + * If the client has requested a decode to kIndex8_SkColorType + * (specified in the SkImageInfo), then the caller must provide + * storage for up to 256 SkPMColor values in fColorPtr. On success, + * the codec must copy N colors into that storage, (where N is the + * logical number of table entries) and set fColorCount to N. + * + * If the client does not request kIndex8_SkColorType, then the last + * two parameters may be NULL. If fColorCount is not null, it will be + * set to 0. + */ + SkPMColor* fColorPtr; + int* fColorCount; + + /** + * The client may provide an integer downscale factor for the decode. + * The codec may implement this downscaling by sampling or another + * method if it is more efficient. + */ + int fSampleSize; + }; + + /** + * Decode into the given pixels, a block of memory of size at + * least (info.fHeight - 1) * rowBytes + (info.fWidth * + * bytesPerPixel) + * + * Repeated calls to this function should give the same results, + * allowing the PixelRef to be immutable. + * + * @param info A description of the format (config, size) + * expected by the caller. This can simply be identical + * to the info returned by getInfo(). + * + * This contract also allows the caller to specify + * different output-configs, which the implementation can + * decide to support or not. + * + * A size that does not match getInfo() implies a request + * to scale or subset. If the codec cannot perform this + * scaling or subsetting, it will return an error code. + * + * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 + * SkPMColor values in options->fColorPtr. On success the codec must copy N colors into + * that storage, (where N is the logical number of table entries) and set + * options->fColorCount to N. + * + * If info is not kIndex8_SkColorType, options->fColorPtr and options->fColorCount may + * be nullptr. + * + * The AndroidOptions object is also used to specify any requested scaling or subsetting + * using options->fSampleSize and options->fSubset. + * + * @return Result kSuccess, or another value explaining the type of failure. + */ + // FIXME: It's a bit redundant to name this getAndroidPixels() when this class is already + // called SkAndroidCodec. On the other hand, it's may be a bit confusing to call + // this getPixels() when it is a slightly different API than SkCodec's getPixels(). + // Maybe this should be decode() or decodeSubset()? + SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, + const AndroidOptions* options); + + /** + * Simplified version of getAndroidPixels() where we supply the default AndroidOptions. + * + * This will return an error if the info is kIndex_8_SkColorType and also will not perform + * any scaling or subsetting. + */ + SkCodec::Result getAndroidPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); + +protected: + + SkAndroidCodec(const SkImageInfo&); + + virtual SkEncodedFormat onGetEncodedFormat() const = 0; + + virtual SkISize onGetSampledDimensions(int sampleSize) const = 0; + + virtual bool onGetSupportedSubset(SkIRect* desiredSubset) const = 0; + + virtual SkCodec::Result onGetAndroidPixels(const SkImageInfo& info, void* pixels, + size_t rowBytes, const AndroidOptions& options) = 0; + +private: + + // This will always be a reference to the info that is contained by the + // embedded SkCodec. + const SkImageInfo& fInfo; +}; +#endif // SkAndroidCodec_DEFINED diff --git a/gfx/skia/skia/include/codec/SkCodec.h b/gfx/skia/skia/include/codec/SkCodec.h new file mode 100644 index 000000000000..9f28af010edf --- /dev/null +++ b/gfx/skia/skia/include/codec/SkCodec.h @@ -0,0 +1,614 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkCodec_DEFINED +#define SkCodec_DEFINED + +#include "../private/SkTemplates.h" +#include "SkColor.h" +#include "SkEncodedFormat.h" +#include "SkImageInfo.h" +#include "SkSize.h" +#include "SkStream.h" +#include "SkTypes.h" + +class SkData; +class SkPngChunkReader; +class SkSampler; + +/** + * Abstraction layer directly on top of an image codec. + */ +class SkCodec : SkNoncopyable { +public: + /** + * If this stream represents an encoded image that we know how to decode, + * return an SkCodec that can decode it. Otherwise return NULL. + * + * If the SkPngChunkReader is not NULL then: + * If the image is not a PNG, the SkPngChunkReader will be ignored. + * If the image is a PNG, the SkPngChunkReader will be reffed. + * If the PNG has unknown chunks, the SkPngChunkReader will be used + * to handle these chunks. SkPngChunkReader will be called to read + * any unknown chunk at any point during the creation of the codec + * or the decode. Note that if SkPngChunkReader fails to read a + * chunk, this could result in a failure to create the codec or a + * failure to decode the image. + * If the PNG does not contain unknown chunks, the SkPngChunkReader + * will not be used or modified. + * + * If NULL is returned, the stream is deleted immediately. Otherwise, the + * SkCodec takes ownership of it, and will delete it when done with it. + */ + static SkCodec* NewFromStream(SkStream*, SkPngChunkReader* = NULL); + + /** + * If this data represents an encoded image that we know how to decode, + * return an SkCodec that can decode it. Otherwise return NULL. + * + * If the SkPngChunkReader is not NULL then: + * If the image is not a PNG, the SkPngChunkReader will be ignored. + * If the image is a PNG, the SkPngChunkReader will be reffed. + * If the PNG has unknown chunks, the SkPngChunkReader will be used + * to handle these chunks. SkPngChunkReader will be called to read + * any unknown chunk at any point during the creation of the codec + * or the decode. Note that if SkPngChunkReader fails to read a + * chunk, this could result in a failure to create the codec or a + * failure to decode the image. + * If the PNG does not contain unknown chunks, the SkPngChunkReader + * will not be used or modified. + * + * Will take a ref if it returns a codec, else will not affect the data. + */ + static SkCodec* NewFromData(SkData*, SkPngChunkReader* = NULL); + + virtual ~SkCodec(); + + /** + * Return the ImageInfo associated with this codec. + */ + const SkImageInfo& getInfo() const { return fSrcInfo; } + + /** + * Return a size that approximately supports the desired scale factor. + * The codec may not be able to scale efficiently to the exact scale + * factor requested, so return a size that approximates that scale. + * The returned value is the codec's suggestion for the closest valid + * scale that it can natively support + */ + SkISize getScaledDimensions(float desiredScale) const { + // Negative and zero scales are errors. + SkASSERT(desiredScale > 0.0f); + if (desiredScale <= 0.0f) { + return SkISize::Make(0, 0); + } + + // Upscaling is not supported. Return the original size if the client + // requests an upscale. + if (desiredScale >= 1.0f) { + return this->getInfo().dimensions(); + } + return this->onGetScaledDimensions(desiredScale); + } + + /** + * Return (via desiredSubset) a subset which can decoded from this codec, + * or false if this codec cannot decode subsets or anything similar to + * desiredSubset. + * + * @param desiredSubset In/out parameter. As input, a desired subset of + * the original bounds (as specified by getInfo). If true is returned, + * desiredSubset may have been modified to a subset which is + * supported. Although a particular change may have been made to + * desiredSubset to create something supported, it is possible other + * changes could result in a valid subset. + * If false is returned, desiredSubset's value is undefined. + * @return true if this codec supports decoding desiredSubset (as + * returned, potentially modified) + */ + bool getValidSubset(SkIRect* desiredSubset) const { + return this->onGetValidSubset(desiredSubset); + } + + /** + * Format of the encoded data. + */ + SkEncodedFormat getEncodedFormat() const { return this->onGetEncodedFormat(); } + + /** + * Used to describe the result of a call to getPixels(). + * + * Result is the union of possible results from subclasses. + */ + enum Result { + /** + * General return value for success. + */ + kSuccess, + /** + * The input is incomplete. A partial image was generated. + */ + kIncompleteInput, + /** + * The generator cannot convert to match the request, ignoring + * dimensions. + */ + kInvalidConversion, + /** + * The generator cannot scale to requested size. + */ + kInvalidScale, + /** + * Parameters (besides info) are invalid. e.g. NULL pixels, rowBytes + * too small, etc. + */ + kInvalidParameters, + /** + * The input did not contain a valid image. + */ + kInvalidInput, + /** + * Fulfilling this request requires rewinding the input, which is not + * supported for this input. + */ + kCouldNotRewind, + /** + * This method is not implemented by this codec. + * FIXME: Perhaps this should be kUnsupported? + */ + kUnimplemented, + }; + + /** + * Whether or not the memory passed to getPixels is zero initialized. + */ + enum ZeroInitialized { + /** + * The memory passed to getPixels is zero initialized. The SkCodec + * may take advantage of this by skipping writing zeroes. + */ + kYes_ZeroInitialized, + /** + * The memory passed to getPixels has not been initialized to zero, + * so the SkCodec must write all zeroes to memory. + * + * This is the default. It will be used if no Options struct is used. + */ + kNo_ZeroInitialized, + }; + + /** + * Additional options to pass to getPixels. + */ + struct Options { + Options() + : fZeroInitialized(kNo_ZeroInitialized) + , fSubset(NULL) + {} + + ZeroInitialized fZeroInitialized; + /** + * If not NULL, represents a subset of the original image to decode. + * Must be within the bounds returned by getInfo(). + * If the EncodedFormat is kWEBP_SkEncodedFormat (the only one which + * currently supports subsets), the top and left values must be even. + * + * In getPixels, we will attempt to decode the exact rectangular + * subset specified by fSubset. + * + * In a scanline decode, it does not make sense to specify a subset + * top or subset height, since the client already controls which rows + * to get and which rows to skip. During scanline decodes, we will + * require that the subset top be zero and the subset height be equal + * to the full height. We will, however, use the values of + * subset left and subset width to decode partial scanlines on calls + * to getScanlines(). + */ + SkIRect* fSubset; + }; + + /** + * Decode into the given pixels, a block of memory of size at + * least (info.fHeight - 1) * rowBytes + (info.fWidth * + * bytesPerPixel) + * + * Repeated calls to this function should give the same results, + * allowing the PixelRef to be immutable. + * + * @param info A description of the format (config, size) + * expected by the caller. This can simply be identical + * to the info returned by getInfo(). + * + * This contract also allows the caller to specify + * different output-configs, which the implementation can + * decide to support or not. + * + * A size that does not match getInfo() implies a request + * to scale. If the generator cannot perform this scale, + * it will return kInvalidScale. + * + * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 + * SkPMColor values in ctable. On success the generator must copy N colors into that storage, + * (where N is the logical number of table entries) and set ctableCount to N. + * + * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount + * is not null, it will be set to 0. + * + * If a scanline decode is in progress, scanline mode will end, requiring the client to call + * startScanlineDecode() in order to return to decoding scanlines. + * + * @return Result kSuccess, or another value explaining the type of failure. + */ + Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options*, + SkPMColor ctable[], int* ctableCount); + + /** + * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and + * uses the default Options. + */ + Result getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); + + /** + * Some images may initially report that they have alpha due to the format + * of the encoded data, but then never use any colors which have alpha + * less than 100%. This function can be called *after* decoding to + * determine if such an image truly had alpha. Calling it before decoding + * is undefined. + * FIXME: see skbug.com/3582. + */ + bool reallyHasAlpha() const { + return this->onReallyHasAlpha(); + } + + /** + * The remaining functions revolve around decoding scanlines. + */ + + /** + * Prepare for a scanline decode with the specified options. + * + * After this call, this class will be ready to decode the first scanline. + * + * This must be called in order to call getScanlines or skipScanlines. + * + * This may require rewinding the stream. + * + * Not all SkCodecs support this. + * + * @param dstInfo Info of the destination. If the dimensions do not match + * those of getInfo, this implies a scale. + * @param options Contains decoding options, including if memory is zero + * initialized. + * @param ctable A pointer to a color table. When dstInfo.colorType() is + * kIndex8, this should be non-NULL and have enough storage for 256 + * colors. The color table will be populated after decoding the palette. + * @param ctableCount A pointer to the size of the color table. When + * dstInfo.colorType() is kIndex8, this should be non-NULL. It will + * be modified to the true size of the color table (<= 256) after + * decoding the palette. + * @return Enum representing success or reason for failure. + */ + Result startScanlineDecode(const SkImageInfo& dstInfo, const SkCodec::Options* options, + SkPMColor ctable[], int* ctableCount); + + /** + * Simplified version of startScanlineDecode() that asserts that info is NOT + * kIndex8_SkColorType and uses the default Options. + */ + Result startScanlineDecode(const SkImageInfo& dstInfo); + + /** + * Write the next countLines scanlines into dst. + * + * Not valid to call before calling startScanlineDecode(). + * + * @param dst Must be non-null, and large enough to hold countLines + * scanlines of size rowBytes. + * @param countLines Number of lines to write. + * @param rowBytes Number of bytes per row. Must be large enough to hold + * a scanline based on the SkImageInfo used to create this object. + * @return the number of lines successfully decoded. If this value is + * less than countLines, this will fill the remaining lines with a + * default value. + */ + int getScanlines(void* dst, int countLines, size_t rowBytes); + + /** + * Skip count scanlines. + * + * Not valid to call before calling startScanlineDecode(). + * + * The default version just calls onGetScanlines and discards the dst. + * NOTE: If skipped lines are the only lines with alpha, this default + * will make reallyHasAlpha return true, when it could have returned + * false. + * + * @return true if the scanlines were successfully skipped + * false on failure, possible reasons for failure include: + * An incomplete input image stream. + * Calling this function before calling startScanlineDecode(). + * If countLines is less than zero or so large that it moves + * the current scanline past the end of the image. + */ + bool skipScanlines(int countLines); + + /** + * The order in which rows are output from the scanline decoder is not the + * same for all variations of all image types. This explains the possible + * output row orderings. + */ + enum SkScanlineOrder { + /* + * By far the most common, this indicates that the image can be decoded + * reliably using the scanline decoder, and that rows will be output in + * the logical order. + */ + kTopDown_SkScanlineOrder, + + /* + * This indicates that the scanline decoder reliably outputs rows, but + * they will be returned in reverse order. If the scanline format is + * kBottomUp, the nextScanline() API can be used to determine the actual + * y-coordinate of the next output row, but the client is not forced + * to take advantage of this, given that it's not too tough to keep + * track independently. + * + * For full image decodes, it is safe to get all of the scanlines at + * once, since the decoder will handle inverting the rows as it + * decodes. + * + * For subset decodes and sampling, it is simplest to get and skip + * scanlines one at a time, using the nextScanline() API. It is + * possible to ask for larger chunks at a time, but this should be used + * with caution. As with full image decodes, the decoder will handle + * inverting the requested rows, but rows will still be delivered + * starting from the bottom of the image. + * + * Upside down bmps are an example. + */ + kBottomUp_SkScanlineOrder, + + /* + * This indicates that the scanline decoder reliably outputs rows, but + * they will not be in logical order. If the scanline format is + * kOutOfOrder, the nextScanline() API should be used to determine the + * actual y-coordinate of the next output row. + * + * For this scanline ordering, it is advisable to get and skip + * scanlines one at a time. + * + * Interlaced gifs are an example. + */ + kOutOfOrder_SkScanlineOrder, + + /* + * Indicates that the entire image must be decoded in order to output + * any amount of scanlines. In this case, it is a REALLY BAD IDEA to + * request scanlines 1-by-1 or in small chunks. The client should + * determine which scanlines are needed and ask for all of them in + * a single call to getScanlines(). + * + * Interlaced pngs are an example. + */ + kNone_SkScanlineOrder, + }; + + /** + * An enum representing the order in which scanlines will be returned by + * the scanline decoder. + */ + SkScanlineOrder getScanlineOrder() const { return this->onGetScanlineOrder(); } + + /** + * Returns the y-coordinate of the next row to be returned by the scanline + * decoder. + * + * This will equal fCurrScanline, except in the case of strangely + * encoded image types (bottom-up bmps, interlaced gifs). + * + * Results are undefined when not in scanline decoding mode. + */ + int nextScanline() const { return this->outputScanline(fCurrScanline); } + + /** + * Returns the output y-coordinate of the row that corresponds to an input + * y-coordinate. The input y-coordinate represents where the scanline + * is located in the encoded data. + * + * This will equal inputScanline, except in the case of strangely + * encoded image types (bottom-up bmps, interlaced gifs). + */ + int outputScanline(int inputScanline) const; + +protected: + SkCodec(const SkImageInfo&, SkStream*); + + virtual SkISize onGetScaledDimensions(float /* desiredScale */) const { + // By default, scaling is not supported. + return this->getInfo().dimensions(); + } + + // FIXME: What to do about subsets?? + /** + * Subclasses should override if they support dimensions other than the + * srcInfo's. + */ + virtual bool onDimensionsSupported(const SkISize&) { + return false; + } + + virtual SkEncodedFormat onGetEncodedFormat() const = 0; + + /** + * @param rowsDecoded When the encoded image stream is incomplete, this function + * will return kIncompleteInput and rowsDecoded will be set to + * the number of scanlines that were successfully decoded. + * This will allow getPixels() to fill the uninitialized memory. + */ + virtual Result onGetPixels(const SkImageInfo& info, + void* pixels, size_t rowBytes, const Options&, + SkPMColor ctable[], int* ctableCount, + int* rowsDecoded) = 0; + + virtual bool onGetValidSubset(SkIRect* /* desiredSubset */) const { + // By default, subsets are not supported. + return false; + } + + virtual bool onReallyHasAlpha() const { return false; } + + /** + * If the stream was previously read, attempt to rewind. + * + * If the stream needed to be rewound, call onRewind. + * @returns true if the codec is at the right position and can be used. + * false if there was a failure to rewind. + * + * This is called by getPixels() and start(). Subclasses may call if they + * need to rewind at another time. + */ + bool SK_WARN_UNUSED_RESULT rewindIfNeeded(); + + /** + * Called by rewindIfNeeded, if the stream needed to be rewound. + * + * Subclasses should do any set up needed after a rewind. + */ + virtual bool onRewind() { + return true; + } + + /** + * On an incomplete input, getPixels() and getScanlines() will fill any uninitialized + * scanlines. This allows the subclass to indicate what value to fill with. + * + * @param colorType Destination color type. + * @param alphaType Destination alpha type. + * @return The value with which to fill uninitialized pixels. + * + * Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color, + * an 8-bit gray color, or an 8-bit index into a color table, depending on the color + * type. + */ + uint32_t getFillValue(SkColorType colorType, SkAlphaType alphaType) const { + return this->onGetFillValue(colorType, alphaType); + } + + /** + * Some subclasses will override this function, but this is a useful default for the color + * types that we support. Note that for color types that do not use the full 32-bits, + * we will simply take the low bits of the fill value. + * + * kN32_SkColorType: Transparent or Black + * kRGB_565_SkColorType: Black + * kGray_8_SkColorType: Black + * kIndex_8_SkColorType: First color in color table + */ + virtual uint32_t onGetFillValue(SkColorType /*colorType*/, SkAlphaType alphaType) const { + return kOpaque_SkAlphaType == alphaType ? SK_ColorBLACK : SK_ColorTRANSPARENT; + } + + /** + * Get method for the input stream + */ + SkStream* stream() { + return fStream.get(); + } + + /** + * The remaining functions revolve around decoding scanlines. + */ + + /** + * Most images types will be kTopDown and will not need to override this function. + */ + virtual SkScanlineOrder onGetScanlineOrder() const { return kTopDown_SkScanlineOrder; } + + /** + * Update the next scanline. Used by interlaced png. + */ + void updateNextScanline(int newY) { fCurrScanline = newY; } + + const SkImageInfo& dstInfo() const { return fDstInfo; } + + const SkCodec::Options& options() const { return fOptions; } + + virtual int onOutputScanline(int inputScanline) const; + +private: + const SkImageInfo fSrcInfo; + SkAutoTDelete fStream; + bool fNeedsRewind; + // These fields are only meaningful during scanline decodes. + SkImageInfo fDstInfo; + SkCodec::Options fOptions; + int fCurrScanline; + + /** + * Return whether these dimensions are supported as a scale. + * + * The codec may choose to cache the information about scale and subset. + * Either way, the same information will be passed to onGetPixels/onStart + * on success. + * + * This must return true for a size returned from getScaledDimensions. + */ + bool dimensionsSupported(const SkISize& dim) { + return dim == fSrcInfo.dimensions() || this->onDimensionsSupported(dim); + } + + // Methods for scanline decoding. + virtual SkCodec::Result onStartScanlineDecode(const SkImageInfo& /*dstInfo*/, + const SkCodec::Options& /*options*/, SkPMColor* /*ctable*/, int* /*ctableCount*/) { + return kUnimplemented; + } + + // Naive default version just calls onGetScanlines on temp memory. + virtual bool onSkipScanlines(int countLines) { + // FIXME (msarett): Make this a pure virtual and always override this. + SkAutoMalloc storage(fDstInfo.minRowBytes()); + + // Note that we pass 0 to rowBytes so we continue to use the same memory. + // Also note that while getScanlines checks that rowBytes is big enough, + // onGetScanlines bypasses that check. + // Calling the virtual method also means we do not double count + // countLines. + return countLines == this->onGetScanlines(storage.get(), countLines, 0); + } + + virtual int onGetScanlines(void* /*dst*/, int /*countLines*/, size_t /*rowBytes*/) { return 0; } + + /** + * On an incomplete decode, getPixels() and getScanlines() will call this function + * to fill any uinitialized memory. + * + * @param dstInfo Contains the destination color type + * Contains the destination alpha type + * Contains the destination width + * The height stored in this info is unused + * @param dst Pointer to the start of destination pixel memory + * @param rowBytes Stride length in destination pixel memory + * @param zeroInit Indicates if memory is zero initialized + * @param linesRequested Number of lines that the client requested + * @param linesDecoded Number of lines that were successfully decoded + */ + void fillIncompleteImage(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, + ZeroInitialized zeroInit, int linesRequested, int linesDecoded); + + /** + * Return an object which will allow forcing scanline decodes to sample in X. + * + * May create a sampler, if one is not currently being used. Otherwise, does + * not affect ownership. + * + * Only valid during scanline decoding. + */ + virtual SkSampler* getSampler(bool /*createIfNecessary*/) { return nullptr; } + + friend class SkSampledCodec; +}; +#endif // SkCodec_DEFINED diff --git a/gfx/skia/skia/include/codec/SkEncodedFormat.h b/gfx/skia/skia/include/codec/SkEncodedFormat.h new file mode 100644 index 000000000000..003159a8de27 --- /dev/null +++ b/gfx/skia/skia/include/codec/SkEncodedFormat.h @@ -0,0 +1,27 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkEncodedFormat_DEFINED +#define SkEncodedFormat_DEFINED + +/** + * Enum describing format of encoded data. + */ +enum SkEncodedFormat { + kUnknown_SkEncodedFormat, + kBMP_SkEncodedFormat, + kGIF_SkEncodedFormat, + kICO_SkEncodedFormat, + kJPEG_SkEncodedFormat, + kPNG_SkEncodedFormat, + kWBMP_SkEncodedFormat, + kWEBP_SkEncodedFormat, + kPKM_SkEncodedFormat, + kKTX_SkEncodedFormat, + kASTC_SkEncodedFormat, +}; +#endif // SkEncodedFormat_DEFINED diff --git a/gfx/skia/skia/include/config/SkUserConfig.h b/gfx/skia/skia/include/config/SkUserConfig.h index 3d21b4c689d4..f1a4959cadbc 100644 --- a/gfx/skia/skia/include/config/SkUserConfig.h +++ b/gfx/skia/skia/include/config/SkUserConfig.h @@ -58,13 +58,6 @@ //#define SK_DEBUG_GLYPH_CACHE //#define SK_DEBUG_PATH -/* To assist debugging, Skia provides an instance counting utility in - include/core/SkInstCount.h. This flag turns on and off that utility to - allow instance count tracking in either debug or release builds. By - default it is enabled in debug but disabled in release. - */ -#define SK_ENABLE_INST_COUNT 0 - /* If, in debugging mode, Skia needs to stop (presumably to invoke a debugger) it will call SK_CRASH(). If this is not defined it, it is defined in SkPostConfig.h to write to an illegal address @@ -107,14 +100,6 @@ */ //#define SK_DEFAULT_IMAGE_CACHE_LIMIT (1024 * 1024) -/* If zlib is available and you want to support the flate compression - algorithm (used in PDF generation), define SK_ZLIB_INCLUDE to be the - include path. Alternatively, define SK_SYSTEM_ZLIB to use the system zlib - library specified as "#include ". - */ -//#define SK_ZLIB_INCLUDE -//#define SK_SYSTEM_ZLIB - /* Define this to allow PDF scalars above 32k. The PDF/A spec doesn't allow them, but modern PDF interpreters should handle them just fine. */ @@ -139,17 +124,15 @@ //#define SK_SUPPORT_UNITTEST #endif -/* If your system embeds skia and has complex event logging, define this - symbol to name a file that maps the following macros to your system's - equivalents: - SK_TRACE_EVENT0(event) - SK_TRACE_EVENT1(event, name1, value1) - SK_TRACE_EVENT2(event, name1, value1, name2, value2) - src/utils/SkDebugTrace.h has a trivial implementation that writes to - the debug output stream. If SK_USER_TRACE_INCLUDE_FILE is not defined, - SkTrace.h will define the above three macros to do nothing. -*/ -//#undef SK_USER_TRACE_INCLUDE_FILE +/* Change the ordering to work in X windows. + */ +//#ifdef SK_SAMPLES_FOR_X +// #define SK_R32_SHIFT 16 +// #define SK_G32_SHIFT 8 +// #define SK_B32_SHIFT 0 +// #define SK_A32_SHIFT 24 +//#endif + /* Determines whether to build code that supports the GPU backend. Some classes that are not GPU-specific, such as SkShader subclasses, have optional code @@ -161,40 +144,14 @@ //#define SK_SUPPORT_GPU 1 -/* The PDF generation code uses Path Ops to generate inverse fills and complex - * clipping paths, but at this time, Path Ops is not release ready yet. So, - * the code is hidden behind this #define guard. If you are feeling adventurous - * and want the latest and greatest PDF generation code, uncomment the #define. +/* The PDF generation code uses Path Ops to handle complex clipping paths, + * but at this time, Path Ops is not release ready yet. So, the code is + * hidden behind this #define guard. If you are feeling adventurous and + * want the latest and greatest PDF generation code, uncomment the #define. * When Path Ops is release ready, the define guards and this user config * define should be removed entirely. */ -//#define SK_PDF_USE_PATHOPS - -/* Skia uses these defines as the target of include preprocessor directives. - * The header files pointed to by these defines provide declarations and - * possibly inline implementations of threading primitives. - * - * See SkThread.h for documentation on what these includes must contain. - */ -//#define SK_ATOMICS_PLATFORM_H "SkAtomics_xxx.h" -//#define SK_MUTEX_PLATFORM_H "SkMutex_xxx.h" -#if defined(_MSC_VER) -# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h" -#else -# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h" -#endif - -#if defined(_WIN32) -# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_win.h" -#else -# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h" -#endif - -#if defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64) -# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_arm.h" -#else -# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_x86.h" -#endif +//#define SK_PDF_USE_PATHOPS_CLIPPING // On all platforms we have this byte order #define SK_A32_SHIFT 24 @@ -205,8 +162,21 @@ #define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 0 #define SK_SUPPORT_LEGACY_GETDEVICE + #define SK_IGNORE_ETC1_SUPPORT #define SK_RASTERIZE_EVEN_ROUNDING +#define GR_GL_PER_GL_FUNC_CALLBACK 1 + +#define MOZ_SKIA 1 + +#ifndef MOZ_IMPLICIT +# ifdef MOZ_CLANG_PLUGIN +# define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) +# else +# define MOZ_IMPLICIT +# endif +#endif + #endif diff --git a/gfx/skia/skia/include/core/SkAnnotation.h b/gfx/skia/skia/include/core/SkAnnotation.h index d7b9b84529d3..80503c78d21d 100644 --- a/gfx/skia/skia/include/core/SkAnnotation.h +++ b/gfx/skia/skia/include/core/SkAnnotation.h @@ -10,12 +10,11 @@ #include "SkRefCnt.h" #include "SkString.h" +#include "SkTypes.h" class SkData; class SkReadBuffer; class SkWriteBuffer; -class SkStream; -class SkWStream; struct SkPoint; /** @@ -27,12 +26,10 @@ public: virtual ~SkAnnotation(); static SkAnnotation* Create(const char key[], SkData* value) { - return SkNEW_ARGS(SkAnnotation, (key, value)); + return new SkAnnotation(key, value); } - static SkAnnotation* Create(SkReadBuffer& buffer) { - return SkNEW_ARGS(SkAnnotation, (buffer)); - } + static SkAnnotation* Create(SkReadBuffer& buffer) { return new SkAnnotation(buffer); } /** * Return the data for the specified key, or NULL. diff --git a/gfx/skia/skia/include/core/SkBBHFactory.h b/gfx/skia/skia/include/core/SkBBHFactory.h index 4c0384422117..ca7040409d37 100644 --- a/gfx/skia/skia/include/core/SkBBHFactory.h +++ b/gfx/skia/skia/include/core/SkBBHFactory.h @@ -8,62 +8,24 @@ #ifndef SkBBHFactory_DEFINED #define SkBBHFactory_DEFINED -#include "SkSize.h" -#include "SkPoint.h" - +#include "SkTypes.h" class SkBBoxHierarchy; +struct SkRect; class SK_API SkBBHFactory { public: /** * Allocate a new SkBBoxHierarchy. Return NULL on failure. */ - virtual SkBBoxHierarchy* operator()(int width, int height) const = 0; + virtual SkBBoxHierarchy* operator()(const SkRect& bounds) const = 0; virtual ~SkBBHFactory() {}; }; -class SK_API SkQuadTreeFactory : public SkBBHFactory { -public: - virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE; -private: - typedef SkBBHFactory INHERITED; -}; - - class SK_API SkRTreeFactory : public SkBBHFactory { public: - virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE; + SkBBoxHierarchy* operator()(const SkRect& bounds) const override; private: typedef SkBBHFactory INHERITED; }; -class SK_API SkTileGridFactory : public SkBBHFactory { -public: - struct TileGridInfo { - /** Tile placement interval */ - SkISize fTileInterval; - - /** Pixel coverage overlap between adjacent tiles */ - SkISize fMargin; - - /** Offset added to device-space bounding box positions to convert - * them to tile-grid space. This can be used to adjust the "phase" - * of the tile grid to match probable query rectangles that will be - * used to search into the tile grid. As long as the offset is smaller - * or equal to the margin, there is no need to extend the domain of - * the tile grid to prevent data loss. - */ - SkIPoint fOffset; - }; - - SkTileGridFactory(const TileGridInfo& info) : fInfo(info) { } - - virtual SkBBoxHierarchy* operator()(int width, int height) const SK_OVERRIDE; - -private: - TileGridInfo fInfo; - - typedef SkBBHFactory INHERITED; -}; - #endif diff --git a/gfx/skia/skia/include/core/SkBitmap.h b/gfx/skia/skia/include/core/SkBitmap.h index 0e847f2a4cf6..eda13b3c5239 100644 --- a/gfx/skia/skia/include/core/SkBitmap.h +++ b/gfx/skia/skia/include/core/SkBitmap.h @@ -11,6 +11,7 @@ #include "SkColor.h" #include "SkColorTable.h" #include "SkImageInfo.h" +#include "SkPixmap.h" #include "SkPoint.h" #include "SkRefCnt.h" @@ -38,29 +39,6 @@ class SK_API SkBitmap { public: class SK_API Allocator; -#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG - enum Config { - kNo_Config, //!< bitmap has not been configured - kA8_Config, //!< 8-bits per pixel, with only alpha specified (0 is transparent, 0xFF is opaque) - kIndex8_Config, //!< 8-bits per pixel, using SkColorTable to specify the colors - kRGB_565_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing) - kARGB_4444_Config, //!< 16-bits per pixel, (see SkColorPriv.h for packing) - kARGB_8888_Config, //!< 32-bits per pixel, (see SkColorPriv.h for packing) - }; - - // do not add this to the Config enum, otherwise the compiler will let us - // pass this as a valid parameter for Config. - enum { - kConfigCount = kARGB_8888_Config + 1 - }; - - /** Return the config for the bitmap. */ - Config config() const; - - SK_ATTR_DEPRECATED("use config()") - Config getConfig() const { return this->config(); } -#endif - /** * Default construct creates a bitmap with zero width and height, and no pixels. * Its colortype is set to kUnknown_SkColorType. @@ -91,10 +69,11 @@ public: const SkImageInfo& info() const { return fInfo; } - int width() const { return fInfo.fWidth; } - int height() const { return fInfo.fHeight; } - SkColorType colorType() const { return fInfo.fColorType; } - SkAlphaType alphaType() const { return fInfo.fAlphaType; } + int width() const { return fInfo.width(); } + int height() const { return fInfo.height(); } + SkColorType colorType() const { return fInfo.colorType(); } + SkAlphaType alphaType() const { return fInfo.alphaType(); } + SkColorProfileType profileType() const { return fInfo.profileType(); } /** * Return the number of bytes per pixel based on the colortype. If the colortype is @@ -155,7 +134,7 @@ public: Note this truncates the result to 32bits. Call getSize64() to detect if the real size exceeds 32bits. */ - size_t getSize() const { return fInfo.fHeight * fRowBytes; } + size_t getSize() const { return fInfo.height() * fRowBytes; } /** Return the number of bytes from the pointer returned by getPixels() to the end of the allocated space in the buffer. Required in @@ -167,7 +146,7 @@ public: * Return the full size of the bitmap, in bytes. */ int64_t computeSize64() const { - return sk_64_mul(fInfo.fHeight, fRowBytes); + return sk_64_mul(fInfo.height(), fRowBytes); } /** @@ -233,6 +212,14 @@ public: void getBounds(SkRect* bounds) const; void getBounds(SkIRect* bounds) const; + SkIRect bounds() const { return fInfo.bounds(); } + SkISize dimensions() const { return fInfo.dimensions(); } + // Returns the bounds of this bitmap, offset by its pixelref origin. + SkIRect getSubset() const { + return SkIRect::MakeXYWH(fPixelRefOrigin.x(), fPixelRefOrigin.y(), + fInfo.width(), fInfo.height()); + } + bool setInfo(const SkImageInfo&, size_t rowBytes = 0); /** @@ -241,7 +228,13 @@ public: * a colortable, then ColorTable must be non-null, and will be ref'd. * On failure, the bitmap will be set to empty and return false. */ - bool allocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*); + bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo&, SkPixelRefFactory*, SkColorTable*); + + void allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, SkColorTable* ctable) { + if (!this->tryAllocPixels(info, factory, ctable)) { + sk_throw(); + } + } /** * Allocate the bitmap's pixels to match the requested image info and @@ -251,24 +244,32 @@ public: * the pixel size specified by info.colorType()) then false is returned * and the bitmap is set to empty. */ - bool allocPixels(const SkImageInfo& info, size_t rowBytes); + bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info, size_t rowBytes); - /** - * Allocate a pixelref to match the specified image info, using the default - * allocator. - * On success, the bitmap's pixels will be "locked", and return true. - * On failure, the bitmap will be set to empty and return false. - */ - bool allocPixels(const SkImageInfo& info) { - return this->allocPixels(info, info.minRowBytes()); + void allocPixels(const SkImageInfo& info, size_t rowBytes) { + if (!this->tryAllocPixels(info, rowBytes)) { + sk_throw(); + } } - bool allocN32Pixels(int width, int height, bool isOpaque = false) { - SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); - if (isOpaque) { - info.fAlphaType = kOpaque_SkAlphaType; - } - return this->allocPixels(info); + bool SK_WARN_UNUSED_RESULT tryAllocPixels(const SkImageInfo& info) { + return this->tryAllocPixels(info, info.minRowBytes()); + } + + void allocPixels(const SkImageInfo& info) { + this->allocPixels(info, info.minRowBytes()); + } + + bool SK_WARN_UNUSED_RESULT tryAllocN32Pixels(int width, int height, bool isOpaque = false) { + SkImageInfo info = SkImageInfo::MakeN32(width, height, + isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); + return this->tryAllocPixels(info); + } + + void allocN32Pixels(int width, int height, bool isOpaque = false) { + SkImageInfo info = SkImageInfo::MakeN32(width, height, + isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); + this->allocPixels(info); } /** @@ -277,6 +278,9 @@ public: * referenced, if releaseProc is not null, it will be called with the * pixels and context as parameters. * On failure, the bitmap will be set to empty and return false. + * + * If specified, the releaseProc will always be called, even on failure. It is also possible + * for success but the releaseProc is immediately called (e.g. valid Info but NULL pixels). */ bool installPixels(const SkImageInfo&, void* pixels, size_t rowBytes, SkColorTable*, void (*releaseProc)(void* addr, void* context), void* context); @@ -343,8 +347,12 @@ public: @return true if the allocation succeeds. If not the pixelref field of the bitmap will be unchanged. */ - bool allocPixels(SkColorTable* ctable = NULL) { - return this->allocPixels(NULL, ctable); + bool SK_WARN_UNUSED_RESULT tryAllocPixels(SkColorTable* ctable = NULL) { + return this->tryAllocPixels(NULL, ctable); + } + + void allocPixels(SkColorTable* ctable = NULL) { + this->allocPixels(NULL, ctable); } /** Use the specified Allocator to create the pixelref that manages the @@ -365,7 +373,13 @@ public: @return true if the allocation succeeds. If not the pixelref field of the bitmap will be unchanged. */ - bool allocPixels(Allocator* allocator, SkColorTable* ctable); + bool SK_WARN_UNUSED_RESULT tryAllocPixels(Allocator* allocator, SkColorTable* ctable); + + void allocPixels(Allocator* allocator, SkColorTable* ctable) { + if (!this->tryAllocPixels(allocator, ctable)) { + sk_throw(); + } + } /** * Return the current pixelref object or NULL if there is none. This does @@ -423,13 +437,15 @@ public: */ bool lockPixelsAreWritable() const; + bool requestLock(SkAutoPixmapUnlock* result) const; + /** Call this to be sure that the bitmap is valid enough to be drawn (i.e. it has non-null pixels, and if required by its colortype, it has a non-null colortable. Returns true if all of the above are met. */ bool readyToDraw() const { return this->getPixels() != NULL && - (this->colorType() != kIndex_8_SkColorType || NULL != fColorTable); + (this->colorType() != kIndex_8_SkColorType || fColorTable); } /** Returns the pixelRef's texture, or NULL @@ -462,10 +478,7 @@ public: * of the color is ignored (treated as opaque). If the colortype only supports * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored. */ - void eraseColor(SkColor c) const { - this->eraseARGB(SkColorGetA(c), SkColorGetR(c), SkColorGetG(c), - SkColorGetB(c)); - } + void eraseColor(SkColor c) const; /** * Fill the entire bitmap with the specified color. @@ -473,7 +486,9 @@ public: * of the color is ignored (treated as opaque). If the colortype only supports * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored. */ - void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const; + void eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { + this->eraseColor(SkColorSetARGB(a, r, g, b)); + } SK_ATTR_DEPRECATED("use eraseARGB or eraseColor") void eraseRGB(U8CPU r, U8CPU g, U8CPU b) const { @@ -486,29 +501,12 @@ public: * of the color is ignored (treated as opaque). If the colortype only supports * alpha (e.g. A1 or A8) then the color's r,g,b components are ignored. */ - void eraseArea(const SkIRect& area, SkColor c) const; + void erase(SkColor c, const SkIRect& area) const; - /** Scroll (a subset of) the contents of this bitmap by dx/dy. If there are - no pixels allocated (i.e. getPixels() returns null) the method will - still update the inval region (if present). If the bitmap is immutable, - do nothing and return false. - - @param subset The subset of the bitmap to scroll/move. To scroll the - entire contents, specify [0, 0, width, height] or just - pass null. - @param dx The amount to scroll in X - @param dy The amount to scroll in Y - @param inval Optional (may be null). Returns the area of the bitmap that - was scrolled away. E.g. if dx = dy = 0, then inval would - be set to empty. If dx >= width or dy >= height, then - inval would be set to the entire bounds of the bitmap. - @return true if the scroll was doable. Will return false if the colortype is kUnkown or - if the bitmap is immutable. - If no pixels are present (i.e. getPixels() returns false) - inval will still be updated, and true will be returned. - */ - bool scrollRect(const SkIRect* subset, int dx, int dy, - SkRegion* inval = NULL) const; + // DEPRECATED + void eraseArea(const SkIRect& area, SkColor c) const { + this->erase(c, area); + } /** * Return the SkColor of the specified pixel. In most cases this will @@ -665,12 +663,21 @@ public: bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator, SkIPoint* offset) const; + /** + * If the pixels are available from this bitmap (w/o locking) return true, and fill out the + * specified pixmap (if not null). If the pixels are not available (either because there are + * none, or becuase accessing them would require locking or other machinary) return false and + * ignore the pixmap parameter. + * + * Note: if this returns true, the results (in the pixmap) are only valid until the bitmap + * is changed in anyway, in which case the results are invalid. + */ + bool peekPixels(SkPixmap*) const; + SkDEBUGCODE(void validate() const;) class Allocator : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(Allocator) - /** Allocate the pixel memory for the bitmap, given its dimensions and colortype. Return true on success, where success means either setPixels or setPixelRef was called. The pixels need not be locked when this @@ -689,7 +696,7 @@ public: */ class HeapAllocator : public Allocator { public: - virtual bool allocPixelRef(SkBitmap*, SkColorTable*) SK_OVERRIDE; + bool allocPixelRef(SkBitmap*, SkColorTable*) override; }; class RLEPixels { @@ -736,24 +743,17 @@ private: }; SkImageInfo fInfo; - uint32_t fRowBytes; - uint8_t fFlags; - void internalErase(const SkIRect&, U8CPU a, U8CPU r, U8CPU g, U8CPU b)const; - /* Unreference any pixelrefs or colortables */ void freePixels(); void updatePixelsFromRef() const; - void legacyUnflatten(SkReadBuffer&); - static void WriteRawPixels(SkWriteBuffer*, const SkBitmap&); static bool ReadRawPixels(SkReadBuffer*, SkBitmap*); - friend class SkBitmapSource; // unflatten friend class SkReadBuffer; // unflatten, rawpixels friend class SkWriteBuffer; // rawpixels friend struct SkBitmapProcState; @@ -780,60 +780,6 @@ private: //TODO(mtklein): uncomment when 71713004 lands and Chromium's fixed. //#define SkAutoLockPixels(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockPixels) -/** Helper class that performs the lock/unlockColors calls on a colortable. - The destructor will call unlockColors(false) if it has a bitmap's colortable -*/ -class SkAutoLockColors : SkNoncopyable { -public: - /** Initialize with no bitmap. Call lockColors(bitmap) to lock bitmap's - colortable - */ - SkAutoLockColors() : fCTable(NULL), fColors(NULL) {} - /** Initialize with bitmap, locking its colortable if present - */ - explicit SkAutoLockColors(const SkBitmap& bm) { - fCTable = bm.getColorTable(); - fColors = fCTable ? fCTable->lockColors() : NULL; - } - /** Initialize with a colortable (may be null) - */ - explicit SkAutoLockColors(SkColorTable* ctable) { - fCTable = ctable; - fColors = ctable ? ctable->lockColors() : NULL; - } - ~SkAutoLockColors() { - if (fCTable) { - fCTable->unlockColors(); - } - } - - /** Return the currently locked colors, or NULL if no bitmap's colortable - is currently locked. - */ - const SkPMColor* colors() const { return fColors; } - - /** Locks the table and returns is colors (assuming ctable is not null) and - unlocks the previous table if one was present - */ - const SkPMColor* lockColors(SkColorTable* ctable) { - if (fCTable) { - fCTable->unlockColors(); - } - fCTable = ctable; - fColors = ctable ? ctable->lockColors() : NULL; - return fColors; - } - - const SkPMColor* lockColors(const SkBitmap& bm) { - return this->lockColors(bm.getColorTable()); - } - -private: - SkColorTable* fCTable; - const SkPMColor* fColors; -}; -#define SkAutoLockColors(...) SK_REQUIRE_LOCAL_VAR(SkAutoLockColors) - /////////////////////////////////////////////////////////////////////////////// inline uint32_t* SkBitmap::getAddr32(int x, int y) const { @@ -865,13 +811,4 @@ inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const { return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)]; } -#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG -/////////////////////////////////////////////////////////////////////////////// -// -// Helpers until we can fully deprecate SkBitmap::Config -// -SK_API SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType); -SK_API SkColorType SkBitmapConfigToColorType(SkBitmap::Config); -#endif - #endif diff --git a/gfx/skia/skia/include/core/SkBitmapDevice.h b/gfx/skia/skia/include/core/SkBitmapDevice.h index e1765e56abc3..d1cb9ad0f866 100644 --- a/gfx/skia/skia/include/core/SkBitmapDevice.h +++ b/gfx/skia/skia/include/core/SkBitmapDevice.h @@ -9,54 +9,74 @@ #ifndef SkBitmapDevice_DEFINED #define SkBitmapDevice_DEFINED +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkColor.h" #include "SkDevice.h" +#include "SkImageFilter.h" +#include "SkImageInfo.h" +#include "SkRect.h" +#include "SkScalar.h" +#include "SkSize.h" +#include "SkSurfaceProps.h" +#include "SkTypes.h" + +class SkDraw; +class SkMatrix; +class SkPaint; +class SkPath; +class SkPixelRef; +class SkPixmap; +class SkRRect; +class SkSurface; +class SkXfermode; +struct SkPoint; /////////////////////////////////////////////////////////////////////////////// class SK_API SkBitmapDevice : public SkBaseDevice { public: - SK_DECLARE_INST_COUNT(SkBitmapDevice) - /** * Construct a new device with the specified bitmap as its backend. It is * valid for the bitmap to have no pixels associated with it. In that case, * any drawing to this device will have no effect. - */ + */ SkBitmapDevice(const SkBitmap& bitmap); + /** + * Create a new device along with its requisite pixel memory using + * default SkSurfaceProps (i.e., kLegacyFontHost_InitType-style). + * Note: this entry point is slated for removal - no one should call it. + */ + static SkBitmapDevice* Create(const SkImageInfo& info); + /** * Construct a new device with the specified bitmap as its backend. It is * valid for the bitmap to have no pixels associated with it. In that case, * any drawing to this device will have no effect. - */ - SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties); + */ + SkBitmapDevice(const SkBitmap& bitmap, const SkSurfaceProps& surfaceProps); - static SkBitmapDevice* Create(const SkImageInfo&, - const SkDeviceProperties* = NULL); + static SkBitmapDevice* Create(const SkImageInfo&, const SkSurfaceProps&); - virtual SkImageInfo imageInfo() const SK_OVERRIDE; + SkImageInfo imageInfo() const override; protected: - virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE; - - /** Clears the entire device to the specified color (including alpha). - * Ignores the clip. - */ - virtual void clear(SkColor color) SK_OVERRIDE; + bool onShouldDisableLCD(const SkPaint&) const override; /** These are called inside the per-device-layer loop for each draw call. When these are called, we have already applied any saveLayer operations, and are handling any looping from the paint, and any effects from the DrawFilter. */ - virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE; + void drawPaint(const SkDraw&, const SkPaint& paint) override; virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, - const SkPoint[], const SkPaint& paint) SK_OVERRIDE; + const SkPoint[], const SkPaint& paint) override; virtual void drawRect(const SkDraw&, const SkRect& r, - const SkPaint& paint) SK_OVERRIDE; + const SkPaint& paint) override; virtual void drawOval(const SkDraw&, const SkRect& oval, - const SkPaint& paint) SK_OVERRIDE; + const SkPaint& paint) override; virtual void drawRRect(const SkDraw&, const SkRRect& rr, - const SkPaint& paint) SK_OVERRIDE; + const SkPaint& paint) override; /** * If pathIsMutable, then the implementation is allowed to cast path to a @@ -72,43 +92,34 @@ protected: virtual void drawPath(const SkDraw&, const SkPath& path, const SkPaint& paint, const SkMatrix* prePathMatrix = NULL, - bool pathIsMutable = false) SK_OVERRIDE; + bool pathIsMutable = false) override; virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, - const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE; + const SkMatrix& matrix, const SkPaint& paint) override; virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, - int x, int y, const SkPaint& paint) SK_OVERRIDE; + int x, int y, const SkPaint& paint) override; /** * The default impl. will create a bitmap-shader from the bitmap, * and call drawRect with it. */ - virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, - const SkRect* srcOrNull, const SkRect& dst, - const SkPaint& paint, - SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE; + void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, const SkRect&, + const SkPaint&, SkCanvas::SrcRectConstraint) override; /** * Does not handle text decoration. * Decorations (underline and stike-thru) will be handled by SkCanvas. */ virtual void drawText(const SkDraw&, const void* text, size_t len, - SkScalar x, SkScalar y, const SkPaint& paint) SK_OVERRIDE; + SkScalar x, SkScalar y, const SkPaint& paint) override; virtual void drawPosText(const SkDraw&, const void* text, size_t len, - const SkScalar pos[], SkScalar constY, - int scalarsPerPos, const SkPaint& paint) SK_OVERRIDE; - virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) SK_OVERRIDE; + const SkScalar pos[], int scalarsPerPos, + const SkPoint& offset, const SkPaint& paint) override; virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, - const SkPaint& paint) SK_OVERRIDE; - /** The SkBaseDevice passed will be an SkBaseDevice which was returned by a call to - onCreateDevice on this device with kSaveLayer_Usage. - */ - virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, - const SkPaint&) SK_OVERRIDE; + const SkPaint& paint) override; + virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override; /////////////////////////////////////////////////////////////////////////// @@ -117,7 +128,7 @@ protected: altered. The config/width/height/rowbytes must remain unchanged. @return the device contents as a bitmap */ - virtual const SkBitmap& onAccessBitmap() SK_OVERRIDE; + const SkBitmap& onAccessBitmap() override; SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); } // just for subclasses, to assign a custom pixelref @@ -126,15 +137,12 @@ protected: return pr; } - virtual bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) SK_OVERRIDE; - virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE; - virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes) SK_OVERRIDE; - - /** Called when this device is installed into a Canvas. Balanced by a call - to unlockPixels() when the device is removed from a Canvas. - */ - virtual void lockPixels() SK_OVERRIDE; - virtual void unlockPixels() SK_OVERRIDE; + bool onReadPixels(const SkImageInfo&, void*, size_t, int x, int y) override; + bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) override; + bool onPeekPixels(SkPixmap*) override; + bool onAccessPixels(SkPixmap*) override; + void onAttachToCanvas(SkCanvas*) override; + void onDetachFromCanvas() override; private: friend class SkCanvas; @@ -142,22 +150,24 @@ private: friend class SkDraw; friend class SkDrawIter; friend class SkDeviceFilteredPaint; - friend class SkDeviceImageFilterProxy; friend class SkSurface_Raster; // used to change the backend's pixels (and possibly config/rowbytes) // but cannot change the width/height, so there should be no change to // any clip information. - virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE; + void replaceBitmapBackendForRasterSurface(const SkBitmap&) override; - virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; + SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) override; - virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE; - virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE; + SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) override; + + SkImageFilter::Cache* getImageFilterCache() override; SkBitmap fBitmap; + void setNewSize(const SkISize&); // Used by SkCanvas for resetForNextPicture(). + typedef SkBaseDevice INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkBlitRow.h b/gfx/skia/skia/include/core/SkBlitRow.h index 9393589b82b1..56121eba78e2 100644 --- a/gfx/skia/skia/include/core/SkBlitRow.h +++ b/gfx/skia/skia/include/core/SkBlitRow.h @@ -26,17 +26,26 @@ public: a corresponding scanline of 16bit colors (specific format based on the config passed to the Factory. - The x,y params are useful just for dithering + The x,y params provide the dithering phase for the start of the scanline @param alpha A global alpha to be applied to all of the src colors @param x The x coordinate of the beginning of the scanline @param y THe y coordinate of the scanline */ - typedef void (*Proc)(uint16_t* dst, - const SkPMColor* src, - int count, U8CPU alpha, int x, int y); + typedef void (*Proc16)(uint16_t dst[], const SkPMColor src[], int count, + U8CPU alpha, int x, int y); - static Proc Factory(unsigned flags, SkColorType); + static Proc16 Factory16(unsigned flags); + + /** + * Function pointer that blends a single src color onto a scaline of dst colors. + * + * The x,y params provide the dithering phase for the start of the scanline + */ + typedef void (*ColorProc16)(uint16_t dst[], SkPMColor src, int count, int x, int y); + + // Note : we ignore the kGlobalAlpha_Flag setting, but do respect kSrcPixelAlpha_Flag + static ColorProc16 ColorFactory16(unsigned flags); ///////////// D32 version @@ -51,38 +60,15 @@ public: @param count number of colors to blend @param alpha global alpha to be applied to all src colors */ - typedef void (*Proc32)(uint32_t* dst, - const SkPMColor* src, - int count, U8CPU alpha); + typedef void (*Proc32)(uint32_t dst[], const SkPMColor src[], int count, U8CPU alpha); static Proc32 Factory32(unsigned flags32); - /** Function pointer that blends a single color with a row of 32-bit colors - onto a 32-bit destination - */ - typedef void (*ColorProc)(SkPMColor* dst, const SkPMColor* src, int count, - SkPMColor color); - /** Blend a single color onto a row of S32 pixels, writing the result into a row of D32 pixels. src and dst may be the same memory, but if they are not, they may not overlap. */ - static void Color32(SkPMColor dst[], const SkPMColor src[], - int count, SkPMColor color); - - //! Public entry-point to return a blit function ptr - static ColorProc ColorProcFactory(); - - /** Function pointer that blends a single color onto a 32-bit rectangle. */ - typedef void (*ColorRectProc)(SkPMColor* dst, int width, int height, - size_t rowBytes, SkPMColor color); - - /** Blend a single color into a rectangle of D32 pixels. */ - static void ColorRect32(SkPMColor* dst, int width, int height, - size_t rowBytes, SkPMColor color); - - //! Public entry-point to return a blit function ptr - static ColorRectProc ColorRectProcFactory(); + static void Color32(SkPMColor dst[], const SkPMColor src[], int count, SkPMColor color); /** These static functions are called by the Factory and Factory32 functions, and should return either NULL, or a @@ -91,8 +77,9 @@ public: */ static Proc32 PlatformProcs32(unsigned flags); - static Proc PlatformProcs565(unsigned flags); - static ColorProc PlatformColorProc(); + + static Proc16 PlatformFactory565(unsigned flags); + static ColorProc16 PlatformColorFactory565(unsigned flags); private: enum { diff --git a/gfx/skia/skia/include/core/SkCanvas.h b/gfx/skia/skia/include/core/SkCanvas.h index d68a9c50ab80..53f6dda88b09 100644 --- a/gfx/skia/skia/include/core/SkCanvas.h +++ b/gfx/skia/skia/include/core/SkCanvas.h @@ -11,30 +11,31 @@ #include "SkTypes.h" #include "SkBitmap.h" #include "SkDeque.h" -#include "SkClipStack.h" #include "SkPaint.h" #include "SkRefCnt.h" -#include "SkPath.h" #include "SkRegion.h" +#include "SkSurfaceProps.h" #include "SkXfermode.h" -#ifdef SK_SUPPORT_LEGACY_DRAWTEXT_VIRTUAL - #define SK_LEGACY_DRAWTEXT_VIRTUAL virtual -#else - #define SK_LEGACY_DRAWTEXT_VIRTUAL -#endif - -class SkCanvasClipVisitor; -class SkBaseDevice; -class SkDraw; -class SkDrawFilter; -class SkMetaData; -class SkPicture; -class SkRRect; -class SkSurface; -class SkSurface_Base; class GrContext; class GrRenderTarget; +class SkBaseDevice; +class SkCanvasClipVisitor; +class SkClipStack; +class SkDraw; +class SkDrawable; +class SkDrawFilter; +class SkImage; +class SkImageFilter; +class SkMetaData; +class SkPath; +class SkPicture; +class SkPixmap; +class SkRRect; +struct SkRSXform; +class SkSurface; +class SkSurface_Base; +class SkTextBlob; /** \class SkCanvas @@ -53,37 +54,6 @@ class GrRenderTarget; */ class SK_API SkCanvas : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkCanvas) - - /** - * Attempt to allocate an offscreen raster canvas, matching the ImageInfo. - * On success, return a new canvas that will draw into that offscreen. - * - * The caller can access the pixels after drawing into this canvas by - * calling readPixels() or peekPixels(). - * - * If the requested ImageInfo is opaque (either the colortype is - * intrinsically opaque like RGB_565, or the info's alphatype is kOpaque) - * then the pixel memory may be uninitialized. Otherwise, the pixel memory - * will be initialized to 0, which is interpreted as transparent. - * - * On failure, return NULL. This can fail for several reasons: - * 1. the memory allocation failed (e.g. request is too large) - * 2. invalid ImageInfo (e.g. negative dimensions) - * 3. unsupported ImageInfo for a canvas - * - kUnknown_SkColorType, kIndex_8_SkColorType - * - kIgnore_SkAlphaType - * - this list is not complete, so others may also be unsupported - * - * Note: it is valid to request a supported ImageInfo, but with zero - * dimensions. - */ - static SkCanvas* NewRaster(const SkImageInfo&); - - static SkCanvas* NewRasterN32(int width, int height) { - return NewRaster(SkImageInfo::MakeN32Premul(width, height)); - } - /** * Attempt to allocate raster canvas, matching the ImageInfo, that will draw directly into the * specified pixels. To access the pixels after drawing to them, the caller should call @@ -93,7 +63,7 @@ public: * 1. invalid ImageInfo (e.g. negative dimensions) * 2. unsupported ImageInfo for a canvas * - kUnknown_SkColorType, kIndex_8_SkColorType - * - kIgnore_SkAlphaType + * - kUnknown_SkAlphaType * - this list is not complete, so others may also be unsupported * * Note: it is valid to request a supported ImageInfo, but with zero @@ -116,7 +86,7 @@ public: * by any device/pixels. Typically this use used by subclasses who handle * the draw calls in some other way. */ - SkCanvas(int width, int height); + SkCanvas(int width, int height, const SkSurfaceProps* = NULL); /** Construct a canvas with the specified device to draw into. @@ -129,6 +99,14 @@ public: structure are copied to the canvas. */ explicit SkCanvas(const SkBitmap& bitmap); + + /** Construct a canvas with the specified bitmap to draw into. + @param bitmap Specifies a bitmap for the canvas to draw into. Its + structure are copied to the canvas. + @param props New canvas surface properties. + */ + SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props); + virtual ~SkCanvas(); SkMetaData& getMetaData(); @@ -151,7 +129,7 @@ public: * origin of the base layer is always (0,0). The current drawable area may be * smaller (due to clipping or saveLayer). */ - SkISize getBaseLayerSize() const; + virtual SkISize getBaseLayerSize() const; /** * DEPRECATED: call getBaseLayerSize @@ -169,6 +147,9 @@ protected: // Can we make this private? #endif SkBaseDevice* getDevice() const; public: + SkBaseDevice* getDevice_just_for_deprecated_compatibility_testing() const { + return this->getDevice(); + } /** * saveLayer() can create another device (which is later drawn onto @@ -193,8 +174,12 @@ public: * Create a new surface matching the specified info, one that attempts to * be maximally compatible when used with this canvas. If there is no matching Surface type, * NULL is returned. + * + * If surfaceprops is specified, those are passed to the new surface, otherwise the new surface + * inherits the properties of the surface that owns this canvas. If this canvas has no parent + * surface, then the new surface is created with default properties. */ - SkSurface* newSurface(const SkImageInfo&); + SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps* = NULL); /** * Return the GPU context of the device that is associated with the canvas. @@ -347,6 +332,9 @@ public: @return The value to pass to restoreToCount() to balance this save() */ int saveLayer(const SkRect* bounds, const SkPaint* paint); + int saveLayer(const SkRect& bounds, const SkPaint* paint) { + return this->saveLayer(&bounds, paint); + } /** DEPRECATED - use saveLayer(const SkRect*, const SkPaint*) instead. @@ -417,11 +405,6 @@ public: */ void restoreToCount(int saveCount); - /** Returns true if drawing is currently going to a layer (from saveLayer) - * rather than to the root device. - */ - virtual bool isDrawingToLayer() const; - /** Preconcat the current matrix with the specified translation @param dx The distance to translate in X @param dy The distance to translate in Y @@ -609,24 +592,15 @@ public: @param color the color to draw with @param mode the mode to apply the color in (defaults to SrcOver) */ - void drawColor(SkColor color, - SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); + void drawColor(SkColor color, SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode); /** - * This erases the entire drawing surface to the specified color, - * irrespective of the clip. It does not blend with the previous pixels, - * but always overwrites them. - * - * It is roughly equivalent to the following: - * canvas.save(); - * canvas.clipRect(hugeRect, kReplace_Op); - * paint.setColor(color); - * paint.setXfermodeMode(kSrc_Mode); - * canvas.drawPaint(paint); - * canvas.restore(); - * though it is almost always much more efficient. + * Helper method for drawing a color in SRC mode, completely replacing all the pixels + * in the current clip with this color. */ - virtual void clear(SkColor); + void clear(SkColor color) { + this->drawColor(color, SkXfermode::kSrc_Mode); + } /** * This makes the contents of the canvas undefined. Subsequent calls that @@ -647,7 +621,7 @@ public: * specified paint. * @param paint The paint used to fill the canvas */ - virtual void drawPaint(const SkPaint& paint); + void drawPaint(const SkPaint& paint); enum PointMode { /** drawPoints draws each point separately */ @@ -679,8 +653,7 @@ public: @param pts Array of points to draw @param paint The paint used to draw the points */ - virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], - const SkPaint& paint); + void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint); /** Helper method for drawing a single point. See drawPoints() for a more details. @@ -711,7 +684,7 @@ public: @param rect The rect to be drawn @param paint The paint used to draw the rect */ - virtual void drawRect(const SkRect& rect, const SkPaint& paint); + void drawRect(const SkRect& rect, const SkPaint& paint); /** Draw the specified rectangle using the specified paint. The rectangle will be filled or framed based on the Style in the paint. @@ -740,7 +713,7 @@ public: @param oval The rectangle bounds of the oval to be drawn @param paint The paint used to draw the oval */ - virtual void drawOval(const SkRect& oval, const SkPaint&); + void drawOval(const SkRect& oval, const SkPaint&); /** * Draw the specified RRect using the specified paint The rrect will be filled or stroked @@ -749,7 +722,7 @@ public: * @param rrect The round-rect to draw * @param paint The paint used to draw the round-rect */ - virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint); + void drawRRect(const SkRRect& rrect, const SkPaint& paint); /** * Draw the annulus formed by the outer and inner rrects. The results @@ -797,7 +770,84 @@ public: @param path The path to be drawn @param paint The paint used to draw the path */ - virtual void drawPath(const SkPath& path, const SkPaint& paint); + void drawPath(const SkPath& path, const SkPaint& paint); + + /** Draw the specified image, with its top/left corner at (x,y), using the + specified paint, transformed by the current matrix. + + @param image The image to be drawn + @param left The position of the left side of the image being drawn + @param top The position of the top side of the image being drawn + @param paint The paint used to draw the image, or NULL + */ + void drawImage(const SkImage* image, SkScalar left, SkScalar top, const SkPaint* paint = NULL); + + /** + * Controls the behavior at the edge of the src-rect, when specified in drawImageRect, + * trading off speed for exactness. + * + * When filtering is enabled (in the Paint), skia may need to sample in a neighborhood around + * the pixels in the image. If there is a src-rect specified, it is intended to restrict the + * pixels that will be read. However, for performance reasons, some implementations may slow + * down if they cannot read 1-pixel past the src-rect boundary at times. + * + * This enum allows the caller to specify if such a 1-pixel "slop" will be visually acceptable. + * If it is, the caller should pass kFast, and it may result in a faster draw. If the src-rect + * must be strictly respected, the caller should pass kStrict. + */ + enum SrcRectConstraint { + /** + * If kStrict is specified, the implementation must respect the src-rect + * (if specified) strictly, and will never sample outside of those bounds during sampling + * even when filtering. This may be slower than kFast. + */ + kStrict_SrcRectConstraint, + + /** + * If kFast is specified, the implementation may sample outside of the src-rect + * (if specified) by half the width of filter. This allows greater flexibility + * to the implementation and can make the draw much faster. + */ + kFast_SrcRectConstraint, + }; + + /** Draw the specified image, scaling and translating so that it fills the specified + * dst rect. If the src rect is non-null, only that subset of the image is transformed + * and drawn. + * + * @param image The image to be drawn + * @param src Optional: specify the subset of the image to be drawn + * @param dst The destination rectangle where the scaled/translated + * image will be drawn + * @param paint The paint used to draw the image, or NULL + * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect. + */ + void drawImageRect(const SkImage* image, const SkRect& src, const SkRect& dst, + const SkPaint* paint, + SrcRectConstraint constraint = kStrict_SrcRectConstraint); + // variant that takes src SkIRect + void drawImageRect(const SkImage* image, const SkIRect& isrc, const SkRect& dst, + const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); + // variant that assumes src == image-bounds + void drawImageRect(const SkImage* image, const SkRect& dst, const SkPaint* paint, + SrcRectConstraint = kStrict_SrcRectConstraint); + + /** + * Draw the image stretched differentially to fit into dst. + * center is a rect within the image, and logically divides the image + * into 9 sections (3x3). For example, if the middle pixel of a [5x5] + * image is the "center", then the center-rect should be [2, 2, 3, 3]. + * + * If the dst is >= the image size, then... + * - The 4 corners are not stretched at all. + * - The sides are stretched in only one axis. + * - The center is stretched in both axes. + * Else, for each axis where dst < image, + * - The corners shrink proportionally + * - The sides (along the shrink axis) and center are not drawn + */ + void drawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, + const SkPaint* paint = NULL); /** Draw the specified bitmap, with its top/left corner at (x,y), using the specified paint, transformed by the current matrix. Note: if the paint @@ -815,51 +865,27 @@ public: @param top The position of the top side of the bitmap being drawn @param paint The paint used to draw the bitmap, or NULL */ - virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, - const SkPaint* paint = NULL); + void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top, + const SkPaint* paint = NULL); - enum DrawBitmapRectFlags { - kNone_DrawBitmapRectFlag = 0x0, - /** - * When filtering is enabled, allow the color samples outside of - * the src rect (but still in the src bitmap) to bleed into the - * drawn portion - */ - kBleed_DrawBitmapRectFlag = 0x1, - }; - - /** Draw the specified bitmap, with the specified matrix applied (before the - canvas' matrix is applied). - @param bitmap The bitmap to be drawn - @param src Optional: specify the subset of the bitmap to be drawn - @param dst The destination rectangle where the scaled/translated - image will be drawn - @param paint The paint used to draw the bitmap, or NULL - */ - virtual void drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, - const SkRect& dst, - const SkPaint* paint = NULL, - DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag); - - void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, - const SkPaint* paint = NULL) { - this->drawBitmapRectToRect(bitmap, NULL, dst, paint, kNone_DrawBitmapRectFlag); - } - - void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* isrc, - const SkRect& dst, const SkPaint* paint = NULL, - DrawBitmapRectFlags flags = kNone_DrawBitmapRectFlag) { - SkRect realSrcStorage; - SkRect* realSrcPtr = NULL; - if (isrc) { - realSrcStorage.set(*isrc); - realSrcPtr = &realSrcStorage; - } - this->drawBitmapRectToRect(bitmap, realSrcPtr, dst, paint, flags); - } - - virtual void drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m, - const SkPaint* paint = NULL); + /** Draw the specified bitmap, scaling and translating so that it fills the specified + * dst rect. If the src rect is non-null, only that subset of the bitmap is transformed + * and drawn. + * + * @param bitmap The bitmap to be drawn + * @param src Optional: specify the subset of the bitmap to be drawn + * @param dst The destination rectangle where the scaled/translated + * bitmap will be drawn + * @param paint The paint used to draw the bitmap, or NULL + * @param constraint Control the tradeoff between speed and exactness w.r.t. the src-rect. + */ + void drawBitmapRect(const SkBitmap& bitmap, const SkRect& src, const SkRect& dst, + const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); + // variant where src is SkIRect + void drawBitmapRect(const SkBitmap& bitmap, const SkIRect& isrc, const SkRect& dst, + const SkPaint* paint, SrcRectConstraint = kStrict_SrcRectConstraint); + void drawBitmapRect(const SkBitmap& bitmap, const SkRect& dst, const SkPaint* paint, + SrcRectConstraint = kStrict_SrcRectConstraint); /** * Draw the bitmap stretched differentially to fit into dst. @@ -875,8 +901,8 @@ public: * - The corners shrink proportionally * - The sides (along the shrink axis) and center are not drawn */ - virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, - const SkRect& dst, const SkPaint* paint = NULL); + void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, + const SkPaint* paint = NULL); /** Draw the specified bitmap, with its top/left corner at (x,y), NOT transformed by the current matrix. Note: if the paint @@ -889,8 +915,7 @@ public: @param top The position of the top side of the bitmap being drawn @param paint The paint used to draw the bitmap, or NULL */ - virtual void drawSprite(const SkBitmap& bitmap, int left, int top, - const SkPaint* paint = NULL); + void drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint = NULL); /** Draw the text, with origin at (x,y), using the specified paint. The origin is interpreted based on the Align setting in the paint. @@ -900,8 +925,8 @@ public: @param y The y-coordinate of the origin of the text being drawn @param paint The paint used for the text (e.g. color, size, style) */ - SK_LEGACY_DRAWTEXT_VIRTUAL void drawText(const void* text, size_t byteLength, SkScalar x, - SkScalar y, const SkPaint& paint); + void drawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, + const SkPaint& paint); /** Draw the text, with each character/glyph origin specified by the pos[] array. The origin is interpreted by the Align setting in the paint. @@ -910,8 +935,8 @@ public: @param pos Array of positions, used to position each character @param paint The paint used for the text (e.g. color, size, style) */ - SK_LEGACY_DRAWTEXT_VIRTUAL void drawPosText(const void* text, size_t byteLength, - const SkPoint pos[], const SkPaint& paint); + void drawPosText(const void* text, size_t byteLength, const SkPoint pos[], + const SkPaint& paint); /** Draw the text, with each character/glyph origin specified by the x coordinate taken from the xpos[] array, and the y from the constY param. @@ -922,9 +947,8 @@ public: @param constY The shared Y coordinate for all of the positions @param paint The paint used for the text (e.g. color, size, style) */ - SK_LEGACY_DRAWTEXT_VIRTUAL void drawPosTextH(const void* text, size_t byteLength, - const SkScalar xpos[], SkScalar constY, - const SkPaint& paint); + void drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, + const SkPaint& paint); /** Draw the text, with origin at (x,y), using the specified paint, along the specified path. The paint's Align setting determins where along the @@ -938,8 +962,7 @@ public: position the text @param paint The paint used for the text */ - void drawTextOnPathHV(const void* text, size_t byteLength, - const SkPath& path, SkScalar hOffset, + void drawTextOnPathHV(const void* text, size_t byteLength, const SkPath& path, SkScalar hOffset, SkScalar vOffset, const SkPaint& paint); /** Draw the text, with origin at (x,y), using the specified paint, along @@ -952,17 +975,16 @@ public: mapped onto the path @param paint The paint used for the text */ - SK_LEGACY_DRAWTEXT_VIRTUAL void drawTextOnPath(const void* text, size_t byteLength, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint); + void drawTextOnPath(const void* text, size_t byteLength, const SkPath& path, + const SkMatrix* matrix, const SkPaint& paint); - /** PRIVATE / EXPERIMENTAL -- do not call - Perform back-end analysis/optimization of a picture. This may attach - optimization data to the picture which can be used by a later - drawPicture call. - @param picture The recorded drawing commands to analyze/optimize + /** Draw the text blob, offset by (x,y), using the specified paint. + @param blob The text blob to be drawn + @param x The x-offset of the text being drawn + @param y The y-offset of the text being drawn + @param paint The paint used for the text (e.g. color, size, style) */ - void EXPERIMENTAL_optimize(const SkPicture* picture); + void drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint); /** Draw the picture into this canvas. This method effective brackets the playback of the picture's draw calls with save/restore, so the state @@ -970,7 +992,23 @@ public: @param picture The recorded drawing commands to playback into this canvas. */ - void drawPicture(const SkPicture* picture); + void drawPicture(const SkPicture* picture) { + this->drawPicture(picture, NULL, NULL); + } + + /** + * Draw the picture into this canvas. + * + * If matrix is non-null, apply that matrix to the CTM when drawing this picture. This is + * logically equivalent to + * save/concat/drawPicture/restore + * + * If paint is non-null, draw the picture into a temporary buffer, and then apply the paint's + * alpha/colorfilter/imagefilter/xfermode to that buffer as it is drawn to the canvas. + * This is logically equivalent to + * saveLayer(paint)/drawPicture/restore + */ + void drawPicture(const SkPicture*, const SkMatrix* matrix, const SkPaint* paint); enum VertexMode { kTriangles_VertexMode, @@ -1001,48 +1039,64 @@ public: @param indexCount number of entries in the indices array (if not null) @param paint Specifies the shader/texture if present. */ - virtual void drawVertices(VertexMode vmode, int vertexCount, - const SkPoint vertices[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint& paint); + void drawVertices(VertexMode vmode, int vertexCount, + const SkPoint vertices[], const SkPoint texs[], + const SkColor colors[], SkXfermode* xmode, + const uint16_t indices[], int indexCount, + const SkPaint& paint); - /** Send a blob of data to the canvas. - For canvases that draw, this call is effectively a no-op, as the data - is not parsed, but just ignored. However, this call exists for - subclasses like SkPicture's recording canvas, that can store the data - and then play it back later (via another call to drawData). - */ - virtual void drawData(const void* data, size_t length) { - // do nothing. Subclasses may do something with the data - } + /** + Draw a cubic coons patch - /** Add comments. beginCommentGroup/endCommentGroup open/close a new group. - Each comment added via addComment is notionally attached to its - enclosing group. Top-level comments simply belong to no group. + @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order + starting at the top left corner. + @param colors specifies the colors for the corners which will be bilerp across the patch, + their order is clockwise starting at the top left corner. + @param texCoords specifies the texture coordinates that will be bilerp across the patch, + their order is the same as the colors. + @param xmode specifies how are the colors and the textures combined if both of them are + present. + @param paint Specifies the shader/texture if present. */ - virtual void beginCommentGroup(const char* description) { - // do nothing. Subclasses may do something - } - virtual void addComment(const char* kywd, const char* value) { - // do nothing. Subclasses may do something - } - virtual void endCommentGroup() { - // do nothing. Subclasses may do something + void drawPatch(const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint); + + /** + * Draw a set of sprites from the atlas. Each is specified by a tex rectangle in the + * coordinate space of the atlas, and a corresponding xform which transforms the tex rectangle + * into a quad. + * + * xform maps [0, 0, tex.width, tex.height] -> quad + * + * The color array is optional. When specified, each color modulates the pixels in its + * corresponding quad (via the specified SkXfermode::Mode). + * + * The cullRect is optional. When specified, it must be a conservative bounds of all of the + * resulting transformed quads, allowing the canvas to skip drawing if the cullRect does not + * intersect the current clip. + * + * The paint is optional. If specified, its antialiasing, alpha, color-filter, image-filter + * and xfermode are used to affect each of the quads. + */ + void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], + const SkColor colors[], int count, SkXfermode::Mode, const SkRect* cullRect, + const SkPaint* paint); + + void drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], int count, + const SkRect* cullRect, const SkPaint* paint) { + this->drawAtlas(atlas, xform, tex, NULL, count, SkXfermode::kDst_Mode, cullRect, paint); } /** - * With this call the client asserts that subsequent draw operations (up to the - * matching popCull()) are fully contained within the given bounding box. The assertion - * is not enforced, but the information might be used to quick-reject command blocks, - * so an incorrect bounding box may result in incomplete rendering. + * Draw the contents of this drawable into the canvas. If the canvas is async + * (e.g. it is recording into a picture) then the drawable will be referenced instead, + * to have its draw() method called when the picture is finalized. + * + * If the intent is to force the contents of the drawable into this canvas immediately, + * then drawable->draw(canvas) may be called. */ - void pushCull(const SkRect& cullRect); - - /** - * Terminates the current culling block, and restores the previous one (if any). - */ - void popCull(); + void drawDrawable(SkDrawable* drawable, const SkMatrix* = NULL); + void drawDrawable(SkDrawable*, SkScalar x, SkScalar y); ////////////////////////////////////////////////////////////////////////// @@ -1085,25 +1139,13 @@ public: */ const SkMatrix& getTotalMatrix() const; -#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE - enum ClipType { - kEmpty_ClipType = 0, - kRect_ClipType, - kComplex_ClipType - }; - /** Returns a description of the total clip; may be cheaper than - getting the clip and querying it directly. - */ - virtual ClipType getClipType() const; -#endif - /** Return the clip stack. The clip stack stores all the individual * clips organized by the save/restore frame in which they were * added. * @return the current clip stack ("list" of individual clip elements) */ const SkClipStack* getClipStack() const { - return &fClipStack; + return fClipStack; } typedef SkCanvasClipVisitor ClipVisitor; @@ -1154,20 +1196,30 @@ public: bool fDone; }; - // don't call - const SkRegion& internal_private_getTotalClip() const; - // don't call - void internal_private_getTotalClipAsPath(SkPath*) const; // don't call GrRenderTarget* internal_private_accessTopLayerRenderTarget(); + // don't call + static void Internal_Private_SetIgnoreSaveLayerBounds(bool); + static bool Internal_Private_GetIgnoreSaveLayerBounds(); + static void Internal_Private_SetTreatSpriteAsBitmap(bool); + static bool Internal_Private_GetTreatSpriteAsBitmap(); + + // TEMP helpers until we switch virtual over to const& for src-rect + void legacy_drawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, + const SkPaint* paint, + SrcRectConstraint constraint = kStrict_SrcRectConstraint); + void legacy_drawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, + const SkPaint* paint, + SrcRectConstraint constraint = kStrict_SrcRectConstraint); + protected: // default impl defers to getDevice()->newSurface(info) - virtual SkSurface* onNewSurface(const SkImageInfo&); + virtual SkSurface* onNewSurface(const SkImageInfo&, const SkSurfaceProps&); // default impl defers to its device - virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes); - virtual void* onAccessTopLayerPixels(SkImageInfo*, size_t* rowBytes); + virtual bool onPeekPixels(SkPixmap*); + virtual bool onAccessTopLayerPixels(SkPixmap*); // Subclass save/restore notifiers. // Overriders should call the corresponding INHERITED method up the inheritance chain. @@ -1182,6 +1234,7 @@ protected: return kFullLayer_SaveLayerStrategy; } virtual void willRestore() {} + virtual void didRestore() {} virtual void didConcat(const SkMatrix&) {} virtual void didSetMatrix(const SkMatrix&) {} @@ -1201,6 +1254,39 @@ protected: const SkPath& path, const SkMatrix* matrix, const SkPaint& paint); + virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, + const SkPaint& paint); + + virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint); + + virtual void onDrawDrawable(SkDrawable*, const SkMatrix*); + + virtual void onDrawPaint(const SkPaint&); + virtual void onDrawRect(const SkRect&, const SkPaint&); + virtual void onDrawOval(const SkRect&, const SkPaint&); + virtual void onDrawRRect(const SkRRect&, const SkPaint&); + virtual void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&); + virtual void onDrawVertices(VertexMode, int vertexCount, const SkPoint vertices[], + const SkPoint texs[], const SkColor colors[], SkXfermode*, + const uint16_t indices[], int indexCount, const SkPaint&); + + virtual void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], + int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*); + virtual void onDrawPath(const SkPath&, const SkPaint&); + virtual void onDrawImage(const SkImage*, SkScalar dx, SkScalar dy, const SkPaint*); + virtual void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*, + SrcRectConstraint); + virtual void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, + const SkPaint*); + + virtual void onDrawBitmap(const SkBitmap&, SkScalar dx, SkScalar dy, const SkPaint*); + virtual void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*, + SrcRectConstraint); + virtual void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, + const SkPaint*); + virtual void onDrawSprite(const SkBitmap&, int left, int top, const SkPaint*); + enum ClipEdgeStyle { kHard_ClipEdgeStyle, kSoft_ClipEdgeStyle @@ -1213,7 +1299,7 @@ protected: virtual void onDiscard(); - virtual void onDrawPicture(const SkPicture* picture); + virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*); // Returns the canvas to be used by DrawIter. Default implementation // returns this. Subclasses that encapsulate an indirect canvas may @@ -1229,30 +1315,40 @@ protected: SkIRect* intersection, const SkImageFilter* imageFilter = NULL); - // Called by child classes that override clipPath and clipRRect to only - // track fast conservative clip bounds, rather than exact clips. - void updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op, - bool inverseFilled); +private: + enum ShaderOverrideOpacity { + kNone_ShaderOverrideOpacity, //!< there is no overriding shader (bitmap or image) + kOpaque_ShaderOverrideOpacity, //!< the overriding shader is opaque + kNotOpaque_ShaderOverrideOpacity, //!< the overriding shader may not be opaque + }; // notify our surface (if we have one) that we are about to draw, so it // can perform copy-on-write or invalidate any cached images - void predrawNotify(); + void predrawNotify(bool willOverwritesEntireSurface = false); + void predrawNotify(const SkRect* rect, const SkPaint* paint, ShaderOverrideOpacity); + void predrawNotify(const SkRect* rect, const SkPaint* paint, bool shaderOverrideIsOpaque) { + this->predrawNotify(rect, paint, shaderOverrideIsOpaque ? kOpaque_ShaderOverrideOpacity + : kNotOpaque_ShaderOverrideOpacity); + } - virtual void onPushCull(const SkRect& cullRect); - virtual void onPopCull(); - -private: class MCRec; - SkClipStack fClipStack; + SkAutoTUnref fClipStack; SkDeque fMCStack; // points to top of stack MCRec* fMCRec; // the first N recs that can fit here mean we won't call malloc - uint32_t fMCRecStorage[32]; + enum { + kMCRecSize = 128, // most recent measurement + kMCRecCount = 32, // common depth for save/restores + kDeviceCMSize = 136, // most recent measurement + }; + intptr_t fMCRecStorage[kMCRecSize * kMCRecCount / sizeof(intptr_t)]; + intptr_t fDeviceCMStorage[kDeviceCMSize / sizeof(intptr_t)]; - int fSaveLayerCount; // number of successful saveLayer calls - int fCullCount; // number of active culls + const SkSurfaceProps fProps; + + int fSaveCount; // value returned by getSaveCount() SkMetaData* fMetaData; @@ -1267,25 +1363,37 @@ private: bool fDeviceCMDirty; // cleared by updateDeviceCMCache() void updateDeviceCMCache(); + void doSave(); + void checkForDeferredSave(); + friend class SkDrawIter; // needs setupDrawForLayerDevice() friend class AutoDrawLooper; friend class SkLua; // needs top layer size and offset friend class SkDebugCanvas; // needs experimental fAllowSimplifyClip - friend class SkDeferredDevice; // needs getTopDevice() friend class SkSurface_Raster; // needs getDevice() + friend class SkRecorder; // InitFlags + friend class SkNoSaveLayerCanvas; // InitFlags + friend class SkPictureImageFilter; // SkCanvas(SkBaseDevice*, SkSurfaceProps*, InitFlags) + friend class SkPictureRecord; // predrawNotify (why does it need it? ) - SkBaseDevice* createLayerDevice(const SkImageInfo&); + enum InitFlags { + kDefault_InitFlags = 0, + kConservativeRasterClip_InitFlag = 1 << 0, + }; + SkCanvas(const SkIRect& bounds, InitFlags); + SkCanvas(SkBaseDevice* device, InitFlags); - SkBaseDevice* init(SkBaseDevice*); + void resetForNextPicture(const SkIRect& bounds); - /** - * DEPRECATED - * - * Specify a device for this canvas to draw into. If it is not null, its - * reference count is incremented. If the canvas was already holding a - * device, its reference count is decremented. The new device is returned. - */ - SkBaseDevice* setRootDevice(SkBaseDevice* device); + // needs gettotalclip() + friend class SkCanvasStateUtils; + + // call this each time we attach ourselves to a device + // - constructor + // - internalSaveLayer + void setupDevice(SkBaseDevice*); + + SkBaseDevice* init(SkBaseDevice*, InitFlags); /** * Gets the size/origin of the top level layer in global canvas coordinates. We don't want this @@ -1294,21 +1402,15 @@ private: SkISize getTopLayerSize() const; SkIPoint getTopLayerOrigin() const; - // internal methods are not virtual, so they can safely be called by other - // canvas apis, without confusing subclasses (like SkPictureRecording) - void internalDrawBitmap(const SkBitmap&, const SkMatrix& m, const SkPaint* paint); void internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, const SkPaint* paint, - DrawBitmapRectFlags flags); - void internalDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, - const SkRect& dst, const SkPaint* paint); + SrcRectConstraint); void internalDrawPaint(const SkPaint& paint); - int internalSaveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags, bool justForImageFilter, SaveLayerStrategy strategy); - void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*); + void internalSaveLayer(const SkRect* bounds, const SkPaint*, SaveFlags, SaveLayerStrategy); + void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*, bool isBitmapDevice); // shared by save() and saveLayer() - int internalSave(); + void internalSave(); void internalRestore(); static void DrawRect(const SkDraw& draw, const SkPaint& paint, const SkRect& r, SkScalar textSize); @@ -1316,6 +1418,17 @@ private: const char text[], size_t byteLength, SkScalar x, SkScalar y); + // only for canvasutils + const SkRegion& internal_private_getTotalClip() const; + + /* + * Returns true if drawing the specified rect (or all if it is null) with the specified + * paint (or default if null) would overwrite the entire root device of the canvas + * (i.e. the canvas' surface if it had one). + */ + bool wouldOverwriteEntireSurface(const SkRect*, const SkPaint*, ShaderOverrideOpacity) const; + + /* These maintain a cache of the clip bounds in local coordinates, (converted to 2s-compliment if floats are slow). */ @@ -1323,6 +1436,7 @@ private: mutable bool fCachedLocalClipBoundsDirty; bool fAllowSoftClip; bool fAllowSimplifyClip; + const bool fConservativeRasterClip; const SkRect& getLocalClipBounds() const { if (fCachedLocalClipBoundsDirty) { @@ -1346,9 +1460,6 @@ private: }; #ifdef SK_DEBUG - // The cull stack rects are in device-space - SkTDArray fCullStack; - void validateCull(const SkIRect&); void validateClip() const; #else void validateClip() const {} @@ -1394,28 +1505,6 @@ private: }; #define SkAutoCanvasRestore(...) SK_REQUIRE_LOCAL_VAR(SkAutoCanvasRestore) -/** Stack helper class to automatically open and close a comment block - */ -class SkAutoCommentBlock : SkNoncopyable { -public: - SkAutoCommentBlock(SkCanvas* canvas, const char* description) { - fCanvas = canvas; - if (NULL != fCanvas) { - fCanvas->beginCommentGroup(description); - } - } - - ~SkAutoCommentBlock() { - if (NULL != fCanvas) { - fCanvas->endCommentGroup(); - } - } - -private: - SkCanvas* fCanvas; -}; -#define SkAutoCommentBlock(...) SK_REQUIRE_LOCAL_VAR(SkAutoCommentBlock) - /** * If the caller wants read-only access to the pixels in a canvas, it can just * call canvas->peekPixels(), since that is the fastest way to "peek" at the diff --git a/gfx/skia/skia/include/core/SkChunkAlloc.h b/gfx/skia/skia/include/core/SkChunkAlloc.h index e13e2b99c640..9699842e6b42 100644 --- a/gfx/skia/skia/include/core/SkChunkAlloc.h +++ b/gfx/skia/skia/include/core/SkChunkAlloc.h @@ -22,6 +22,11 @@ public: * pointers. */ void reset(); + /** + * Reset to 0 used bytes preserving as much memory as possible. + * This invalidates all returned pointers. + */ + void rewind(); enum AllocFailType { kReturnNil_AllocFailType, @@ -43,7 +48,8 @@ public: size_t totalCapacity() const { return fTotalCapacity; } size_t totalUsed() const { return fTotalUsed; } - int blockCount() const { return fBlockCount; } + SkDEBUGCODE(int blockCount() const { return fBlockCount; }) + SkDEBUGCODE(size_t totalLost() const { return fTotalLost; }) /** * Returns true if the specified address is within one of the chunks, and @@ -60,9 +66,13 @@ private: size_t fChunkSize; size_t fTotalCapacity; size_t fTotalUsed; // will be <= fTotalCapacity - int fBlockCount; + SkDEBUGCODE(int fBlockCount;) + SkDEBUGCODE(size_t fTotalLost;) // will be <= fTotalCapacity Block* newBlock(size_t bytes, AllocFailType ftype); + Block* addBlockIfNecessary(size_t bytes, AllocFailType ftype); + + SkDEBUGCODE(void validate();) }; #endif diff --git a/gfx/skia/skia/include/core/SkClipStack.h b/gfx/skia/skia/include/core/SkClipStack.h index 95e41e622087..b74e47697f91 100644 --- a/gfx/skia/skia/include/core/SkClipStack.h +++ b/gfx/skia/skia/include/core/SkClipStack.h @@ -24,7 +24,7 @@ class SkCanvasClipVisitor; // (i.e., the fSaveCount in force when it was added). Restores are thus // implemented by removing clips from fDeque that have an fSaveCount larger // then the freshly decremented count. -class SK_API SkClipStack { +class SK_API SkClipStack : public SkNVRefCnt { public: enum BoundsType { // The bounding box contains all the pixels that can be written to @@ -309,13 +309,6 @@ public: BoundsType* boundType, bool* isIntersectionOfRects = NULL) const; - /** - * Takes an input rect in device space and conservatively clips it to the - * clip-stack. If false is returned then the rect does not intersect the - * clip and is unmodified. - */ - bool intersectRectWithClip(SkRect* devRect) const; - /** * Returns true if the input rect in device space is entirely contained * by the clip. A return value of false does not guarantee that the rect @@ -323,6 +316,12 @@ public: */ bool quickContains(const SkRect& devRect) const; + /** + * Flattens the clip stack into a single SkPath. Returns true if any of + * the clip stack components requires anti-aliasing. + */ + bool asPath(SkPath* path) const; + void clipDevRect(const SkIRect& ir, SkRegion::Op op) { SkRect r; r.set(ir); diff --git a/gfx/skia/skia/include/core/SkColor.h b/gfx/skia/skia/include/core/SkColor.h index 7faeca7f84b3..1ba1331c1a72 100644 --- a/gfx/skia/skia/include/core/SkColor.h +++ b/gfx/skia/skia/include/core/SkColor.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,11 +5,11 @@ * found in the LICENSE file. */ - #ifndef SkColor_DEFINED #define SkColor_DEFINED #include "SkScalar.h" +#include "SkTypes.h" /** \file SkColor.h @@ -161,9 +160,4 @@ SK_API SkPMColor SkPreMultiplyColor(SkColor c); */ typedef SkPMColor (*SkXfermodeProc)(SkPMColor src, SkPMColor dst); -/** Define a function pointer type for combining a premultiplied src color - and a 16bit device color. -*/ -typedef uint16_t (*SkXfermodeProc16)(SkPMColor src, uint16_t dst); - #endif diff --git a/gfx/skia/skia/include/core/SkColorFilter.h b/gfx/skia/skia/include/core/SkColorFilter.h index 25e6bbe746bb..57650fbd9859 100644 --- a/gfx/skia/skia/include/core/SkColorFilter.h +++ b/gfx/skia/skia/include/core/SkColorFilter.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,17 +5,17 @@ * found in the LICENSE file. */ - #ifndef SkColorFilter_DEFINED #define SkColorFilter_DEFINED #include "SkColor.h" #include "SkFlattenable.h" +#include "SkTDArray.h" #include "SkXfermode.h" -class SkBitmap; -class GrEffect; class GrContext; +class GrFragmentProcessor; +class SkBitmap; /** * ColorFilters are optional objects in the drawing pipeline. When present in @@ -28,8 +27,6 @@ class GrContext; */ class SK_API SkColorFilter : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkColorFilter) - /** * If the filter can be represented by a source color plus Mode, this * returns true, and sets (if not NULL) the color and mode appropriately. @@ -69,34 +66,27 @@ public: @param count the number of entries in the src[] and result[] arrays @param result written by the filter */ - virtual void filterSpan(const SkPMColor src[], int count, - SkPMColor result[]) const = 0; - /** Called with a scanline of colors, as if there was a shader installed. - The implementation writes out its filtered version into result[]. - Note: shader and result may be the same buffer. - @param src array of colors, possibly generated by a shader - @param count the number of entries in the src[] and result[] arrays - @param result written by the filter - */ - virtual void filterSpan16(const uint16_t shader[], int count, - uint16_t result[]) const; + virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) const = 0; enum Flags { - /** If set the filter methods will not change the alpha channel of the - colors. + /** If set the filter methods will not change the alpha channel of the colors. */ kAlphaUnchanged_Flag = 0x01, - /** If set, this subclass implements filterSpan16(). If this flag is - set, then kAlphaUnchanged_Flag must also be set. - */ - kHasFilter16_Flag = 0x02 }; - /** Returns the flags for this filter. Override in subclasses to return - custom flags. + /** Returns the flags for this filter. Override in subclasses to return custom flags. */ virtual uint32_t getFlags() const { return 0; } + /** + * If this subclass can optimally createa composition with the inner filter, return it as + * a new filter (which the caller must unref() when it is done). If no such optimization + * is known, return NULL. + * + * e.g. result(color) == this_filter(inner(color)) + */ + virtual SkColorFilter* newComposed(const SkColorFilter* /*inner*/) const { return NULL; } + /** * Apply this colorfilter to the specified SkColor. This routine handles * converting to SkPMColor, calling the filter, and then converting back @@ -123,10 +113,31 @@ public: */ static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add); - /** A subclass may implement this factory function to work with the GPU backend. If the return - is non-NULL then the caller owns a ref on the returned object. + /** Construct a colorfilter whose effect is to first apply the inner filter and then apply + * the outer filter to the result of the inner's. + * The reference counts for outer and inner are incremented. + * + * Due to internal limits, it is possible that this will return NULL, so the caller must + * always check. */ - virtual GrEffect* asNewEffect(GrContext*) const; + static SkColorFilter* CreateComposeFilter(SkColorFilter* outer, SkColorFilter* inner); + + /** + * A subclass may implement this factory function to work with the GPU backend. It returns + * a GrFragmentProcessor that implemets the color filter in GPU shader code. + * + * The fragment processor receives a premultiplied input color and produces a premultiplied + * output color. + * + * A null return indicates that the color filter isn't implemented for the GPU backend. + */ + virtual const GrFragmentProcessor* asFragmentProcessor(GrContext*) const { + return nullptr; + } + + bool affectsTransparentBlack() const { + return this->filterColor(0) != 0; + } SK_TO_STRING_PUREVIRT() @@ -135,9 +146,18 @@ public: protected: SkColorFilter() {} - SkColorFilter(SkReadBuffer& rb) : INHERITED(rb) {} private: + /* + * Returns 1 if this is a single filter (not a composition of other filters), otherwise it + * reutrns the number of leaf-node filters in a composition. This should be the same value + * as the number of GrFragmentProcessors returned by asFragmentProcessors's array parameter. + * + * e.g. compose(filter, compose(compose(filter, filter), filter)) --> 4 + */ + virtual int privateComposedFilterCount() const { return 1; } + friend class SkComposeColorFilter; + typedef SkFlattenable INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkColorPriv.h b/gfx/skia/skia/include/core/SkColorPriv.h index 6f23f9be1498..6347660dbc99 100644 --- a/gfx/skia/skia/include/core/SkColorPriv.h +++ b/gfx/skia/skia/include/core/SkColorPriv.h @@ -193,7 +193,7 @@ static inline unsigned Sk255To256(U8CPU value) { /** Multiplify value by 0..256, and shift the result down 8 (i.e. return (value * alpha256) >> 8) */ -#define SkAlphaMul(value, alpha256) (SkMulS16(value, alpha256) >> 8) +#define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8) // The caller may want negative values, so keep all params signed (int) // so we don't accidentally slip into unsigned math and lose the sign @@ -213,11 +213,21 @@ static inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) { SkASSERT((int16_t)dst == dst); SkASSERT((uint8_t)alpha == alpha); - int prod = SkMulS16(src - dst, alpha) + 128; + int prod = (src - dst) * alpha + 128; prod = (prod + (prod >> 8)) >> 8; return dst + prod; } +static inline U8CPU SkUnitScalarClampToByte(SkScalar x) { + if (x < 0) { + return 0; + } + if (x >= SK_Scalar1) { + return 255; + } + return SkScalarToFixed(x) >> 8; +} + #define SK_R16_BITS 5 #define SK_G16_BITS 6 #define SK_B16_BITS 5 @@ -281,6 +291,16 @@ static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) { // this helper explicitly returns a clean 16bit value (but slower) #define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s) +/** Blend pre-expanded RGB32 with 16bit color value by the 0..32 scale parameter. + The computation yields only 16bits of valid data, but we claim to return + 32bits, so that the compiler won't generate extra instructions to "clean" + the top 16bits. +*/ +static inline U16CPU SkBlend32_RGB16(uint32_t src_expand, uint16_t dst, unsigned scale) { + uint32_t dst_expand = SkExpand_rgb_16(dst) * scale; + return SkCompact_rgb_16((src_expand + dst_expand) >> 5); +} + /** Blend src and dst 16bit colors by the 0..256 scale parameter. The computation yields only 16bits of valid data, but we claim to return 32bits, so that the compiler won't generate extra instructions to @@ -306,7 +326,8 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], do { uint32_t src32 = SkExpand_rgb_16(*src++); uint32_t dst32 = SkExpand_rgb_16(*dst); - *dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)); + *dst++ = static_cast( + SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5))); } while (--count > 0); } @@ -345,21 +366,31 @@ static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], #define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK) #ifdef SK_DEBUG - static inline void SkPMColorAssert(SkPMColor c) { - unsigned a = SkGetPackedA32(c); - unsigned r = SkGetPackedR32(c); - unsigned g = SkGetPackedG32(c); - unsigned b = SkGetPackedB32(c); - - SkA32Assert(a); - SkASSERT(r <= a); - SkASSERT(g <= a); - SkASSERT(b <= a); - } + #define SkPMColorAssert(color_value) \ + do { \ + SkPMColor pm_color_value = (color_value); \ + uint32_t alpha_color_value = SkGetPackedA32(pm_color_value); \ + SkA32Assert(alpha_color_value); \ + SkASSERT(SkGetPackedR32(pm_color_value) <= alpha_color_value); \ + SkASSERT(SkGetPackedG32(pm_color_value) <= alpha_color_value); \ + SkASSERT(SkGetPackedB32(pm_color_value) <= alpha_color_value); \ + } while (false) #else #define SkPMColorAssert(c) #endif +static inline bool SkPMColorValid(SkPMColor c) { + auto a = SkGetPackedA32(c); + bool valid = a <= SK_A32_MASK + && SkGetPackedR32(c) <= a + && SkGetPackedG32(c) <= a + && SkGetPackedB32(c) <= a; + if (valid) { + SkPMColorAssert(c); // Make sure we're consistent when it counts. + } + return valid; +} + /** * Pack the components into a SkPMColor, checking (in the debug version) that * the components are 0..255, and are already premultiplied (i.e. alpha >= color) @@ -787,7 +818,7 @@ static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r, (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT)); } -static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) { +static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c, int scale) { SkASSERT(scale <= 16); const unsigned mask = 0xF0F; //gMask_0F0F; @@ -797,14 +828,14 @@ static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) { unsigned ag = ((c >> 4) & mask) * scale; return (rb & mask) | (ag & ~mask); #else - c = (c & mask) | ((c & (mask << 4)) << 12); - c = c * scale >> 4; - return (c & mask) | ((c >> 12) & (mask << 4)); + unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12); + unsigned scaled_c = (expanded_c * scale) >> 4; + return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4)); #endif } /** Expand the SkPMColor16 color into a 32bit value that can be scaled all at - once by a value up to 16. Used in conjunction with SkCompact_4444. + once by a value up to 16. */ static inline uint32_t SkExpand_4444(U16CPU c) { SkASSERT(c == (uint16_t)c); @@ -813,18 +844,6 @@ static inline uint32_t SkExpand_4444(U16CPU c) { return (c & mask) | ((c & ~mask) << 12); } -/** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16. - NOTE: this explicitly does not clean the top 16 bits (which may be garbage). - It does this for speed, since if it is being written directly to 16bits of - memory, the top 16bits will be ignored. Casting the result to uint16_t here - would add 2 more instructions, slow us down. It is up to the caller to - perform the cast if needed. -*/ -static inline U16CPU SkCompact_4444(uint32_t c) { - const unsigned mask = 0xF0F; //gMask_0F0F; - return (c & mask) | ((c >> 12) & ~mask); -} - static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { unsigned sa = SkGetPackedA4444(s); unsigned sr = SkR4444ToR565(SkGetPackedR4444(s)); @@ -856,22 +875,6 @@ static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale1 return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst); } -static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16) { - SkASSERT((unsigned)scale16 <= 16); - - uint32_t src32 = SkExpand_4444(src) * scale16; - // the scaled srcAlpha is the bottom byte -#ifdef SK_DEBUG - { - unsigned srcA = SkGetPackedA4444(src) * scale16; - SkASSERT(srcA == (src32 & 0xFF)); - } -#endif - unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4; - uint32_t dst32 = SkExpand_4444(dst) * dstScale; - return SkCompact_4444((src32 + dst32) >> 4); -} - static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) { uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) | (SkGetPackedR4444(c) << SK_R32_SHIFT) | diff --git a/gfx/skia/skia/include/core/SkColorTable.h b/gfx/skia/skia/include/core/SkColorTable.h index e4c8c86c13dd..ccea7ed550bf 100644 --- a/gfx/skia/skia/include/core/SkColorTable.h +++ b/gfx/skia/skia/include/core/SkColorTable.h @@ -10,6 +10,7 @@ #ifndef SkColorTable_DEFINED #define SkColorTable_DEFINED +#include "../private/SkOncePtr.h" #include "SkColor.h" #include "SkFlattenable.h" #include "SkImageInfo.h" @@ -18,75 +19,64 @@ SkColorTable holds an array SkPMColors (premultiplied 32-bit colors) used by 8-bit bitmaps, where the bitmap bytes are interpreted as indices into the colortable. -*/ -class SkColorTable : public SkRefCnt { -public: - SK_DECLARE_INST_COUNT(SkColorTable) - /** Makes a deep copy of colors. + SkColorTable is thread-safe. +*/ +class SK_API SkColorTable : public SkRefCnt { +public: + /** Copy up to 256 colors into a new SkColorTable. */ - SkColorTable(const SkColorTable& src); - SkColorTable(const SkPMColor colors[], int count, - SkAlphaType alphaType = kPremul_SkAlphaType); + SkColorTable(const SkPMColor colors[], int count); virtual ~SkColorTable(); - SkAlphaType alphaType() const { return (SkAlphaType)fAlphaType; } - - bool isOpaque() const { - return SkAlphaTypeIsOpaque(this->alphaType()); - } - /** Returns the number of colors in the table. - */ + */ int count() const { return fCount; } /** Returns the specified color from the table. In the debug build, this asserts that - the index is in range (0 <= index < count). - */ + * the index is in range (0 <= index < count). + */ SkPMColor operator[](int index) const { - SkASSERT(fColors != NULL && (unsigned)index < fCount); + SkASSERT(fColors != NULL && (unsigned)index < (unsigned)fCount); return fColors[index]; } - /** - * Return the array of colors for reading. This must be balanced by a call - * to unlockColors(). + /** Return the array of colors for reading. */ - const SkPMColor* lockColors() { - SkDEBUGCODE(sk_atomic_inc(&fColorLockCount);) - return fColors; - } + const SkPMColor* readColors() const { return fColors; } - /** - * Balancing call to lockColors(). + /** read16BitCache() returns the array of RGB16 colors that mirror the 32bit colors. */ - void unlockColors(); + const uint16_t* read16BitCache() const; - /** Similar to lockColors(), lock16BitCache() returns the array of - RGB16 colors that mirror the 32bit colors. However, this function - will return null if kColorsAreOpaque_Flag is not set. - Also, unlike lockColors(), the returned array here cannot be modified. - */ - const uint16_t* lock16BitCache(); - /** Balancing call to lock16BitCache(). - */ - void unlock16BitCache() { - SkASSERT(f16BitCacheLockCount > 0); - SkDEBUGCODE(f16BitCacheLockCount -= 1); - } - - explicit SkColorTable(SkReadBuffer&); void writeToBuffer(SkWriteBuffer&) const; -private: - SkPMColor* fColors; - uint16_t* f16BitCache; - uint16_t fCount; - uint8_t fAlphaType; - SkDEBUGCODE(int fColorLockCount;) - SkDEBUGCODE(int f16BitCacheLockCount;) + // may return null + static SkColorTable* Create(SkReadBuffer&); - void inval16BitCache(); +private: + enum AllocatedWithMalloc { + kAllocatedWithMalloc + }; + // assumes ownership of colors (assumes it was allocated w/ malloc) + SkColorTable(SkPMColor* colors, int count, AllocatedWithMalloc); + + SkPMColor* fColors; + SkOncePtr f16BitCache; + int fCount; + + void init(const SkPMColor* colors, int count); + + friend class SkImageGenerator; + // Only call if no other thread or cache has seen this table. + void dangerous_overwriteColors(const SkPMColor newColors[], int count) { + if (count < 0 || count > fCount) { + sk_throw(); + } + // assumes that f16BitCache nas NOT been initialized yet, so we don't try to update it + memcpy(fColors, newColors, count * sizeof(SkPMColor)); + fCount = count; // update fCount, in case count is smaller + } typedef SkRefCnt INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkComposeShader.h b/gfx/skia/skia/include/core/SkComposeShader.h index 3a28e1e03d8d..bc9d932ee5f2 100644 --- a/gfx/skia/skia/include/core/SkComposeShader.h +++ b/gfx/skia/skia/include/core/SkComposeShader.h @@ -34,7 +34,14 @@ public: SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL); virtual ~SkComposeShader(); - virtual size_t contextSize() const SK_OVERRIDE; + size_t contextSize() const override; + +#if SK_SUPPORT_GPU + const GrFragmentProcessor* asFragmentProcessor(GrContext*, + const SkMatrix& viewM, + const SkMatrix* localMatrix, + SkFilterQuality) const override; +#endif class ComposeShaderContext : public SkShader::Context { public: @@ -48,7 +55,7 @@ public: virtual ~ComposeShaderContext(); - virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; + void shadeSpan(int x, int y, SkPMColor[], int count) override; private: SkShader::Context* fShaderContextA; @@ -62,15 +69,15 @@ public: SkShader* getShaderB() { return fShaderB; } #endif - virtual bool asACompose(ComposeRec* rec) const SK_OVERRIDE; + bool asACompose(ComposeRec* rec) const override; SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader) protected: SkComposeShader(SkReadBuffer& ); - virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual Context* onCreateContext(const ContextRec&, void*) const SK_OVERRIDE; + void flatten(SkWriteBuffer&) const override; + Context* onCreateContext(const ContextRec&, void*) const override; private: SkShader* fShaderA; diff --git a/gfx/skia/skia/include/core/SkData.h b/gfx/skia/skia/include/core/SkData.h index fba2846c7045..60a98e00f004 100644 --- a/gfx/skia/skia/include/core/SkData.h +++ b/gfx/skia/skia/include/core/SkData.h @@ -1,4 +1,3 @@ - /* * Copyright 2011 Google Inc. * @@ -6,14 +5,14 @@ * found in the LICENSE file. */ - - #ifndef SkData_DEFINED #define SkData_DEFINED +#include + #include "SkRefCnt.h" -struct SkFILE; +class SkStream; /** * SkData holds an immutable data buffer. Not only is the data immutable, @@ -22,8 +21,6 @@ struct SkFILE; */ class SK_API SkData : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkData) - /** * Returns the number of bytes stored. */ @@ -44,6 +41,19 @@ public: return reinterpret_cast(fPtr); } + /** + * USE WITH CAUTION. + * This call will assert that the refcnt is 1, as a precaution against modifying the + * contents when another client/thread has access to the data. + */ + void* writable_data() { + if (fSize) { + // only assert we're unique if we're not empty + SkASSERT(this->unique()); + } + return fPtr; + } + /** * Helper to copy a range of the data into a caller-provided buffer. * Returns the actual number of bytes copied, after clamping offset and @@ -60,15 +70,21 @@ public: /** * Function that, if provided, will be called when the SkData goes out - * of scope, allowing for custom allocation/freeing of the data. + * of scope, allowing for custom allocation/freeing of the data's contents. */ - typedef void (*ReleaseProc)(const void* ptr, size_t length, void* context); + typedef void (*ReleaseProc)(const void* ptr, void* context); /** * Create a new dataref by copying the specified data */ static SkData* NewWithCopy(const void* data, size_t length); + /** + * Create a new data with uninitialized contents. The caller should call writable_data() + * to write into the buffer, but this must be done before another ref() is made. + */ + static SkData* NewUninitialized(size_t length); + /** * Create a new dataref by copying the specified c-string * (a null-terminated array of bytes). The returned SkData will have size() @@ -78,11 +94,18 @@ public: static SkData* NewWithCString(const char cstr[]); /** - * Create a new dataref, taking the data ptr as is, and using the + * Create a new dataref, taking the ptr as is, and using the * releaseproc to free it. The proc may be NULL. */ - static SkData* NewWithProc(const void* data, size_t length, - ReleaseProc proc, void* context); + static SkData* NewWithProc(const void* ptr, size_t length, ReleaseProc proc, void* context); + + /** + * Call this when the data parameter is already const and will outlive the lifetime of the + * SkData. Suitable for with const globals. + */ + static SkData* NewWithoutCopy(const void* data, size_t length) { + return NewWithProc(data, length, DummyReleaseProc, NULL); + } /** * Create a new dataref from a pointer allocated by malloc. The Data object @@ -97,13 +120,13 @@ public: static SkData* NewFromFileName(const char path[]); /** - * Create a new dataref from a SkFILE. - * This does not take ownership of the SkFILE, nor close it. - * The caller is free to close the SkFILE at its convenience. - * The SkFILE must be open for reading only. + * Create a new dataref from a stdio FILE. + * This does not take ownership of the FILE, nor close it. + * The caller is free to close the FILE at its convenience. + * The FILE must be open for reading only. * Returns NULL on failure. */ - static SkData* NewFromFILE(SkFILE* f); + static SkData* NewFromFILE(FILE* f); /** * Create a new dataref from a file descriptor. @@ -114,6 +137,13 @@ public: */ static SkData* NewFromFD(int fd); + /** + * Attempt to read size bytes into a SkData. If the read succeeds, return the data, + * else return NULL. Either way the stream's cursor may have been changed as a result + * of calling read(). + */ + static SkData* NewFromStream(SkStream*, size_t size); + /** * Create a new dataref using a subset of the data in the specified * src dataref. @@ -129,16 +159,29 @@ public: private: ReleaseProc fReleaseProc; void* fReleaseProcContext; - - const void* fPtr; + void* fPtr; size_t fSize; SkData(const void* ptr, size_t size, ReleaseProc, void* context); + explicit SkData(size_t size); // inplace new/delete virtual ~SkData(); + + // Objects of this type are sometimes created in a custom fashion using sk_malloc_throw and + // therefore must be sk_freed. We overload new to also call sk_malloc_throw so that memory + // can be unconditionally released using sk_free in an overloaded delete. Overloading regular + // new means we must also overload placement new. + void* operator new(size_t size) { return sk_malloc_throw(size); } + void* operator new(size_t, void* p) { return p; } + void operator delete(void* p) { sk_free(p); } + // Called the first time someone calls NewEmpty to initialize the singleton. - static SkData* NewEmptyImpl(); - static void DeleteEmpty(SkData*); + friend SkData* sk_new_empty_data(); + + // shared internal factory + static SkData* PrivateNewWithCopy(const void* srcOrNull, size_t length); + + static void DummyReleaseProc(const void*, void*) {} typedef SkRefCnt INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkDataTable.h b/gfx/skia/skia/include/core/SkDataTable.h index 9440000e00b4..798ca9c0c4ac 100644 --- a/gfx/skia/skia/include/core/SkDataTable.h +++ b/gfx/skia/skia/include/core/SkDataTable.h @@ -20,8 +20,6 @@ */ class SK_API SkDataTable : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkDataTable) - /** * Returns true if the table is empty (i.e. has no entries). */ diff --git a/gfx/skia/skia/include/core/SkDevice.h b/gfx/skia/skia/include/core/SkDevice.h index 4a9edee0ec45..c52c579424a2 100644 --- a/gfx/skia/skia/include/core/SkDevice.h +++ b/gfx/skia/skia/include/core/SkDevice.h @@ -9,47 +9,31 @@ #define SkDevice_DEFINED #include "SkRefCnt.h" -#include "SkBitmap.h" #include "SkCanvas.h" #include "SkColor.h" -#include "SkDeviceProperties.h" #include "SkImageFilter.h" +#include "SkSurfaceProps.h" +class SkBitmap; class SkClipStack; class SkDraw; +class SkDrawFilter; struct SkIRect; class SkMatrix; class SkMetaData; class SkRegion; - class GrRenderTarget; class SK_API SkBaseDevice : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkBaseDevice) - /** * Construct a new device. */ - SkBaseDevice(); - - /** - * Construct a new device. - */ - SkBaseDevice(const SkDeviceProperties& deviceProperties); - + explicit SkBaseDevice(const SkSurfaceProps&); virtual ~SkBaseDevice(); - SkBaseDevice* createCompatibleDevice(const SkImageInfo&); - SkMetaData& getMetaData(); - /** Return the image properties of the device. */ - virtual const SkDeviceProperties& getDeviceProperties() const { - //Currently, all the properties are leaky. - return fLeakyProperties; - } - /** * Return ImageInfo for this device. If the canvas is not backed by pixels * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. @@ -67,6 +51,12 @@ public: bounds->setXYWH(origin.x(), origin.y(), this->width(), this->height()); } + SkIRect getGlobalBounds() const { + SkIRect bounds; + this->getGlobalBounds(&bounds); + return bounds; + } + int width() const { return this->imageInfo().width(); } @@ -89,7 +79,22 @@ public: bool writePixels(const SkImageInfo&, const void*, size_t rowBytes, int x, int y); - void* accessPixels(SkImageInfo* info, size_t* rowBytes); + /** + * Try to get write-access to the pixels behind the device. If successful, this returns true + * and fills-out the pixmap parameter. On success it also bumps the genID of the underlying + * bitmap. + * + * On failure, returns false and ignores the pixmap parameter. + */ + bool accessPixels(SkPixmap* pmap); + + /** + * Try to get read-only-access to the pixels behind the device. If successful, this returns + * true and fills-out the pixmap parameter. + * + * On failure, returns false and ignores the pixmap parameter. + */ + bool peekPixels(SkPixmap*); /** * Return the device's associated gpu render target, or NULL. @@ -111,7 +116,6 @@ public: */ virtual void onAttachToCanvas(SkCanvas*) { SkASSERT(!fAttachedToCanvas); - this->lockPixels(); #ifdef SK_DEBUG fAttachedToCanvas = true; #endif @@ -125,30 +129,28 @@ public: */ virtual void onDetachFromCanvas() { SkASSERT(fAttachedToCanvas); - this->unlockPixels(); #ifdef SK_DEBUG fAttachedToCanvas = false; #endif }; protected: - enum Usage { - kGeneral_Usage, - kSaveLayer_Usage // clear(eraseColor); } - /** These are called inside the per-device-layer loop for each draw call. When these are called, we have already applied any saveLayer operations, and are handling any looping from the paint, and any effects from the @@ -223,7 +217,15 @@ protected: virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst, const SkPaint& paint, - SkCanvas::DrawBitmapRectFlags flags) = 0; + SkCanvas::SrcRectConstraint) = 0; + virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center, + const SkRect& dst, const SkPaint&); + + virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&); + virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst, + const SkPaint&, SkCanvas::SrcRectConstraint); + virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center, + const SkRect& dst, const SkPaint&); /** * Does not handle text decoration. @@ -232,22 +234,33 @@ protected: virtual void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y, const SkPaint& paint) = 0; virtual void drawPosText(const SkDraw&, const void* text, size_t len, - const SkScalar pos[], SkScalar constY, - int scalarsPerPos, const SkPaint& paint) = 0; - virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, - const SkPath& path, const SkMatrix* matrix, - const SkPaint& paint) = 0; + const SkScalar pos[], int scalarsPerPos, + const SkPoint& offset, const SkPaint& paint) = 0; virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[], const SkPoint texs[], const SkColor colors[], SkXfermode* xmode, const uint16_t indices[], int indexCount, const SkPaint& paint) = 0; + // default implementation unrolls the blob runs. + virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y, + const SkPaint& paint, SkDrawFilter* drawFilter); + // default implementation calls drawVertices + virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint); + + // default implementation calls drawPath + virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[], + const SkColor[], int count, SkXfermode::Mode, const SkPaint&); + /** The SkDevice passed will be an SkDevice which was returned by a call to - onCreateDevice on this device with kSaveLayer_Usage. + onCreateDevice on this device with kNeverTile_TileExpectation. */ virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) = 0; + virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&, + const SkMatrix*, const SkPaint&); + bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y); /////////////////////////////////////////////////////////////////////////// @@ -258,20 +271,6 @@ protected: */ virtual const SkBitmap& onAccessBitmap() = 0; - /** Called when this device is installed into a Canvas. Balanced by a call - to unlockPixels() when the device is removed from a Canvas. - */ - virtual void lockPixels() {} - virtual void unlockPixels() {} - - /** - * Returns true if the device allows processing of this imagefilter. If - * false is returned, then the filter is ignored. This may happen for - * some subclasses that do not support pixel manipulations after drawing - * has occurred (e.g. printing). The default implementation returns true. - */ - virtual bool allowImageFilter(const SkImageFilter*) { return true; } - /** * Override and return true for filters that the device can handle * intrinsically. Doing so means that SkCanvas will pass-through this @@ -289,17 +288,14 @@ protected: * it just returns false and leaves result and offset unchanged. */ virtual bool filterImage(const SkImageFilter*, const SkBitmap&, - const SkImageFilter::Context& ctx, - SkBitmap* result, SkIPoint* offset) { + const SkImageFilter::Context&, + SkBitmap* /*result*/, SkIPoint* /*offset*/) { return false; } protected: - // default impl returns NULL - virtual SkSurface* newSurface(const SkImageInfo&); - - // default impl returns NULL - virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes); + virtual SkSurface* newSurface(const SkImageInfo&, const SkSurfaceProps&) { return NULL; } + virtual bool onPeekPixels(SkPixmap*) { return false; } /** * The caller is responsible for "pre-clipping" the dst. The impl can assume that the dst @@ -317,24 +313,11 @@ protected: */ virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y); - /** - * Default impl returns NULL. - */ - virtual void* onAccessPixels(SkImageInfo* info, size_t* rowBytes); + virtual bool onAccessPixels(SkPixmap*) { return false; } - /** - * Leaky properties are those which the device should be applying but it isn't. - * These properties will be applied by the draw, when and as it can. - * If the device does handle a property, that property should be set to the identity value - * for that property, effectively making it non-leaky. - */ - SkDeviceProperties fLeakyProperties; - - /** - * PRIVATE / EXPERIMENTAL -- do not call - * Construct an acceleration object and attach it to 'picture' - */ - virtual void EXPERIMENTAL_optimize(const SkPicture* picture); + const SkSurfaceProps& surfaceProps() const { + return fSurfaceProps; + } /** * PRIVATE / EXPERIMENTAL -- do not call @@ -346,7 +329,42 @@ protected: * to perform some device-specific warm up tasks and then let SkCanvas * perform the main rendering loop (by return false from here). */ - virtual bool EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* picture); + virtual bool EXPERIMENTAL_drawPicture(SkCanvas*, const SkPicture*, const SkMatrix*, + const SkPaint*); + + struct CreateInfo { + static SkPixelGeometry AdjustGeometry(const SkImageInfo&, TileUsage, SkPixelGeometry); + + // The constructor may change the pixel geometry based on other parameters. + CreateInfo(const SkImageInfo& info, + TileUsage tileUsage, + SkPixelGeometry geo, + bool forImageFilter = false) + : fInfo(info) + , fTileUsage(tileUsage) + , fPixelGeometry(AdjustGeometry(info, tileUsage, geo)) + , fForImageFilter(forImageFilter) {} + + const SkImageInfo fInfo; + const TileUsage fTileUsage; + const SkPixelGeometry fPixelGeometry; + const bool fForImageFilter; + }; + + /** + * Create a new device based on CreateInfo. If the paint is not null, then it represents a + * preview of how the new device will be composed with its creator device (this). + * + * The subclass may be handed this device in drawDevice(), so it must always return + * a device that it knows how to draw, and that it knows how to identify if it is not of the + * same subclass (since drawDevice is passed a SkBaseDevice*). If the subclass cannot fulfill + * that contract (e.g. PDF cannot support some settings on the paint) it should return NULL, + * and the caller may then decide to explicitly create a bitmapdevice, knowing that later + * it could not call drawDevice with it (but it could call drawSprite or drawBitmap). + */ + virtual SkBaseDevice* onCreateDevice(const CreateInfo&, const SkPaint*) { + return NULL; + } private: friend class SkCanvas; @@ -354,8 +372,8 @@ private: friend class SkDraw; friend class SkDrawIter; friend class SkDeviceFilteredPaint; - friend class SkDeviceImageFilterProxy; - friend class SkDeferredDevice; // for newSurface + friend class SkImageFilter::DeviceProxy; + friend class SkNoPixelsBitmapDevice; friend class SkSurface_Raster; @@ -365,21 +383,20 @@ private: // TODO: move to SkBitmapDevice virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) {} + virtual bool forceConservativeRasterClip() const { return false; } + // just called by SkCanvas when built as a layer void setOrigin(int x, int y) { fOrigin.set(x, y); } - // just called by SkCanvas for saveLayer - SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&); - - virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) { - return NULL; - } /** Causes any deferred drawing to the device to be completed. */ virtual void flush() {} + virtual SkImageFilter::Cache* getImageFilterCache() { return NULL; } + SkIPoint fOrigin; SkMetaData* fMetaData; + SkSurfaceProps fSurfaceProps; #ifdef SK_DEBUG bool fAttachedToCanvas; diff --git a/gfx/skia/skia/include/core/SkDeviceProperties.h b/gfx/skia/skia/include/core/SkDeviceProperties.h deleted file mode 100644 index 80e0177650ba..000000000000 --- a/gfx/skia/skia/include/core/SkDeviceProperties.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef SkDeviceProperties_DEFINED -#define SkDeviceProperties_DEFINED - -//TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and remove this import. -#include "SkFontLCDConfig.h" - -struct SkDeviceProperties { - struct Geometry { - /** The orientation of the pixel specifies the interpretation of the - * layout. If the orientation is horizontal, the layout is interpreted as - * left to right. It the orientation is vertical, the layout is - * interpreted top to bottom (rotated 90deg cw from horizontal). - */ - enum Orientation { - kUnknown_Orientation = 0x0, - kKnown_Orientation = 0x2, - - kHorizontal_Orientation = 0x2, //!< this is the default - kVertical_Orientation = 0x3, - - kOrientationMask = 0x3, - }; - - /** The layout of the pixel specifies its subpixel geometry. - * - * kUnknown_Layout means that the subpixel elements are not spatially - * separated in any known or usable fashion. - */ - enum Layout { - kUnknown_Layout = 0x0, - kKnown_Layout = 0x8, - - kRGB_Layout = 0x8, //!< this is the default - kBGR_Layout = 0xC, - - kLayoutMask = 0xC, - }; - - Orientation getOrientation() { - return static_cast(fGeometry & kOrientationMask); - } - Layout getLayout() { - return static_cast(fGeometry & kLayoutMask); - } - - bool isOrientationKnown() { - return SkToBool(fGeometry & kKnown_Orientation); - } - bool isLayoutKnown() { - return SkToBool(fGeometry & kKnown_Layout); - } - - private: - //TODO: get everyone to stop using SkFontLCDConfig::SetSubpixel* and replace these calls with constants. - static Orientation fromOldOrientation(SkFontLCDConfig::LCDOrientation orientation) { - switch (orientation) { - case SkFontLCDConfig::kHorizontal_LCDOrientation: return kHorizontal_Orientation; - case SkFontLCDConfig::kVertical_LCDOrientation: return kVertical_Orientation; - default: return kUnknown_Orientation; - } - } - static Layout fromOldLayout(SkFontLCDConfig::LCDOrder order) { - switch (order) { - case SkFontLCDConfig::kRGB_LCDOrder: return kRGB_Layout; - case SkFontLCDConfig::kBGR_LCDOrder: return kBGR_Layout; - default: return kUnknown_Layout; - } - } - public: - static Geometry MakeDefault() { - Orientation orientation = fromOldOrientation(SkFontLCDConfig::GetSubpixelOrientation()); //kHorizontal_Orientation - Layout layout = fromOldLayout(SkFontLCDConfig::GetSubpixelOrder()); //kRGB_Layout - Geometry ret = { SkToU8(orientation | layout) }; - return ret; - } - - static Geometry Make(Orientation orientation, Layout layout) { - Geometry ret = { SkToU8(orientation | layout) }; - return ret; - } - - uint8_t fGeometry; - }; - - static SkDeviceProperties MakeDefault() { - SkDeviceProperties ret = { Geometry::MakeDefault(), SK_GAMMA_EXPONENT }; - return ret; - } - - static SkDeviceProperties Make(Geometry geometry, SkScalar gamma) { - SkDeviceProperties ret = { geometry, gamma }; - return ret; - } - - /** Each pixel of an image will have some number of channels. - * Can the layout of those channels be exploited? */ - Geometry fGeometry; - - /** Represents the color space of the image. This is a woefully inadequate beginning. */ - SkScalar fGamma; -}; - -#endif diff --git a/gfx/skia/skia/include/core/SkDocument.h b/gfx/skia/skia/include/core/SkDocument.h index dbf4bc5957e7..316d15a25342 100644 --- a/gfx/skia/skia/include/core/SkDocument.h +++ b/gfx/skia/skia/include/core/SkDocument.h @@ -12,6 +12,8 @@ #include "SkPicture.h" #include "SkRect.h" #include "SkRefCnt.h" +#include "SkString.h" +#include "SkTime.h" class SkCanvas; class SkWStream; @@ -30,56 +32,50 @@ class SkWStream; * c. doc->endPage(); * 3. Close the document with doc->close(). */ -class SkDocument : public SkRefCnt { +class SK_API SkDocument : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkDocument) + /** + * Create a PDF-backed document, writing the results into a SkWStream. + * + * PDF pages are sized in point units. 1 pt == 1/72 inch == 127/360 mm. + * + * @param SkWStream* A PDF document will be written to this + * stream. The document may write to the stream at + * anytime during its lifetime, until either close() is + * called or the document is deleted. + * @param dpi The DPI (pixels-per-inch) at which features without + * native PDF support will be rasterized (e.g. draw image + * with perspective, draw text with perspective, ...) A + * larger DPI would create a PDF that reflects the + * original intent with better fidelity, but it can make + * for larger PDF files too, which would use more memory + * while rendering, and it would be slower to be processed + * or sent online or to printer. + * @returns NULL if there is an error, otherwise a newly created + * PDF-backed SkDocument. + */ + static SkDocument* CreatePDF(SkWStream*, + SkScalar dpi = SK_ScalarDefaultRasterDPI); /** * Create a PDF-backed document, writing the results into a file. - * If there is an error trying to create the doc, returns NULL. - * encoder sets the DCTEncoder for images, to encode a bitmap - * as JPEG (DCT). - * rasterDpi - the DPI at which features without native PDF support - * will be rasterized (e.g. draw image with perspective, - * draw text with perspective, ...) - * A larger DPI would create a PDF that reflects the original - * intent with better fidelity, but it can make for larger - * PDF files too, which would use more memory while rendering, - * and it would be slower to be processed or sent online or - * to printer. */ - static SkDocument* CreatePDF( - const char filename[], - SkPicture::EncodeBitmap encoder = NULL, - SkScalar rasterDpi = SK_ScalarDefaultRasterDPI); + static SkDocument* CreatePDF(const char outputFilePath[], + SkScalar dpi = SK_ScalarDefaultRasterDPI); /** - * Create a PDF-backed document, writing the results into a stream. - * If there is an error trying to create the doc, returns NULL. - * - * The document may write to the stream at anytime during its lifetime, - * until either close() is called or the document is deleted. Once close() - * has been called, and all of the data has been written to the stream, - * if there is a Done proc provided, it will be called with the stream. - * The proc can delete the stream, or whatever it needs to do. - * encoder sets the DCTEncoder for images, to encode a bitmap - * as JPEG (DCT). - * Done - clean up method intended to allow deletion of the stream. - * Its aborted parameter is true if the cleanup is due to an abort - * call. It is false otherwise. - * rasterDpi - the DPI at which features without native PDF support - * will be rasterized (e.g. draw image with perspective, - * draw text with perspective, ...) - * A larger DPI would create a PDF that reflects the original - * intent with better fidelity, but it can make for larger - * PDF files too, which would use more memory while rendering, - * and it would be slower to be processed or sent online or - * to printer. */ - static SkDocument* CreatePDF( - SkWStream*, void (*Done)(SkWStream*,bool aborted) = NULL, - SkPicture::EncodeBitmap encoder = NULL, - SkScalar rasterDpi = SK_ScalarDefaultRasterDPI); + * Create a XPS-backed document, writing the results into the stream. + * Returns NULL if XPS is not supported. + */ + static SkDocument* CreateXPS(SkWStream* stream, + SkScalar dpi = SK_ScalarDefaultRasterDPI); + /** + * Create a XPS-backed document, writing the results into a file. + * Returns NULL if XPS is not supported. + */ + static SkDocument* CreateXPS(const char path[], + SkScalar dpi = SK_ScalarDefaultRasterDPI); /** * Begin a new page for the document, returning the canvas that will draw * into the page. The document owns this canvas, and it will go out of @@ -110,8 +106,36 @@ public: */ void abort(); + /** + * Set the document's metadata, if supported by the document + * type. The creationDate and modifiedDate parameters can be + * nullptr. For example: + * + * SkDocument* make_doc(SkWStream* output) { + * SkTArray info; + * info.emplace_back(SkString("Title"), SkString("...")); + * info.emplace_back(SkString("Author"), SkString("...")); + * info.emplace_back(SkString("Subject"), SkString("...")); + * info.emplace_back(SkString("Keywords"), SkString("...")); + * info.emplace_back(SkString("Creator"), SkString("...")); + * SkTime::DateTime now; + * SkTime::GetDateTime(&now); + * SkDocument* doc = SkDocument::CreatePDF(output); + * doc->setMetadata(info, &now, &now); + * return doc; + * } + */ + struct Attribute { + SkString fKey, fValue; + Attribute(const SkString& k, const SkString& v) : fKey(k), fValue(v) {} + }; + virtual void setMetadata(const SkTArray&, + const SkTime::DateTime* /* creationDate */, + const SkTime::DateTime* /* modifiedDate */) {} + protected: SkDocument(SkWStream*, void (*)(SkWStream*, bool aborted)); + // note: subclasses must call close() in their destructor, as the base class // cannot do this for them. virtual ~SkDocument(); @@ -122,6 +146,9 @@ protected: virtual bool onClose(SkWStream*) = 0; virtual void onAbort() = 0; + // Allows subclasses to write to the stream as pages are written. + SkWStream* getStream() { return fStream; } + enum State { kBetweenPages_State, kInPage_State, diff --git a/gfx/skia/skia/include/core/SkDraw.h b/gfx/skia/skia/include/core/SkDraw.h index 918f2335ea0e..b8cf8027dda5 100644 --- a/gfx/skia/skia/include/core/SkDraw.h +++ b/gfx/skia/skia/include/core/SkDraw.h @@ -17,6 +17,7 @@ class SkBitmap; class SkClipStack; class SkBaseDevice; +class SkBlitter; class SkMatrix; class SkPath; class SkRegion; @@ -33,7 +34,11 @@ public: void drawPaint(const SkPaint&) const; void drawPoints(SkCanvas::PointMode, size_t count, const SkPoint[], const SkPaint&, bool forceUseDevice = false) const; - void drawRect(const SkRect&, const SkPaint&) const; + void drawRect(const SkRect& prePaintRect, const SkPaint&, const SkMatrix* paintMatrix, + const SkRect* postPaintRect) const; + void drawRect(const SkRect& rect, const SkPaint& paint) const { + this->drawRect(rect, paint, NULL, NULL); + } void drawRRect(const SkRRect&, const SkPaint&) const; /** * To save on mallocs, we allow a flag that tells us that srcPath is @@ -49,19 +54,20 @@ public: this->drawPath(path, paint, prePathMatrix, pathIsMutable, false); } - void drawPath(const SkPath& path, const SkPaint& paint) const { - this->drawPath(path, paint, NULL, false, false); + void drawPath(const SkPath& path, const SkPaint& paint, + SkBlitter* customBlitter = NULL) const { + this->drawPath(path, paint, NULL, false, false, customBlitter); } - void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) const; + /* If dstOrNull is null, computes a dst by mapping the bitmap's bounds through the matrix. */ + void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull, + const SkPaint&) const; void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const; void drawText(const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) const; void drawPosText(const char text[], size_t byteLength, - const SkScalar pos[], SkScalar constY, - int scalarsPerPosition, const SkPaint& paint) const; - void drawTextOnPath(const char text[], size_t byteLength, - const SkPath&, const SkMatrix*, const SkPaint&) const; + const SkScalar pos[], int scalarsPerPosition, + const SkPoint& offset, const SkPaint& paint) const; void drawVertices(SkCanvas::VertexMode mode, int count, const SkPoint vertices[], const SkPoint textures[], const SkColor colors[], SkXfermode* xmode, @@ -74,8 +80,9 @@ public: * * Only device A8 is supported right now. */ - void drawPathCoverage(const SkPath& src, const SkPaint& paint) const { - this->drawPath(src, paint, NULL, false, true); + void drawPathCoverage(const SkPath& src, const SkPaint& paint, + SkBlitter* customBlitter = NULL) const { + this->drawPath(src, paint, NULL, false, true, customBlitter); } /** Helper function that creates a mask from a path and an optional maskfilter. @@ -110,15 +117,16 @@ public: void drawText_asPaths(const char text[], size_t byteLength, SkScalar x, SkScalar y, const SkPaint&) const; void drawPosText_asPaths(const char text[], size_t byteLength, - const SkScalar pos[], SkScalar constY, - int scalarsPerPosition, const SkPaint&) const; + const SkScalar pos[], int scalarsPerPosition, + const SkPoint& offset, const SkPaint&) const; private: void drawDevMask(const SkMask& mask, const SkPaint&) const; void drawBitmapAsMask(const SkBitmap&, const SkPaint&) const; void drawPath(const SkPath&, const SkPaint&, const SkMatrix* preMatrix, - bool pathIsMutable, bool drawCoverage) const; + bool pathIsMutable, bool drawCoverage, + SkBlitter* customBlitter = NULL) const; /** * Return the current clip bounds, in local coordinates, with slop to account @@ -132,14 +140,13 @@ private: computeConservativeLocalClipBounds(SkRect* bounds) const; public: - const SkBitmap* fBitmap; // required + SkPixmap fDst; const SkMatrix* fMatrix; // required const SkRegion* fClip; // DEPRECATED const SkRasterClip* fRC; // required const SkClipStack* fClipStack; // optional SkBaseDevice* fDevice; // optional - SkDrawProcs* fProcs; // optional #ifdef SK_DEBUG void validate() const; diff --git a/gfx/skia/skia/include/core/SkDrawFilter.h b/gfx/skia/skia/include/core/SkDrawFilter.h index 52cbba9d20f1..865df5f1e180 100644 --- a/gfx/skia/skia/include/core/SkDrawFilter.h +++ b/gfx/skia/skia/include/core/SkDrawFilter.h @@ -23,8 +23,6 @@ class SkPaint; */ class SK_API SkDrawFilter : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkDrawFilter) - enum Type { kPaint_Type, kPoint_Type, diff --git a/gfx/skia/skia/include/core/SkDrawLooper.h b/gfx/skia/skia/include/core/SkDrawLooper.h index b92baccc0838..28d7d8beef27 100644 --- a/gfx/skia/skia/include/core/SkDrawLooper.h +++ b/gfx/skia/skia/include/core/SkDrawLooper.h @@ -30,8 +30,6 @@ class SkString; */ class SK_API SkDrawLooper : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkDrawLooper) - /** * Holds state during a draw. Users call next() until it returns false. * @@ -87,9 +85,8 @@ public: * storage rect, where the storage rect is with the union of the src rect * and the looper's bounding rect. */ - virtual bool canComputeFastBounds(const SkPaint& paint) const; - virtual void computeFastBounds(const SkPaint& paint, - const SkRect& src, SkRect* dst) const; + bool canComputeFastBounds(const SkPaint& paint) const; + void computeFastBounds(const SkPaint& paint, const SkRect& src, SkRect* dst) const; struct BlurShadowRec { SkScalar fSigma; @@ -114,7 +111,6 @@ public: protected: SkDrawLooper() {} - SkDrawLooper(SkReadBuffer& buffer) : INHERITED(buffer) {} private: typedef SkFlattenable INHERITED; diff --git a/gfx/skia/skia/include/core/SkDrawPictureCallback.h b/gfx/skia/skia/include/core/SkDrawPictureCallback.h deleted file mode 100644 index e86a227e6265..000000000000 --- a/gfx/skia/skia/include/core/SkDrawPictureCallback.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkDrawPictureCallback_DEFINED -#define SkDrawPictureCallback_DEFINED - -/** - * Subclasses of this can be passed to canvas.drawPicture(). During the drawing - * of the picture, this callback will periodically be invoked. If its - * abortDrawing() returns true, then picture playback will be interrupted. - * - * The resulting drawing is undefined, as there is no guarantee how often the - * callback will be invoked. If the abort happens inside some level of nested - * calls to save(), restore will automatically be called to return the state - * to the same level it was before the drawPicture call was made. - */ -class SK_API SkDrawPictureCallback { -public: - SkDrawPictureCallback() {} - virtual ~SkDrawPictureCallback() {} - - virtual bool abortDrawing() = 0; -}; - -#endif//SkDrawPictureCallback_DEFINED diff --git a/gfx/skia/skia/include/core/SkDrawable.h b/gfx/skia/skia/include/core/SkDrawable.h new file mode 100644 index 000000000000..2f0a62d8b5eb --- /dev/null +++ b/gfx/skia/skia/include/core/SkDrawable.h @@ -0,0 +1,77 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkDrawable_DEFINED +#define SkDrawable_DEFINED + +#include "SkRefCnt.h" + +class SkCanvas; +class SkPicture; +struct SkRect; + +/** + * Base-class for objects that draw into SkCanvas. + * + * The object has a generation ID, which is guaranteed to be unique across all drawables. To + * allow for clients of the drawable that may want to cache the results, the drawable must + * change its generation ID whenever its internal state changes such that it will draw differently. + */ +class SkDrawable : public SkRefCnt { +public: + SkDrawable(); + + /** + * Draws into the specified content. The drawing sequence will be balanced upon return + * (i.e. the saveLevel() on the canvas will match what it was when draw() was called, + * and the current matrix and clip settings will not be changed. + */ + void draw(SkCanvas*, const SkMatrix* = NULL); + void draw(SkCanvas*, SkScalar x, SkScalar y); + + SkPicture* newPictureSnapshot(); + + /** + * Return a unique value for this instance. If two calls to this return the same value, + * it is presumed that calling the draw() method will render the same thing as well. + * + * Subclasses that change their state should call notifyDrawingChanged() to ensure that + * a new value will be returned the next time it is called. + */ + uint32_t getGenerationID(); + + /** + * Return the (conservative) bounds of what the drawable will draw. If the drawable can + * change what it draws (e.g. animation or in response to some external change), then this + * must return a bounds that is always valid for all possible states. + */ + SkRect getBounds(); + + /** + * Calling this invalidates the previous generation ID, and causes a new one to be computed + * the next time getGenerationID() is called. Typically this is called by the object itself, + * in response to its internal state changing. + */ + void notifyDrawingChanged(); + +protected: + virtual SkRect onGetBounds() = 0; + virtual void onDraw(SkCanvas*) = 0; + + /** + * Default implementation calls onDraw() with a canvas that records into a picture. Subclasses + * may override if they have a more efficient way to return a picture for the current state + * of their drawable. Note: this picture must draw the same as what would be drawn from + * onDraw(). + */ + virtual SkPicture* onNewPictureSnapshot(); + +private: + int32_t fGenerationID; +}; + +#endif diff --git a/gfx/skia/skia/include/core/SkDynamicAnnotations.h b/gfx/skia/skia/include/core/SkDynamicAnnotations.h deleted file mode 100644 index 422d98db43d2..000000000000 --- a/gfx/skia/skia/include/core/SkDynamicAnnotations.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkDynamicAnnotations_DEFINED -#define SkDynamicAnnotations_DEFINED - -// This file contains macros used to send out-of-band signals to dynamic instrumentation systems, -// namely thread sanitizer. This is a cut-down version of the full dynamic_annotations library with -// only the features used by Skia. - -#if SK_DYNAMIC_ANNOTATIONS_ENABLED - -extern "C" { -// TSAN provides these hooks. -void AnnotateIgnoreReadsBegin(const char* file, int line); -void AnnotateIgnoreReadsEnd(const char* file, int line); -void AnnotateIgnoreWritesBegin(const char* file, int line); -void AnnotateIgnoreWritesEnd(const char* file, int line); -void AnnotateBenignRaceSized(const char* file, int line, - const volatile void* addr, long size, const char* desc); -} // extern "C" - -// SK_ANNOTATE_UNPROTECTED_READ can wrap any variable read to tell TSAN to ignore that it appears to -// be a racy read. This should be used only when we can make an external guarantee that though this -// particular read is racy, it is being used as part of a mechanism which is thread safe. Examples: -// - the first check in double-checked locking; -// - checking if a ref count is equal to 1. -// Note that in both these cases, we must still add terrifyingly subtle memory barriers to provide -// that overall thread safety guarantee. Using this macro to shut TSAN up without providing such an -// external guarantee is pretty much never correct. -template -inline T SK_ANNOTATE_UNPROTECTED_READ(const volatile T& x) { - AnnotateIgnoreReadsBegin(__FILE__, __LINE__); - T read = x; - AnnotateIgnoreReadsEnd(__FILE__, __LINE__); - return read; -} - -// Like SK_ANNOTATE_UNPROTECTED_READ, but for writes. -template -inline void SK_ANNOTATE_UNPROTECTED_WRITE(T* ptr, const volatile T& val) { - AnnotateIgnoreWritesBegin(__FILE__, __LINE__); - *ptr = val; - AnnotateIgnoreWritesEnd(__FILE__, __LINE__); -} - -// Ignore racy reads and racy writes to this pointer, indefinitely. -// If at all possible, use the more precise SK_ANNOTATE_UNPROTECTED_READ. -template -void SK_ANNOTATE_BENIGN_RACE(T* ptr) { - AnnotateBenignRaceSized(__FILE__, __LINE__, ptr, sizeof(*ptr), "SK_ANNOTATE_BENIGN_RACE"); -} - -#else // !SK_DYNAMIC_ANNOTATIONS_ENABLED - -#define SK_ANNOTATE_UNPROTECTED_READ(x) (x) -#define SK_ANNOTATE_UNPROTECTED_WRITE(ptr, val) *(ptr) = (val) -#define SK_ANNOTATE_BENIGN_RACE(ptr) - -#endif - -// Can be used to wrap values that are intentionally racy, usually small mutable cached values, e.g. -// - SkMatrix type mask -// - SkPixelRef genIDs -template -class SkTRacy { -public: - operator const T() const { - return SK_ANNOTATE_UNPROTECTED_READ(fVal); - } - - SkTRacy& operator=(const T& val) { - SK_ANNOTATE_UNPROTECTED_WRITE(&fVal, val); - return *this; - } - -private: - T fVal; -}; - -// This is like SkTRacy, but allows you to return the value by reference. -// TSAN is better at suppressing SkTRacy than SkTRacyReffable, so use SkTRacy when possible. -// -// We use this for SkPathRef bounds, which is an SkRect we pass around by reference publically. -template -class SkTRacyReffable { -public: - SkTRacyReffable() { SK_ANNOTATE_BENIGN_RACE(&fVal); } - - operator const T&() const { - return fVal; - } - - SkTRacyReffable& operator=(const T& val) { - fVal = val; - return *this; - } - - const T* get() const { return &fVal; } - T* get() { return &fVal; } - - const T* operator->() const { return &fVal; } - T* operator->() { return &fVal; } - -private: - T fVal; -}; - -#endif//SkDynamicAnnotations_DEFINED diff --git a/gfx/skia/skia/include/core/SkFilterQuality.h b/gfx/skia/skia/include/core/SkFilterQuality.h new file mode 100644 index 000000000000..db0597e697dd --- /dev/null +++ b/gfx/skia/skia/include/core/SkFilterQuality.h @@ -0,0 +1,24 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkFilterQuality_DEFINED +#define SkFilterQuality_DEFINED + +#include "SkTypes.h" + +/** + * Controls how much filtering to be done when scaling/transforming complex colors + * e.g. images + */ +enum SkFilterQuality { + kNone_SkFilterQuality, //!< fastest but lowest quality, typically nearest-neighbor + kLow_SkFilterQuality, //!< typically bilerp + kMedium_SkFilterQuality, //!< typically bilerp + mipmaps for down-scaling + kHigh_SkFilterQuality //!< slowest but highest quality, typically bicubic or better +}; + +#endif diff --git a/gfx/skia/skia/include/core/SkFixed.h b/gfx/skia/skia/include/core/SkFixed.h index 6f168c8edd9e..fefa718d0fe7 100644 --- a/gfx/skia/skia/include/core/SkFixed.h +++ b/gfx/skia/skia/include/core/SkFixed.h @@ -28,7 +28,7 @@ typedef int32_t SkFixed; #define SK_FixedTanPIOver8 (0x6A0A) #define SK_FixedRoot2Over2 (0xB505) -#define SkFixedToFloat(x) ((x) * 1.5258789e-5f) +#define SkFixedToFloat(x) ((x) * 1.52587890625e-5f) #if 1 #define SkFloatToFixed(x) ((SkFixed)((x) * SK_Fixed1)) #else @@ -50,7 +50,7 @@ typedef int32_t SkFixed; #define SkFloatToFixed_Check(x) SkFloatToFixed(x) #endif -#define SkFixedToDouble(x) ((x) * 1.5258789e-5) +#define SkFixedToDouble(x) ((x) * 1.52587890625e-5) #define SkDoubleToFixed(x) ((SkFixed)((x) * SK_Fixed1)) /** Converts an integer to a SkFixed, asserting that the result does not overflow @@ -60,11 +60,15 @@ typedef int32_t SkFixed; inline SkFixed SkIntToFixed(int n) { SkASSERT(n >= -32768 && n <= 32767); - return n << 16; + // Left shifting a negative value has undefined behavior in C, so we cast to unsigned before + // shifting. + return (unsigned)n << 16; } #else - // force the cast to SkFixed to ensure that the answer is signed (like the debug version) - #define SkIntToFixed(n) (SkFixed)((n) << 16) + // Left shifting a negative value has undefined behavior in C, so we cast to unsigned before + // shifting. Then we force the cast to SkFixed to ensure that the answer is signed (like the + // debug version). + #define SkIntToFixed(n) (SkFixed)((unsigned)(n) << 16) #endif #define SkFixedRoundToInt(x) (((x) + SK_FixedHalf) >> 16) @@ -78,32 +82,23 @@ typedef int32_t SkFixed; #define SkFixedAbs(x) SkAbs32(x) #define SkFixedAve(a, b) (((a) + (b)) >> 1) -SkFixed SkFixedMul_portable(SkFixed, SkFixed); - -#define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16) - -/////////////////////////////////////////////////////////////////////////////// -// TODO: move fixed sin/cos into SkCosineMapper, as that is the only caller -// or rewrite SkCosineMapper to not use it at all - -SkFixed SkFixedSinCos(SkFixed radians, SkFixed* cosValueOrNull); -#define SkFixedSin(radians) SkFixedSinCos(radians, NULL) -static inline SkFixed SkFixedCos(SkFixed radians) { - SkFixed cosValue; - (void)SkFixedSinCos(radians, &cosValue); - return cosValue; -} +// Blink layout tests are baselined to Clang optimizing through undefined behavior in SkDivBits. +#if defined(SK_SUPPORT_LEGACY_DIVBITS_UB) + #define SkFixedDiv(numer, denom) SkDivBits(numer, denom, 16) +#else + // TODO(reed): this clamp shouldn't be needed. Use SkToS32(). + #define SkFixedDiv(numer, denom) \ + SkTPin(((int64_t)numer << 16) / denom, SK_MinS32, SK_MaxS32) +#endif ////////////////////////////////////////////////////////////////////////////////////////////////////// // Now look for ASM overrides for our portable versions (should consider putting this in its own file) -#ifdef SkLONGLONG - inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) - { - return (SkFixed)((int64_t)a * b >> 16); - } - #define SkFixedMul(a,b) SkFixedMul_longlong(a,b) -#endif +inline SkFixed SkFixedMul_longlong(SkFixed a, SkFixed b) { + return (SkFixed)((int64_t)a * b >> 16); +} +#define SkFixedMul(a,b) SkFixedMul_longlong(a,b) + #if defined(SK_CPU_ARM32) /* This guy does not handle NaN or other obscurities, but is faster than @@ -146,20 +141,31 @@ static inline SkFixed SkFixedCos(SkFixed radians) { #define SkFloatToFixed(x) SkFloatToFixed_arm(x) #endif -#ifndef SkFixedMul - #define SkFixedMul(x, y) SkFixedMul_portable(x, y) -#endif +/////////////////////////////////////////////////////////////////////////////// + +typedef int64_t SkFixed3232; // 32.32 + +#define SkIntToFixed3232(x) ((SkFixed3232)(x) << 32) +#define SkFixed3232ToInt(x) ((int)((x) >> 32)) +#define SkFixedToFixed3232(x) ((SkFixed3232)(x) << 16) +#define SkFixed3232ToFixed(x) ((SkFixed)((x) >> 16)) +#define SkFloatToFixed3232(x) ((SkFixed3232)((x) * (65536.0f * 65536.0f))) + +#define SkScalarToFixed3232(x) SkFloatToFixed3232(x) /////////////////////////////////////////////////////////////////////////////// -typedef int64_t SkFixed48; +// 64bits wide, with a 16bit bias. Useful when accumulating lots of 16.16 so +// we don't overflow along the way +typedef int64_t Sk48Dot16; -#define SkIntToFixed48(x) ((SkFixed48)(x) << 48) -#define SkFixed48ToInt(x) ((int)((x) >> 48)) -#define SkFixedToFixed48(x) ((SkFixed48)(x) << 32) -#define SkFixed48ToFixed(x) ((SkFixed)((x) >> 32)) -#define SkFloatToFixed48(x) ((SkFixed48)((x) * (65536.0f * 65536.0f * 65536.0f))) +#define Sk48Dot16FloorToInt(x) static_cast((x) >> 16) -#define SkScalarToFixed48(x) SkFloatToFixed48(x) +static inline float Sk48Dot16ToScalar(Sk48Dot16 x) { + return static_cast(x * 1.5258789e-5); // x * (1.0f / (1 << 16)) +} +#define SkFloatTo48Dot16(x) (static_cast((x) * (1 << 16))) + +#define SkScalarTo48Dot16(x) SkFloatTo48Dot16(x) #endif diff --git a/gfx/skia/skia/include/core/SkFlattenable.h b/gfx/skia/skia/include/core/SkFlattenable.h index f6d377a9d743..bccabc18fa86 100644 --- a/gfx/skia/skia/include/core/SkFlattenable.h +++ b/gfx/skia/skia/include/core/SkFlattenable.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,7 +5,6 @@ * found in the LICENSE file. */ - #ifndef SkFlattenable_DEFINED #define SkFlattenable_DEFINED @@ -15,9 +13,26 @@ class SkReadBuffer; class SkWriteBuffer; -#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ - SkFlattenable::Registrar(#flattenable, flattenable::CreateProc, \ - flattenable::GetFlattenableType()); +class SkPrivateEffectInitializer; + +/* + * Flattening is straight-forward: + * 1. call getFactory() so we have a function-ptr to recreate the subclass + * 2. call flatten(buffer) to write out enough data for the factory to read + * + * Unflattening is easy for the caller: new_instance = factory(buffer) + * + * The complexity of supporting this is as follows. + * + * If your subclass wants to control unflattening, use this macro in your declaration: + * SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS + * This will provide a getFactory(), and require that the subclass implements CreateProc. + * + * For older buffers (before the DEEPFLATTENING change, the macros below declare + * a thin factory DeepCreateProc. It checks the version of the buffer, and if it is pre-deep, + * then it calls through to a (usually protected) constructor, passing the buffer. + * If the buffer is newer, then it directly calls the "real" factory: CreateProc. + */ #define SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() static void InitializeFlattenables(); @@ -27,14 +42,16 @@ class SkWriteBuffer; #define SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END \ } -#define SK_DECLARE_UNFLATTENABLE_OBJECT() \ - virtual Factory getFactory() const SK_OVERRIDE { return NULL; } +#define SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(flattenable) \ + SkFlattenable::Register(#flattenable, flattenable::CreateProc, \ + flattenable::GetFlattenableType()); -#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ - virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } \ - static SkFlattenable* CreateProc(SkReadBuffer& buffer) { \ - return SkNEW_ARGS(flattenable, (buffer)); \ - } +#define SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(flattenable) \ + private: \ + static SkFlattenable* CreateProc(SkReadBuffer&); \ + friend class ::SkPrivateEffectInitializer; \ + public: \ + Factory getFactory() const override { return CreateProc; } /** For SkFlattenable derived objects with a valid type This macro should only be used in base class objects in core @@ -65,8 +82,6 @@ public: kSkXfermode_Type, }; - SK_DECLARE_INST_COUNT(SkFlattenable) - typedef SkFlattenable* (*Factory)(SkReadBuffer&); SkFlattenable() {} @@ -87,21 +102,11 @@ public: static void Register(const char name[], Factory, Type); - class Registrar { - public: - Registrar(const char name[], Factory factory, Type type) { - SkFlattenable::Register(name, factory, type); - } - }; - - /** Override this to write data specific to your subclass into the buffer, - being sure to call your super-class' version first. This data will later - be passed to your Factory function, returned by getFactory(). + /** + * Override this if your subclass needs to record data that it will need to recreate itself + * from its CreateProc (returned by getFactory()). */ - virtual void flatten(SkWriteBuffer&) const; - -protected: - SkFlattenable(SkReadBuffer&) {} + virtual void flatten(SkWriteBuffer&) const {} private: static void InitializeFlattenablesIfNeeded(); diff --git a/gfx/skia/skia/include/core/SkFlattenableBuffers.h b/gfx/skia/skia/include/core/SkFlattenableBuffers.h deleted file mode 100644 index 3e5d5b94ee2c..000000000000 --- a/gfx/skia/skia/include/core/SkFlattenableBuffers.h +++ /dev/null @@ -1,10 +0,0 @@ -// Temporary shim to keep a couple dependencies working in Chromium. -#ifndef SkFlattenableBuffers_DEFINED -#define SkFlattenableBuffers_DEFINED - -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" - -typedef SkReadBuffer SkFlattenableReadBuffer; - -#endif//SkFlattenableBuffers_DEFINED diff --git a/gfx/skia/skia/include/core/SkFont.h b/gfx/skia/skia/include/core/SkFont.h index 9bdecd6eb94e..e4ebebb244af 100644 --- a/gfx/skia/skia/include/core/SkFont.h +++ b/gfx/skia/skia/include/core/SkFont.h @@ -75,8 +75,8 @@ public: enum Flags { /** * Use the system's automatic hinting mechanism to hint the typeface. - * If both bytecode and auto hints are specified, attempt to use the bytecodes first. - * If that fails (e.g. there are no codes), then attempt to autohint. + * This is a last resort hinting method applied only if other hinting methods do not apply. + * TODO: where to put auto-normal vs auto-light? */ kEnableAutoHints_Flag = 1 << 0, @@ -87,6 +87,13 @@ public: */ kEnableByteCodeHints_Flag = 1 << 1, + /** + * If the typeface contains explicit bitmaps for hinting, use them. + * If both bytecode and auto hints are also specified, attempt to use the bitmaps first; + * if that fails (e.g. there are no bitmaps), then attempt to bytecode or autohint. + */ + kEmbeddedBitmaps_Flag = 1 << 2, + /** * Use rounded metric values (e.g. advance). * If either auto or bytecode hinting was used, apply those results to the metrics of the @@ -96,10 +103,9 @@ public: * This applies to calls that return metrics (e.g. measureText) and to drawing the glyphs * (see SkCanvas drawText and drawPosText). */ - kUseNonlinearMetrics_Flag = 1 << 2, + kUseNonlinearMetrics_Flag = 1 << 3, - kVertical_Flag = 1 << 3, - kEmbeddedBitmaps_Flag = 1 << 4, + kVertical_Flag = 1 << 4, kGenA8FromLCD_Flag = 1 << 5, kEmbolden_Flag = 1 << 6, kDevKern_Flag = 1 << 7, // ifdef ANDROID ? diff --git a/gfx/skia/skia/include/core/SkFontHost.h b/gfx/skia/skia/include/core/SkFontHost.h index 4c5013fe4a04..a2cc04bc7097 100644 --- a/gfx/skia/skia/include/core/SkFontHost.h +++ b/gfx/skia/skia/include/core/SkFontHost.h @@ -90,42 +90,6 @@ public: static void SetSubpixelOrder(LCDOrder order); /** @deprecated get from Device. */ static LCDOrder GetSubpixelOrder(); - -private: - /** Return a new, closest matching typeface given either an existing family - (specified by a typeface in that family) or by a familyName and a - requested style. - 1) If familyFace is null, use familyName. - 2) If familyName is null, use data (UTF-16 to cover). - 3) If all are null, return the default font that best matches style - */ - static SkTypeface* CreateTypeface(const SkTypeface* familyFace, - const char familyName[], - SkTypeface::Style style); - - /** Return a new typeface given the data buffer. If the data does not - represent a valid font, returns null. - - If a typeface instance is returned, the caller is responsible for - calling unref() on the typeface when they are finished with it. - - The returned typeface may or may not have called ref() on the stream - parameter. If the typeface has not called ref(), then it may have made - a copy of the releveant data. In either case, the caller is still - responsible for its refcnt ownership of the stream. - */ - static SkTypeface* CreateTypefaceFromStream(SkStream*); - - /** Return a new typeface from the specified file path. If the file does not - represent a valid font, this returns null. If a typeface is returned, - the caller is responsible for calling unref() when it is no longer used. - */ - static SkTypeface* CreateTypefaceFromFile(const char path[]); - - /////////////////////////////////////////////////////////////////////////// - - friend class SkScalerContext; - friend class SkTypeface; }; #endif diff --git a/gfx/skia/skia/include/ports/SkFontStyle.h b/gfx/skia/skia/include/core/SkFontStyle.h similarity index 93% rename from gfx/skia/skia/include/ports/SkFontStyle.h rename to gfx/skia/skia/include/core/SkFontStyle.h index 9d9a912d7d74..f42d7dd47018 100644 --- a/gfx/skia/skia/include/ports/SkFontStyle.h +++ b/gfx/skia/skia/include/core/SkFontStyle.h @@ -43,6 +43,8 @@ public: SkFontStyle(); SkFontStyle(int weight, int width, Slant); + /** oldStyle means the style-bits in SkTypeface::Style: bold=1, italic=2 */ + explicit SkFontStyle(unsigned oldStyle); bool operator==(const SkFontStyle& rhs) const { return fUnion.fU32 == rhs.fUnion.fU32; diff --git a/gfx/skia/skia/include/core/SkGraphics.h b/gfx/skia/skia/include/core/SkGraphics.h index e7865ca5afb4..5aecc7acd00f 100644 --- a/gfx/skia/skia/include/core/SkGraphics.h +++ b/gfx/skia/skia/include/core/SkGraphics.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,25 +5,26 @@ * found in the LICENSE file. */ - #ifndef SkGraphics_DEFINED #define SkGraphics_DEFINED #include "SkTypes.h" +class SkData; +class SkImageGenerator; +class SkTraceMemoryDump; + class SK_API SkGraphics { public: /** * Call this at process initialization time if your environment does not - * permit static global initializers that execute code. Note that - * Init() is not thread-safe. + * permit static global initializers that execute code. + * Init() is thread-safe and idempotent. */ static void Init(); - /** - * Call this to release any memory held privately, such as the font cache. - */ - static void Term(); + // We're in the middle of cleaning this up. + static void Term() {} /** * Return the version numbers for the library. If the parameter is not @@ -80,46 +80,44 @@ public: static void PurgeFontCache(); /** - * Scaling bitmaps with the SkPaint::kHigh_FilterLevel setting is + * Scaling bitmaps with the kHigh_SkFilterQuality setting is * expensive, so the result is saved in the global Scaled Image * Cache. * * This function returns the memory usage of the Scaled Image Cache. */ - static size_t GetImageCacheTotalBytesUsed(); - /** - * These functions get/set the memory usage limit for the Scaled - * Image Cache. Bitmaps are purged from the cache when the - * memory useage exceeds this limit. - */ - static size_t GetImageCacheTotalByteLimit(); - static size_t SetImageCacheTotalByteLimit(size_t newLimit); - - // DEPRECATED - static size_t GetImageCacheBytesUsed() { - return GetImageCacheTotalBytesUsed(); - } - // DEPRECATED - static size_t GetImageCacheByteLimit() { - return GetImageCacheTotalByteLimit(); - } - // DEPRECATED - static size_t SetImageCacheByteLimit(size_t newLimit) { - return SetImageCacheTotalByteLimit(newLimit); - } + static size_t GetResourceCacheTotalBytesUsed(); /** - * Scaling bitmaps with the SkPaint::kHigh_FilterLevel setting is - * expensive, so the result is saved in the global Scaled Image - * Cache. When the resulting bitmap is too large, this can - * overload the cache. If the ImageCacheSingleAllocationByteLimit - * is set to a non-zero number, and the resulting bitmap would be - * larger than that value, the bitmap scaling algorithm falls - * back onto a cheaper algorithm and does not cache the result. - * Zero is the default value. + * These functions get/set the memory usage limit for the resource cache, used for temporary + * bitmaps and other resources. Entries are purged from the cache when the memory useage + * exceeds this limit. */ - static size_t GetImageCacheSingleAllocationByteLimit(); - static size_t SetImageCacheSingleAllocationByteLimit(size_t newLimit); + static size_t GetResourceCacheTotalByteLimit(); + static size_t SetResourceCacheTotalByteLimit(size_t newLimit); + + /** + * For debugging purposes, this will attempt to purge the resource cache. It + * does not change the limit. + */ + static void PurgeResourceCache(); + + /** + * When the cachable entry is very lage (e.g. a large scaled bitmap), adding it to the cache + * can cause most/all of the existing entries to be purged. To avoid the, the client can set + * a limit for a single allocation. If a cacheable entry would have been cached, but its size + * exceeds this limit, then we do not attempt to cache it at all. + * + * Zero is the default value, meaning we always attempt to cache entries. + */ + static size_t GetResourceCacheSingleAllocationByteLimit(); + static size_t SetResourceCacheSingleAllocationByteLimit(size_t newLimit); + + /** + * Dumps memory usage of caches using the SkTraceMemoryDump interface. See SkTraceMemoryDump + * for usage of this method. + */ + static void DumpMemoryStatistics(SkTraceMemoryDump* dump); /** * Applications with command line options may pass optional state, such @@ -151,12 +149,17 @@ public: */ static void SetTLSFontCacheLimit(size_t bytes); -private: - /** This is automatically called by SkGraphics::Init(), and must be - implemented by the host OS. This allows the host OS to register a callback - with the C++ runtime to call SkGraphics::FreeCaches() - */ - static void InstallNewHandler(); + typedef SkImageGenerator* (*ImageGeneratorFromEncodedFactory)(SkData*); + + /** + * To instantiate images from encoded data, first looks at this runtime function-ptr. If it + * exists, it is called to create an SkImageGenerator from SkData. If there is no function-ptr + * or there is, but it returns NULL, then skia will call its internal default implementation. + * + * Returns the previous factory (which could be NULL). + */ + static ImageGeneratorFromEncodedFactory + SetImageGeneratorFromEncodedFactory(ImageGeneratorFromEncodedFactory); }; class SkAutoGraphics { @@ -164,9 +167,6 @@ public: SkAutoGraphics() { SkGraphics::Init(); } - ~SkAutoGraphics() { - SkGraphics::Term(); - } }; #endif diff --git a/gfx/skia/skia/include/core/SkImage.h b/gfx/skia/skia/include/core/SkImage.h index 04e184370f73..d6b10a8e186b 100644 --- a/gfx/skia/skia/include/core/SkImage.h +++ b/gfx/skia/skia/include/core/SkImage.h @@ -8,6 +8,7 @@ #ifndef SkImage_DEFINED #define SkImage_DEFINED +#include "SkFilterQuality.h" #include "SkImageInfo.h" #include "SkImageEncoder.h" #include "SkRefCnt.h" @@ -16,7 +17,13 @@ class SkData; class SkCanvas; +class SkColorTable; +class SkImageGenerator; class SkPaint; +class SkPicture; +class SkPixelSerializer; +class SkString; +class SkSurface; class GrContext; class GrTexture; @@ -29,50 +36,128 @@ class GrTexture; * The content of SkImage is always immutable, though the actual storage may * change, if for example that image can be re-created via encoded data or * other means. + * + * SkImage always has a non-zero dimensions. If there is a request to create a new image, either + * directly or via SkSurface, and either of the requested dimensions are zero, then NULL will be + * returned. */ class SK_API SkImage : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkImage) - typedef SkImageInfo Info; + typedef void* ReleaseContext; - static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes); + static SkImage* NewRasterCopy(const Info&, const void* pixels, size_t rowBytes, + SkColorTable* ctable = NULL); static SkImage* NewRasterData(const Info&, SkData* pixels, size_t rowBytes); - static SkImage* NewEncodedData(SkData*); + + typedef void (*RasterReleaseProc)(const void* pixels, ReleaseContext); /** - * GrTexture is a more logical parameter for this factory, but its - * interactions with scratch cache still has issues, so for now we take - * SkBitmap instead. This will be changed in the future. skbug.com/1449 + * Return a new Image referencing the specified pixels. These must remain valid and unchanged + * until the specified release-proc is called, indicating that Skia no longer has a reference + * to the pixels. + * + * Returns NULL if the requested Info is unsupported. */ - static SkImage* NewTexture(const SkBitmap&); + static SkImage* NewFromRaster(const Info&, const void* pixels, size_t rowBytes, + RasterReleaseProc, ReleaseContext); + + /** + * Construct a new image from the specified bitmap. If the bitmap is marked immutable, and + * its pixel memory is shareable, it may be shared instead of copied. + */ + static SkImage* NewFromBitmap(const SkBitmap&); + + /** + * Construct a new SkImage based on the given ImageGenerator. + * This function will always take ownership of the passed + * ImageGenerator. Returns NULL on error. + * + * If a subset is specified, it must be contained within the generator's bounds. + */ + static SkImage* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = NULL); + + /** + * Construct a new SkImage based on the specified encoded data. Returns NULL on failure, + * which can mean that the format of the encoded data was not recognized/supported. + * + * If a subset is specified, it must be contained within the encoded data's bounds. + * + * Regardless of success or failure, the caller is responsible for managing their ownership + * of the data. + */ + static SkImage* NewFromEncoded(SkData* encoded, const SkIRect* subset = NULL); + + /** + * Create a new image from the specified descriptor. Note - the caller is responsible for + * managing the lifetime of the underlying platform texture. + * + * Will return NULL if the specified descriptor is unsupported. + */ + static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc) { + return NewFromTexture(ctx, desc, kPremul_SkAlphaType, NULL, NULL); + } + + static SkImage* NewFromTexture(GrContext* ctx, const GrBackendTextureDesc& de, SkAlphaType at) { + return NewFromTexture(ctx, de, at, NULL, NULL); + } + + typedef void (*TextureReleaseProc)(ReleaseContext); + + /** + * Create a new image from the specified descriptor. The underlying platform texture must stay + * valid and unaltered until the specified release-proc is invoked, indicating that Skia + * no longer is holding a reference to it. + * + * Will return NULL if the specified descriptor is unsupported. + */ + static SkImage* NewFromTexture(GrContext*, const GrBackendTextureDesc&, SkAlphaType, + TextureReleaseProc, ReleaseContext); + + /** + * Create a new image from the specified descriptor. Note - Skia will delete or recycle the + * texture when the image is released. + * + * Will return NULL if the specified descriptor is unsupported. + */ + static SkImage* NewFromAdoptedTexture(GrContext*, const GrBackendTextureDesc&, + SkAlphaType = kPremul_SkAlphaType); + + /** + * Create a new image by copying the pixels from the specified descriptor. No reference is + * kept to the original platform texture. + * + * Will return NULL if the specified descriptor is unsupported. + */ + static SkImage* NewFromTextureCopy(GrContext*, const GrBackendTextureDesc&, + SkAlphaType = kPremul_SkAlphaType); + + /** + * Create a new image by copying the pixels from the specified y, u, v textures. The data + * from the textures is immediately ingested into the image and the textures can be modified or + * deleted after the function returns. The image will have the dimensions of the y texture. + */ + static SkImage* NewFromYUVTexturesCopy(GrContext*, SkYUVColorSpace, + const GrBackendObject yuvTextureHandles[3], + const SkISize yuvSizes[3], + GrSurfaceOrigin); + + static SkImage* NewFromPicture(const SkPicture*, const SkISize& dimensions, + const SkMatrix*, const SkPaint*); + + /////////////////////////////////////////////////////////////////////////////////////////////// int width() const { return fWidth; } int height() const { return fHeight; } + SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } + SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); } uint32_t uniqueID() const { return fUniqueID; } - - /** - * Return the GrTexture that stores the image pixels. Calling getTexture - * does not affect the reference count of the GrTexture object. - * Will return NULL if the image does not use a texture. - */ - GrTexture* getTexture(); + virtual bool isOpaque() const { return false; } virtual SkShader* newShader(SkShader::TileMode, SkShader::TileMode, const SkMatrix* localMatrix = NULL) const; - void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); - - /** - * Draw the image, cropped to the src rect, to the dst rect of a canvas. - * If src is larger than the bounds of the image, the rest of the image is - * filled with transparent black pixels. - * - * See SkCanvas::drawBitmapRectToRect for similar behavior. - */ - void draw(SkCanvas*, const SkRect* src, const SkRect& dst, const SkPaint*); - /** * If the image has direct access to its pixels (i.e. they are in local * RAM) return the (const) address of those pixels, and if not null, return @@ -84,57 +169,192 @@ public: */ const void* peekPixels(SkImageInfo* info, size_t* rowBytes) const; + /** + * If the image has direct access to its pixels (i.e. they are in local + * RAM) return the (const) address of those pixels, and if not null, return + * true, and if pixmap is not NULL, set it to point into the image. + * + * On failure, return false and ignore the pixmap parameter. + */ + bool peekPixels(SkPixmap* pixmap) const; + + /** + * Some images have to perform preliminary work in preparation for drawing. This can be + * decoding, uploading to a GPU, or other tasks. These happen automatically when an image + * is drawn, and often they are cached so that the cost is only paid the first time. + * + * Preroll() can be called before drawing to try to perform this prepatory work ahead of time. + * For images that have no such work, this returns instantly. Others may do some thing to + * prepare their cache and then return. + * + * If the image will drawn to a GPU-backed canvas or surface, pass the associated GrContext. + * If the image will be drawn to any other type of canvas or surface, pass null. + */ + void preroll(GrContext* = nullptr) const; + + // DEPRECATED + GrTexture* getTexture() const; + + /** + * Returns true if the image is texture backed. + */ + bool isTextureBacked() const; + + /** + * Retrieves the backend API handle of the texture. If flushPendingGrContextIO then the + * GrContext will issue to the backend API any deferred IO operations on the texture before + * returning. + */ + GrBackendObject getTextureHandle(bool flushPendingGrContextIO) const; + + /** + * Hints to image calls where the system might cache computed intermediates (e.g. the results + * of decoding or a read-back from the GPU. Passing kAllow signals that the system's default + * behavior is fine. Passing kDisallow signals that caching should be avoided. + */ + enum CachingHint { + kAllow_CachingHint, + kDisallow_CachingHint, + }; + + /** + * Copy the pixels from the image into the specified buffer (pixels + rowBytes), + * converting them into the requested format (dstInfo). The image pixels are read + * starting at the specified (srcX,srcY) location. + * + * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle + * + * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height()); + * + * srcR is intersected with the bounds of the image. If this intersection is not empty, + * then we have two sets of pixels (of equal size). Replace the dst pixels with the + * corresponding src pixels, performing any colortype/alphatype transformations needed + * (in the case where the src and dst have different colortypes or alphatypes). + * + * This call can fail, returning false, for several reasons: + * - If srcR does not intersect the image bounds. + * - If the requested colortype/alphatype cannot be converted from the image's types. + */ + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + int srcX, int srcY, CachingHint = kAllow_CachingHint) const; + + bool readPixels(const SkPixmap& dst, int srcX, int srcY, + CachingHint = kAllow_CachingHint) const; + + /** + * Copy the pixels from this image into the dst pixmap, converting as needed into dst's + * colortype/alphatype. If the conversion cannot be performed, false is returned. + * + * If dst's dimensions differ from the src dimension, the image will be scaled, applying the + * specified filter-quality. + */ + bool scalePixels(const SkPixmap& dst, SkFilterQuality, CachingHint = kAllow_CachingHint) const; + /** * Encode the image's pixels and return the result as a new SkData, which * the caller must manage (i.e. call unref() when they are done). * * If the image type cannot be encoded, or the requested encoder type is * not supported, this will return NULL. + * + * Note: this will attempt to encode the image's pixels in the specified format, + * even if the image returns a data from refEncoded(). That data will be ignored. */ - SkData* encode(SkImageEncoder::Type t = SkImageEncoder::kPNG_Type, - int quality = 80) const; + SkData* encode(SkImageEncoder::Type, int quality) const; + + /** + * Encode the image and return the result as a caller-managed SkData. This will + * attempt to reuse existing encoded data (as returned by refEncoded). + * + * We defer to the SkPixelSerializer both for vetting existing encoded data + * (useEncodedData) and for encoding the image (encodePixels) when no such data is + * present or is rejected by the serializer. + * + * If not specified, we use a default serializer which 1) always accepts existing data + * (in any format) and 2) encodes to PNG. + * + * If no compatible encoded data exists and encoding fails, this method will also + * fail (return NULL). + */ + SkData* encode(SkPixelSerializer* = nullptr) const; + + /** + * If the image already has its contents in encoded form (e.g. PNG or JPEG), return a ref + * to that data (which the caller must call unref() on). The caller is responsible for calling + * unref on the data when they are done. + * + * If the image does not already has its contents in encoded form, return NULL. + * + * Note: to force the image to return its contents as encoded data, try calling encode(...). + */ + SkData* refEncoded() const; + + const char* toString(SkString*) const; + + /** + * Return a new image that is a subset of this image. The underlying implementation may + * share the pixels, or it may make a copy. + * + * If subset does not intersect the bounds of this image, or the copy/share cannot be made, + * NULL will be returned. + */ + SkImage* newSubset(const SkIRect& subset) const; + + // Helper functions to convert to SkBitmap + + enum LegacyBitmapMode { + kRO_LegacyBitmapMode, + kRW_LegacyBitmapMode, + }; + + /** + * Attempt to create a bitmap with the same pixels as the image. The result will always be + * a raster-backed bitmap (texture-backed bitmaps are DEPRECATED, and not supported here). + * + * If the mode is kRO (read-only), the resulting bitmap will be marked as immutable. + * + * On succcess, returns true. On failure, returns false and the bitmap parameter will be reset + * to empty. + */ + bool asLegacyBitmap(SkBitmap*, LegacyBitmapMode) const; + + /** + * Returns true if the image is backed by an image-generator or other src that creates + * (and caches) its pixels / texture on-demand. + */ + bool isLazyGenerated() const; + + /** + * Apply the specified filter to this image, and return the result as a new image. + * + * if forceResultToOriginalSize is true, then the resulting image will be the same size as the + * src, regardless of the normal output of the filter. + * + * If offset is non-null, it is set to the relative offset needed to draw the resulting image + * in the same logical place as the original. + * + * e.g. + * If the filter makes the result larger by a margin of 4 the output would be: + * result->width() == this->width + 8 + * result->height() == this->height + 8 + * offset.x() == -4 + * offset.y() == -4 + * + * If the filter fails to create a resulting image, null is returned, and the offset parameter + * (if specified) will be undefined. + */ + SkImage* applyFilter(SkImageFilter* filter, SkIPoint* offset, + bool forceResultToOriginalSize) const; protected: - SkImage(int width, int height) : - fWidth(width), - fHeight(height), - fUniqueID(NextUniqueID()) { - - SkASSERT(width >= 0); - SkASSERT(height >= 0); - } + SkImage(int width, int height, uint32_t uniqueID); private: const int fWidth; const int fHeight; const uint32_t fUniqueID; - static uint32_t NextUniqueID(); - typedef SkRefCnt INHERITED; - - /** - * Return a copy of the image's pixels, limiting them to the subset - * rectangle's intersection wit the image bounds. If subset is NULL, then - * the entire image will be considered. - * - * If the bitmap's pixels have already been allocated, then readPixels() - * will succeed only if it can support converting the image's pixels into - * the bitmap's ColorType/AlphaType. Any pixels in the bitmap that do not - * intersect with the image's bounds and the subset (if not null) will be - * left untouched. - * - * If the bitmap is initially empty/unallocated, then it will be allocated - * using the default allocator, and the ColorType/AlphaType will be chosen - * to most closely fit the image's configuration. - * - * On failure, false will be returned, and bitmap will unmodified. - */ - // On ice for now: - // - should it respect the particular colortype/alphatype of the src - // - should it have separate entrypoints for preallocated and not bitmaps? - // - isn't it enough to allow the caller to draw() the image into a canvas? - bool readPixels(SkBitmap* bitmap, const SkIRect* subset = NULL) const; }; #endif diff --git a/gfx/skia/skia/include/core/SkImageDecoder.h b/gfx/skia/skia/include/core/SkImageDecoder.h index b258afedce18..30323b59ee56 100644 --- a/gfx/skia/skia/include/core/SkImageDecoder.h +++ b/gfx/skia/skia/include/core/SkImageDecoder.h @@ -10,11 +10,14 @@ #include "SkBitmap.h" #include "SkImage.h" +#include "SkPngChunkReader.h" #include "SkRect.h" #include "SkRefCnt.h" #include "SkTRegistry.h" #include "SkTypes.h" +//#define SK_LEGACY_PEEKER + class SkStream; class SkStreamRewindable; @@ -26,6 +29,7 @@ class SkImageDecoder : SkNoncopyable { public: virtual ~SkImageDecoder(); + // TODO (scroggo): Merge with SkEncodedFormat enum Format { kUnknown_Format, kBMP_Format, @@ -37,6 +41,7 @@ public: kWEBP_Format, kPKM_Format, kKTX_Format, + kASTC_Format, kLastKnownFormat = kKTX_Format, }; @@ -46,6 +51,15 @@ public: */ virtual Format getFormat() const; + /** If planes or rowBytes is NULL, decodes the header and computes componentSizes + for memory allocation. + Otherwise, decodes the YUV planes into the provided image planes and + updates componentSizes to the final image size. + Returns whether the decoding was successful. + */ + bool decodeYUV8Planes(SkStream* stream, SkISize componentSizes[3], void* planes[3], + size_t rowBytes[3], SkYUVColorSpace*); + /** Return the format of the SkStreamRewindable or kUnknown_Format if it cannot be determined. Rewinds the stream before returning. */ @@ -115,95 +129,20 @@ public: */ bool getRequireUnpremultipliedColors() const { return fRequireUnpremultipliedColors; } - /** \class Peeker - - Base class for optional callbacks to retrieve meta/chunk data out of - an image as it is being decoded. - */ - class Peeker : public SkRefCnt { +#ifdef SK_LEGACY_PEEKER + // Android subclasses SkImageDecoder::Peeker, which has been changed into SkPngChunkReader. + // Temporarily use this class until Android can be updated to directly inherit from + // SkPngChunkReader. + class Peeker : public SkPngChunkReader { public: - SK_DECLARE_INST_COUNT(Peeker) - - /** Return true to continue decoding, or false to indicate an error, which - will cause the decoder to not return the image. - */ + bool readChunk(const char tag[], const void* data, size_t length) final { + return this->peek(tag, data, length); + } virtual bool peek(const char tag[], const void* data, size_t length) = 0; - private: - typedef SkRefCnt INHERITED; }; - - Peeker* getPeeker() const { return fPeeker; } - Peeker* setPeeker(Peeker*); - -#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER - /** \class Chooser - - Base class for optional callbacks to choose an image from a format that - contains multiple images. - */ - class Chooser : public SkRefCnt { - public: - SK_DECLARE_INST_COUNT(Chooser) - - virtual void begin(int count) {} - virtual void inspect(int index, SkBitmap::Config config, int width, int height) {} - /** Return the index of the subimage you want, or -1 to choose none of them. - */ - virtual int choose() = 0; - - private: - typedef SkRefCnt INHERITED; - }; - - Chooser* getChooser() const { return fChooser; } - Chooser* setChooser(Chooser*); -#endif - -#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG - /** - * Optional table describing the caller's preferred config based on - * information about the src data. Each field should be set to the - * preferred config for a src described in the name of the field. The - * src attributes are described in terms of depth (8-index, - * 8bit-grayscale, or 8-bits/component) and whether there is per-pixel - * alpha (does not apply to grayscale). If the caller has no preference - * for a particular src type, its slot should be set to kNo_Config. - * - * NOTE ABOUT PREFERRED CONFIGS: - * If a config is preferred, either using a pref table or as a parameter - * to some flavor of decode, it is still at the discretion of the codec - * as to what output config is actually returned, as it may not be able - * to support the caller's preference. - * - * If a bitmap is decoded into SkBitmap::A8_Config, the resulting bitmap - * will either be a conversion of the grayscale in the case of a - * grayscale source or the alpha channel in the case of a source with - * an alpha channel. - */ - struct PrefConfigTable { - SkBitmap::Config fPrefFor_8Index_NoAlpha_src; - SkBitmap::Config fPrefFor_8Index_YesAlpha_src; - SkBitmap::Config fPrefFor_8Gray_src; - SkBitmap::Config fPrefFor_8bpc_NoAlpha_src; - SkBitmap::Config fPrefFor_8bpc_YesAlpha_src; - }; - - /** - * Set an optional table for specifying the caller's preferred config - * based on information about the src data. - * - * The default is no preference, which will assume the config set by - * decode is preferred. - */ - void setPrefConfigTable(const PrefConfigTable&); - - /** - * Do not use a PrefConfigTable to determine the output config. This - * is the default, so there is no need to call unless a PrefConfigTable - * was previously set. - */ - void resetPrefConfigTable() { fUsePrefTable = false; } #endif + SkPngChunkReader* getPeeker() const { return fPeeker; } + SkPngChunkReader* setPeeker(SkPngChunkReader*); /** * By default, the codec will try to comply with the "pref" colortype @@ -261,13 +200,26 @@ public: kDecodePixels_Mode //!< return entire bitmap (including pixels) }; + /** Result of a decode. If read as a boolean, a partial success is + considered a success (true). + */ + enum Result { + kFailure = 0, //!< Image failed to decode. bitmap will be + // unchanged. + kPartialSuccess = 1, //!< Part of the image decoded. The rest is + // filled in automatically + kSuccess = 2 //!< The entire image was decoded, if Mode is + // kDecodePixels_Mode, or the bounds were + // decoded, in kDecodeBounds_Mode. + }; + /** Given a stream, decode it into the specified bitmap. If the decoder can decompress the image, it calls bitmap.setInfo(), and then if the Mode is kDecodePixels_Mode, call allocPixelRef(), which will allocated a pixelRef. To access the pixel memory, the codec needs to call lockPixels/unlockPixels on the bitmap. It can then set the pixels with the decompressed image. - * If the image cannot be decompressed, return false. After the + * If the image cannot be decompressed, return kFailure. After the * decoding, the function converts the decoded colortype in bitmap * to pref if possible. Whether a conversion is feasible is * tested by Bitmap::canCopyTo(pref). @@ -277,32 +229,14 @@ public: to allocate the memory from a cache, volatile memory, or even from an existing bitmap's memory. - If a Peeker is installed via setPeeker, it may be used to peek into - meta data during the decode. + If an SkPngChunkReader is installed via setPeeker, it may be used to + peek into meta data during the decode. */ - bool decode(SkStream*, SkBitmap* bitmap, SkColorType pref, Mode); - bool decode(SkStream* stream, SkBitmap* bitmap, Mode mode) { + Result decode(SkStream*, SkBitmap* bitmap, SkColorType pref, Mode); + Result decode(SkStream* stream, SkBitmap* bitmap, Mode mode) { return this->decode(stream, bitmap, kUnknown_SkColorType, mode); } - /** - * Given a stream, build an index for doing tile-based decode. - * The built index will be saved in the decoder, and the image size will - * be returned in width and height. - * - * Return true for success or false on failure. - */ - bool buildTileIndex(SkStreamRewindable*, int *width, int *height); - - /** - * Decode a rectangle subset in the image. - * The method can only be called after buildTileIndex(). - * - * Return true for success. - * Return false if the index is never built or failing in decoding. - */ - bool decodeSubset(SkBitmap* bm, const SkIRect& subset, SkColorType pref); - /** Given a stream, this will try to find an appropriate decoder object. If none is found, the method returns NULL. */ @@ -311,8 +245,7 @@ public: /** Decode the image stored in the specified file, and store the result in bitmap. Return true for success or false on failure. - @param pref If the PrefConfigTable is not set, prefer this colortype. - See NOTE ABOUT PREFERRED CONFIGS. + @param pref Prefer this colortype. @param format On success, if format is non-null, it is set to the format of the decoded file. On failure it is ignored. @@ -326,8 +259,7 @@ public: /** Decode the image stored in the specified memory buffer, and store the result in bitmap. Return true for success or false on failure. - @param pref If the PrefConfigTable is not set, prefer this colortype. - See NOTE ABOUT PREFERRED CONFIGS. + @param pref Prefer this colortype. @param format On success, if format is non-null, it is set to the format of the decoded buffer. On failure it is ignored. @@ -338,26 +270,10 @@ public: return DecodeMemory(buffer, size, bitmap, kUnknown_SkColorType, kDecodePixels_Mode, NULL); } - /** - * Struct containing information about a pixel destination. - */ - struct Target { - /** - * Pre-allocated memory. - */ - void* fAddr; - - /** - * Rowbytes of the allocated memory. - */ - size_t fRowBytes; - }; - /** Decode the image stored in the specified SkStreamRewindable, and store the result in bitmap. Return true for success or false on failure. - @param pref If the PrefConfigTable is not set, prefer this colortype. - See NOTE ABOUT PREFERRED CONFIGS. + @param pref Prefer this colortype. @param format On success, if format is non-null, it is set to the format of the decoded stream. On failure it is ignored. @@ -370,39 +286,20 @@ public: protected: // must be overridden in subclasses. This guy is called by decode(...) - virtual bool onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0; + virtual Result onDecode(SkStream*, SkBitmap* bitmap, Mode) = 0; - // If the decoder wants to support tiled based decoding, - // this method must be overridden. This guy is called by buildTileIndex(...) - virtual bool onBuildTileIndex(SkStreamRewindable*, int *width, int *height) { + /** If planes or rowBytes is NULL, decodes the header and computes componentSizes + for memory allocation. + Otherwise, decodes the YUV planes into the provided image planes and + updates componentSizes to the final image size. + Returns whether the decoding was successful. + */ + virtual bool onDecodeYUV8Planes(SkStream*, SkISize[3] /*componentSizes*/, + void*[3] /*planes*/, size_t[3] /*rowBytes*/, + SkYUVColorSpace*) { return false; } - // If the decoder wants to support tiled based decoding, - // this method must be overridden. This guy is called by decodeRegion(...) - virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) { - return false; - } - - /* - * Crop a rectangle from the src Bitmap to the dest Bitmap. src and dst are - * both sampled by sampleSize from an original Bitmap. - * - * @param dst the destination bitmap. - * @param src the source bitmap that is sampled by sampleSize from the - * original bitmap. - * @param sampleSize the sample size that src is sampled from the original bitmap. - * @param (dstX, dstY) the upper-left point of the dest bitmap in terms of - * the coordinate in the original bitmap. - * @param (width, height) the width and height of the unsampled dst. - * @param (srcX, srcY) the upper-left point of the src bitmap in terms of - * the coordinate in the original bitmap. - * @return bool Whether or not it succeeded. - */ - bool cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize, - int dstX, int dstY, int width, int height, - int srcX, int srcY); - /** * Copy all fields on this decoder to the other decoder. Used by subclasses * to decode a subimage using a different decoder, but with the same settings. @@ -428,12 +325,6 @@ protected: * Return the default preference being used by the current or latest call to decode. */ SkColorType getDefaultPref() { return fDefaultPref; } - -#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER - // helper function for decoders to handle the (common) case where there is only - // once choice available in the image file. - bool chooseFromOneChoice(SkColorType, int width, int height) const; -#endif /* Helper for subclasses. Call this to allocate the pixel memory given the bitmap's info. Returns true on success. This method handles checking for an optional Allocator. @@ -459,17 +350,10 @@ protected: SkColorType getPrefColorType(SrcDepth, bool hasAlpha) const; private: - Peeker* fPeeker; -#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER - Chooser* fChooser; -#endif + SkPngChunkReader* fPeeker; SkBitmap::Allocator* fAllocator; int fSampleSize; SkColorType fDefaultPref; // use if fUsePrefTable is false -#ifdef SK_SUPPORT_LEGACY_BITMAP_CONFIG - PrefConfigTable fPrefTable; // use if fUsePrefTable is true - bool fUsePrefTable; -#endif bool fPreserveSrcDepth; bool fDitherImage; bool fSkipWritingZeroes; @@ -486,7 +370,7 @@ private: */ class SkImageDecoderFactory : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkImageDecoderFactory) + virtual SkImageDecoder* newDecoder(SkStreamRewindable*) = 0; @@ -509,10 +393,8 @@ public: // This macro defines the global creation entry point for each decoder. Each // decoder implementation that registers with the decoder factory must call it. -#define DEFINE_DECODER_CREATOR(codec) \ - SkImageDecoder *Create ## codec () { \ - return SkNEW( Sk ## codec ); \ - } +#define DEFINE_DECODER_CREATOR(codec) \ + SkImageDecoder* Create##codec() { return new Sk##codec; } // All the decoders known by Skia. Note that, depending on the compiler settings, // not all of these will be available @@ -525,6 +407,7 @@ DECLARE_DECODER_CREATOR(WBMPImageDecoder); DECLARE_DECODER_CREATOR(WEBPImageDecoder); DECLARE_DECODER_CREATOR(PKMImageDecoder); DECLARE_DECODER_CREATOR(KTXImageDecoder); +DECLARE_DECODER_CREATOR(ASTCImageDecoder); // Typedefs to make registering decoder and formatter callbacks easier. // These have to be defined outside SkImageDecoder. :( diff --git a/gfx/skia/skia/include/core/SkImageEncoder.h b/gfx/skia/skia/include/core/SkImageEncoder.h index 4d4d2a83c0f1..fc999dcc189d 100644 --- a/gfx/skia/skia/include/core/SkImageEncoder.h +++ b/gfx/skia/skia/include/core/SkImageEncoder.h @@ -1,14 +1,14 @@ - /* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ + #ifndef SkImageEncoder_DEFINED #define SkImageEncoder_DEFINED -#include "SkTypes.h" +#include "SkImageInfo.h" #include "SkTRegistry.h" class SkBitmap; @@ -17,6 +17,7 @@ class SkWStream; class SkImageEncoder { public: + // TODO (scroggo): Merge with SkEncodedFormat. enum Type { kUnknown_Type, kBMP_Type, @@ -59,7 +60,10 @@ public: */ bool encodeStream(SkWStream* stream, const SkBitmap& bm, int quality); + static SkData* EncodeData(const SkImageInfo&, const void* pixels, size_t rowBytes, + Type, int quality); static SkData* EncodeData(const SkBitmap&, Type, int quality); + static bool EncodeFile(const char file[], const SkBitmap&, Type, int quality); static bool EncodeStream(SkWStream*, const SkBitmap&, Type, @@ -83,10 +87,8 @@ protected: // This macro defines the global creation entry point for each encoder. Each // encoder implementation that registers with the encoder factory must call it. -#define DEFINE_ENCODER_CREATOR(codec) \ - SkImageEncoder *Create ## codec () { \ - return SkNEW( Sk ## codec ); \ - } +#define DEFINE_ENCODER_CREATOR(codec) \ + SkImageEncoder* Create##codec() { return new Sk##codec; } // All the encoders known by Skia. Note that, depending on the compiler settings, // not all of these will be available diff --git a/gfx/skia/skia/include/core/SkImageFilter.h b/gfx/skia/skia/include/core/SkImageFilter.h index cd34ba3f91bd..d90df29c8bfe 100644 --- a/gfx/skia/skia/include/core/SkImageFilter.h +++ b/gfx/skia/skia/include/core/SkImageFilter.h @@ -8,17 +8,19 @@ #ifndef SkImageFilter_DEFINED #define SkImageFilter_DEFINED +#include "../private/SkTemplates.h" +#include "SkFilterQuality.h" #include "SkFlattenable.h" #include "SkMatrix.h" #include "SkRect.h" -#include "SkTemplates.h" +#include "SkSurfaceProps.h" +class GrFragmentProcessor; +class GrTexture; +class SkBaseDevice; class SkBitmap; class SkColorFilter; -class SkBaseDevice; struct SkIPoint; -class GrEffect; -class GrTexture; /** * Base class for image filters. If one is installed in the paint, then @@ -29,66 +31,109 @@ class GrTexture; */ class SK_API SkImageFilter : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkImageFilter) + // This cache maps from (filter's unique ID + CTM + clipBounds + src bitmap generation ID) to + // (result, offset). + class Cache : public SkRefCnt { + public: + struct Key; + virtual ~Cache() {} + static Cache* Create(size_t maxBytes); + static Cache* Get(); + virtual bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const = 0; + virtual void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) = 0; + virtual void purge() {} + }; + + enum SizeConstraint { + kExact_SizeConstraint, + kApprox_SizeConstraint, + }; + + class Context { + public: + Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache, + SizeConstraint constraint) + : fCTM(ctm) + , fClipBounds(clipBounds) + , fCache(cache) + , fSizeConstraint(constraint) + {} + + const SkMatrix& ctm() const { return fCTM; } + const SkIRect& clipBounds() const { return fClipBounds; } + Cache* cache() const { return fCache; } + SizeConstraint sizeConstraint() const { return fSizeConstraint; } + + private: + SkMatrix fCTM; + SkIRect fClipBounds; + Cache* fCache; + SizeConstraint fSizeConstraint; + }; class CropRect { public: enum CropEdge { kHasLeft_CropEdge = 0x01, kHasTop_CropEdge = 0x02, - kHasRight_CropEdge = 0x04, - kHasBottom_CropEdge = 0x08, + kHasWidth_CropEdge = 0x04, + kHasHeight_CropEdge = 0x08, kHasAll_CropEdge = 0x0F, }; CropRect() {} - explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) : fRect(rect), fFlags(flags) {} + explicit CropRect(const SkRect& rect, uint32_t flags = kHasAll_CropEdge) + : fRect(rect), fFlags(flags) {} uint32_t flags() const { return fFlags; } const SkRect& rect() const { return fRect; } +#ifndef SK_IGNORE_TO_STRING + void toString(SkString* str) const; +#endif + + /** + * Apply this cropRect to the imageBounds. If a given edge of the cropRect is not + * set, then the corresponding edge from imageBounds will be used. + * + * Note: imageBounds is in "device" space, as the output cropped rectangle will be, + * so the context's CTM is ignore for those. It is only applied the croprect's bounds. + * + * The resulting rect will be intersected with the context's clip. If that intersection is + * empty, then this returns false and cropped is unmodified. + */ + bool applyTo(const SkIRect& imageBounds, const Context&, SkIRect* cropped) const; + private: SkRect fRect; uint32_t fFlags; }; - class SK_API Cache : public SkRefCnt { - public: - // By default, we cache only image filters with 2 or more children. - // Values less than 2 mean always cache; values greater than 2 are not supported. - static Cache* Create(int minChildren = 2); - virtual ~Cache() {} - virtual bool get(const SkImageFilter* key, SkBitmap* result, SkIPoint* offset) = 0; - virtual void set(const SkImageFilter* key, - const SkBitmap& result, const SkIPoint& offset) = 0; - virtual void remove(const SkImageFilter* key) = 0; - }; - - class Context { - public: - Context(const SkMatrix& ctm, const SkIRect& clipBounds, Cache* cache) : - fCTM(ctm), fClipBounds(clipBounds), fCache(cache) { - } - const SkMatrix& ctm() const { return fCTM; } - const SkIRect& clipBounds() const { return fClipBounds; } - Cache* cache() const { return fCache; } - private: - SkMatrix fCTM; - SkIRect fClipBounds; - Cache* fCache; - }; - class Proxy { public: - virtual ~Proxy() {}; + virtual ~Proxy() {} virtual SkBaseDevice* createDevice(int width, int height) = 0; - // returns true if the proxy can handle this filter natively - virtual bool canHandleImageFilter(const SkImageFilter*) = 0; - // returns true if the proxy handled the filter itself. if this returns + + // Returns true if the proxy handled the filter itself. If this returns // false then the filter's code will be called. virtual bool filterImage(const SkImageFilter*, const SkBitmap& src, - const Context&, + const SkImageFilter::Context&, SkBitmap* result, SkIPoint* offset) = 0; }; + class DeviceProxy : public Proxy { + public: + DeviceProxy(SkBaseDevice* device) : fDevice(device) {} + + SkBaseDevice* createDevice(int width, int height) override; + + // Returns true if the proxy handled the filter itself. If this returns + // false then the filter's code will be called. + bool filterImage(const SkImageFilter*, const SkBitmap& src, const SkImageFilter::Context&, + SkBitmap* result, SkIPoint* offset) override; + + private: + SkBaseDevice* fDevice; + }; + /** * Request a new (result) image to be created from the src image. * If the src has no pixels (isNull()) then the request just wants to @@ -114,8 +159,8 @@ public: /** * Returns true if the filter can be processed on the GPU. This is most * often used for multi-pass effects, where intermediate results must be - * rendered to textures. For single-pass effects, use asNewEffect(). - * The default implementation returns asNewEffect(NULL, NULL, SkMatrix::I(), + * rendered to textures. For single-pass effects, use asFragmentProcessor(). + * The default implementation returns asFragmentProcessor(NULL, NULL, SkMatrix::I(), * SkIRect()). */ virtual bool canFilterImageGPU() const; @@ -123,12 +168,12 @@ public: /** * Process this image filter on the GPU. This is most often used for * multi-pass effects, where intermediate results must be rendered to - * textures. For single-pass effects, use asNewEffect(). src is the + * textures. For single-pass effects, use asFragmentProcessor(). src is the * source image for processing, as a texture-backed bitmap. result is * the destination bitmap, which should contain a texture-backed pixelref * on success. offset is the amount to translate the resulting image * relative to the src when it is drawn. The default implementation does - * single-pass processing using asNewEffect(). + * single-pass processing using asFragmentProcessor(). */ virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const; @@ -140,7 +185,26 @@ public: * If this returns true, then if filterPtr is not null, it must be set to a ref'd colorfitler * (i.e. it may not be set to NULL). */ - virtual bool asColorFilter(SkColorFilter** filterPtr) const; + bool isColorFilterNode(SkColorFilter** filterPtr) const { + return this->onIsColorFilterNode(filterPtr); + } + + // DEPRECATED : use isColorFilterNode() instead + bool asColorFilter(SkColorFilter** filterPtr) const { + return this->isColorFilterNode(filterPtr); + } + + /** + * Returns true (and optionally returns a ref'd filter) if this imagefilter can be completely + * replaced by the returned colorfilter. i.e. the two effects will affect drawing in the + * same way. + */ + bool asAColorFilter(SkColorFilter** filterPtr) const { + return this->countInputs() > 0 && + NULL == this->getInput(0) && + !this->affectsTransparentBlack() && + this->isColorFilterNode(filterPtr); + } /** * Returns the number of inputs this filter will accept (some inputs can @@ -160,7 +224,8 @@ public: /** * Returns whether any edges of the crop rect have been set. The crop * rect is set at construction time, and determines which pixels from the - * input image will be processed. The size of the crop rect should be + * input image will be processed, and which pixels in the output image will be allowed. + * The size of the crop rect should be * used as the size of the destination image. The origin of this rect * should be used to offset access to the input images, and should also * be added to the "offset" parameter in onFilterImage and @@ -169,34 +234,44 @@ public: */ bool cropRectIsSet() const { return fCropRect.flags() != 0x0; } + CropRect getCropRect() const { return fCropRect; } + // Default impl returns union of all input bounds. virtual void computeFastBounds(const SkRect&, SkRect*) const; -#ifdef SK_SUPPORT_GPU + // Can this filter DAG compute the resulting bounds of an object-space rectangle? + bool canComputeFastBounds() const; + + /** + * If this filter can be represented by another filter + a localMatrix, return that filter, + * else return null. + */ + SkImageFilter* newWithLocalMatrix(const SkMatrix& matrix) const; + + /** + * Create an SkMatrixImageFilter, which transforms its input by the given matrix. + */ + static SkImageFilter* CreateMatrixFilter(const SkMatrix& matrix, + SkFilterQuality, + SkImageFilter* input = NULL); + +#if SK_SUPPORT_GPU /** * Wrap the given texture in a texture-backed SkBitmap. */ static void WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result); - /** - * Recursively evaluate this filter on the GPU. If the filter has no GPU - * implementation, it will be processed in software and uploaded to the GPU. - */ - bool getInputResultGPU(SkImageFilter::Proxy* proxy, const SkBitmap& src, const Context&, - SkBitmap* result, SkIPoint* offset) const; + // Helper function which invokes GPU filter processing on the + // input at the specified "index". If the input is null, it leaves + // "result" and "offset" untouched, and returns true. If the input + // has a GPU implementation, it will be invoked directly. + // Otherwise, the filter will be processed in software and + // uploaded to the GPU. + bool filterInputGPU(int index, SkImageFilter::Proxy* proxy, const SkBitmap& src, const Context&, + SkBitmap* result, SkIPoint* offset, bool relaxSizeConstraint = true) const; #endif - /** - * Set an external cache to be used for all image filter processing. This - * will replace the default intra-frame cache. - */ - static void SetExternalCache(Cache* cache); - - /** - * Returns the currently-set external cache, or NULL if none is set. - */ - static Cache* GetExternalCache(); - + SK_TO_STRING_PUREVIRT() SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter) protected: @@ -205,12 +280,22 @@ protected: Common() {} ~Common(); - bool unflatten(SkReadBuffer&, int expectedInputs = -1); + /** + * Attempt to unflatten the cropRect and the expected number of input filters. + * If any number of input filters is valid, pass -1. + * If this fails (i.e. corrupt buffer or contents) then return false and common will + * be left uninitialized. + * If this returns true, then inputCount() is the number of found input filters, each + * of which may be NULL or a valid imagefilter. + */ + bool unflatten(SkReadBuffer&, int expectedInputs); - CropRect cropRect() const { return fCropRect; } + const CropRect& cropRect() const { return fCropRect; } int inputCount() const { return fInputs.count(); } SkImageFilter** inputs() const { return fInputs.get(); } + SkImageFilter* getInput(int index) const { return fInputs[index]; } + // If the caller wants a copy of the inputs, call this and it will transfer ownership // of the unflattened input filters to the caller. This is just a short-cut for copying // the inputs, calling ref() on each, and then waiting for Common's destructor to call @@ -238,7 +323,7 @@ protected: */ explicit SkImageFilter(int inputCount, SkReadBuffer& rb); - virtual void flatten(SkWriteBuffer& wb) const SK_OVERRIDE; + void flatten(SkWriteBuffer&) const override; /** * This is the virtual which should be overridden by the derived class @@ -267,14 +352,34 @@ protected: // no inputs. virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const; - /** Computes source bounds as the src bitmap bounds offset by srcOffset. - * Apply the transformed crop rect to the bounds if any of the - * corresponding edge flags are set. Intersects the result against the - * context's clipBounds, and returns the result in "bounds". If there is - * no intersection, returns false and leaves "bounds" unchanged. + // Helper function which invokes filter processing on the input at the + // specified "index". If the input is null, it leaves "result" and + // "offset" untouched, and returns true. If the input is non-null, it + // calls filterImage() on that input, and returns true on success. + // i.e., return !getInput(index) || getInput(index)->filterImage(...); + bool filterInput(int index, Proxy*, const SkBitmap& src, const Context&, + SkBitmap* result, SkIPoint* offset, bool relaxSizeConstraint = true) const; + + /** + * Return true (and return a ref'd colorfilter) if this node in the DAG is just a + * colorfilter w/o CropRect constraints. + */ + virtual bool onIsColorFilterNode(SkColorFilter** /*filterPtr*/) const { + return false; + } + + /** Given a "src" bitmap and its "srcOffset", computes source and + * destination bounds for this filter. Initial bounds are the + * "src" bitmap bounds offset by "srcOffset". "dstBounds" are + * computed by transforming the crop rect by the context's CTM, + * applying it to the initial bounds, and intersecting the result + * with the context's clip bounds. "srcBounds" (if non-null) are + * computed by intersecting the initial bounds with "dstBounds", to + * ensure that we never sample outside of the crop rect (this restriction + * may be relaxed in the future). */ bool applyCropRect(const Context&, const SkBitmap& src, const SkIPoint& srcOffset, - SkIRect* bounds) const; + SkIRect* dstBounds, SkIRect* srcBounds = nullptr) const; /** Same as the above call, except that if the resulting crop rect is not * entirely contained by the source bitmap's bounds, it creates a new @@ -289,10 +394,10 @@ protected: /** * Returns true if the filter can be expressed a single-pass - * GrEffect, used to process this filter on the GPU, or false if + * GrProcessor, used to process this filter on the GPU, or false if * not. * - * If effect is non-NULL, a new GrEffect instance is stored + * If effect is non-NULL, a new GrProcessor instance is stored * in it. The caller assumes ownership of the stage, and it is up to the * caller to unref it. * @@ -302,16 +407,40 @@ protected: * will be called with (NULL, NULL, SkMatrix::I()) to query for support, * so returning "true" indicates support for all possible matrices. */ - virtual bool asNewEffect(GrEffect** effect, - GrTexture*, - const SkMatrix& matrix, - const SkIRect& bounds) const; + virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&, + const SkIRect& bounds) const; + + /** + * Returns true if this filter can cause transparent black pixels to become + * visible (ie., alpha > 0). The default implementation returns false. This + * function is non-recursive, i.e., only queries this filter and not its + * inputs. + */ + virtual bool affectsTransparentBlack() const; private: + friend class SkGraphics; + static void PurgeCache(); + + bool usesSrcInput() const { return fUsesSrcInput; } + typedef SkFlattenable INHERITED; int fInputCount; SkImageFilter** fInputs; + bool fUsesSrcInput; CropRect fCropRect; + uint32_t fUniqueID; // Globally unique }; +/** + * Helper to unflatten the common data, and return NULL if we fail. + */ +#define SK_IMAGEFILTER_UNFLATTEN_COMMON(localVar, expectedCount) \ + Common localVar; \ + do { \ + if (!localVar.unflatten(buffer, expectedCount)) { \ + return NULL; \ + } \ + } while (0) + #endif diff --git a/gfx/skia/skia/include/core/SkImageGenerator.h b/gfx/skia/skia/include/core/SkImageGenerator.h index 17477e37b397..66db5e488427 100644 --- a/gfx/skia/skia/include/core/SkImageGenerator.h +++ b/gfx/skia/skia/include/core/SkImageGenerator.h @@ -8,12 +8,19 @@ #ifndef SkImageGenerator_DEFINED #define SkImageGenerator_DEFINED -#include "SkImageInfo.h" +#include "SkBitmap.h" #include "SkColor.h" +#include "SkImageInfo.h" +class GrContext; +class GrTexture; +class GrTextureParams; class SkBitmap; class SkData; class SkImageGenerator; +class SkMatrix; +class SkPaint; +class SkPicture; /** * Takes ownership of SkImageGenerator. If this method fails for @@ -24,29 +31,28 @@ class SkImageGenerator; * If generator is NULL, will safely return false. * * If this fails or when the SkDiscardablePixelRef that is - * installed into destination is destroyed, it will call - * SkDELETE() on the generator. Therefore, generator should be - * allocated with SkNEW() or SkNEW_ARGS(). + * installed into destination is destroyed, it will + * delete the generator. Therefore, generator should be + * allocated with new. * * @param destination Upon success, this bitmap will be * configured and have a pixelref installed. * * @return true iff successful. */ -SK_API bool SkInstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination); +SK_API bool SkDEPRECATED_InstallDiscardablePixelRef(SkImageGenerator*, SkBitmap* destination); /** - * Purges all unlocked discardable memory in Skia's global - * discardable memory pool. + * On success, installs a discardable pixelref into destination, based on encoded data. + * Regardless of success or failure, the caller must still balance their ownership of encoded. */ -SK_API void SkPurgeGlobalDiscardableMemoryPool(); - +SK_API bool SkDEPRECATED_InstallDiscardablePixelRef(SkData* encoded, SkBitmap* destination); /** * An interface that allows a purgeable PixelRef (such as a * SkDiscardablePixelRef) to decode and re-decode an image as needed. */ -class SK_API SkImageGenerator { +class SK_API SkImageGenerator : public SkNoncopyable { public: /** * The PixelRef which takes ownership of this SkImageGenerator @@ -54,13 +60,8 @@ public: */ virtual ~SkImageGenerator() { } -#ifdef SK_SUPPORT_LEGACY_IMAGEGENERATORAPI - virtual SkData* refEncodedData() { return this->onRefEncodedData(); } - virtual bool getInfo(SkImageInfo* info) { return this->onGetInfo(info); } - virtual bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) { - return this->onGetPixels(info, pixels, rowBytes, NULL, NULL); - } -#else + uint32_t uniqueID() const { return fUniqueID; } + /** * Return a ref to the encoded (i.e. compressed) representation, * of this data. @@ -71,15 +72,9 @@ public: SkData* refEncodedData() { return this->onRefEncodedData(); } /** - * Return some information about the image, allowing the owner of - * this object to allocate pixels. - * - * Repeated calls to this function should give the same results, - * allowing the PixelRef to be immutable. - * - * @return false if anything goes wrong. + * Return the ImageInfo associated with this generator. */ - bool getInfo(SkImageInfo* info); + const SkImageInfo& getInfo() const { return fInfo; } /** * Decode into the given pixels, a block of memory of size at @@ -97,6 +92,10 @@ public: * different output-configs, which the implementation can * decide to support or not. * + * A size that does not match getInfo() implies a request + * to scale. If the generator cannot perform this scale, + * it will return kInvalidScale. + * * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 * SkPMColor values in ctable. On success the generator must copy N colors into that storage, * (where N is the logical number of table entries) and set ctableCount to N. @@ -104,17 +103,16 @@ public: * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount * is not null, it will be set to 0. * - * @return false if anything goes wrong or if the image info is - * unsupported. + * @return true on success. */ bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[], int* ctableCount); /** - * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType. + * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and + * uses the default Options. */ bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); -#endif /** * If planes or rowBytes is NULL or if any entry in planes is NULL or if any entry in rowBytes @@ -127,15 +125,140 @@ public: * associated YUV data into those planes of memory supplied by the caller. It should validate * that the sizes match what it expected. If the sizes do not match, it should return false. */ - bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]); + bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], + SkYUVColorSpace* colorSpace); + + /** + * If the generator can natively/efficiently return its pixels as a GPU image (backed by a + * texture) this will return that image. If not, this will return NULL. + * + * Regarding the GrContext parameter: + * + * The caller may pass NULL for the context. In that case the generator may assume that its + * internal context is current. If it has no internal context, then it should just return + * null. + * + * If the caller passes a non-null context, then the generator should only succeed if: + * - it has no intrinsic context, and will use the caller's + * - its internal context is the same + * - it can somehow convert its texture into one that is valid for the provided context. + * + * Regarding the GrTextureParams parameter: + * + * If the context (the provided one or the generator's intrinsic one) determines that to + * support the specified usage, it must return a different sized texture it may, + * so the caller must inspect the texture's width/height and compare them to the generator's + * getInfo() width/height. For readback usage use GrTextureParams::ClampNoFilter() + */ + GrTexture* generateTexture(GrContext*, const SkIRect* subset = nullptr); + + struct SupportedSizes { + SkISize fSizes[2]; + }; + + /** + * Some generators can efficiently scale their contents. If this is supported, the generator + * may only support certain scaled dimensions. Call this with the desired scale factor, + * and it will return true if scaling is supported, and in supportedSizes[] it will return + * the nearest supported dimensions. + * + * If no native scaling is supported, or scale is invalid (e.g. scale <= 0 || scale > 1) + * this will return false, and the supportedsizes will be undefined. + */ + bool computeScaledDimensions(SkScalar scale, SupportedSizes*); + + /** + * Scale the generator's pixels to fit into scaledSize. + * This routine also support retrieving only a subset of the pixels. That subset is specified + * by the following rectangle (in the scaled space): + * + * subset = SkIRect::MakeXYWH(subsetOrigin.x(), subsetOrigin.y(), + * subsetPixels.width(), subsetPixels.height()) + * + * If subset is not contained inside the scaledSize, this returns false. + * + * whole = SkIRect::MakeWH(scaledSize.width(), scaledSize.height()) + * if (!whole.contains(subset)) { + * return false; + * } + * + * If the requested colortype/alphatype in pixels is not supported, + * or the requested scaledSize is not supported, or the generator encounters an error, + * this returns false. + */ + bool generateScaledPixels(const SkISize& scaledSize, const SkIPoint& subsetOrigin, + const SkPixmap& subsetPixels); + + bool generateScaledPixels(const SkPixmap& scaledPixels) { + return this->generateScaledPixels(SkISize::Make(scaledPixels.width(), + scaledPixels.height()), + SkIPoint::Make(0, 0), scaledPixels); + } + + /** + * If the default image decoder system can interpret the specified (encoded) data, then + * this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way + * the caller is still responsible for managing their ownership of the data. + */ + static SkImageGenerator* NewFromEncoded(SkData*); + + /** Return a new image generator backed by the specified picture. If the size is empty or + * the picture is NULL, this returns NULL. + * The optional matrix and paint arguments are passed to drawPicture() at rasterization + * time. + */ + static SkImageGenerator* NewFromPicture(const SkISize&, const SkPicture*, const SkMatrix*, + const SkPaint*); + + bool tryGenerateBitmap(SkBitmap* bm) { + return this->tryGenerateBitmap(bm, nullptr, nullptr); + } + bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo& info, SkBitmap::Allocator* allocator) { + return this->tryGenerateBitmap(bm, &info, allocator); + } + void generateBitmap(SkBitmap* bm) { + if (!this->tryGenerateBitmap(bm, nullptr, nullptr)) { + sk_throw(); + } + } + void generateBitmap(SkBitmap* bm, const SkImageInfo& info) { + if (!this->tryGenerateBitmap(bm, &info, nullptr)) { + sk_throw(); + } + } protected: + SkImageGenerator(const SkImageInfo& info); + virtual SkData* onRefEncodedData(); - virtual bool onGetInfo(SkImageInfo* info); - virtual bool onGetPixels(const SkImageInfo& info, - void* pixels, size_t rowBytes, + + virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[], int* ctableCount); virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]); + virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], + SkYUVColorSpace* colorSpace); + + virtual GrTexture* onGenerateTexture(GrContext*, const SkIRect*) { + return nullptr; + } + + virtual bool onComputeScaledDimensions(SkScalar, SupportedSizes*) { + return false; + } + virtual bool onGenerateScaledPixels(const SkISize&, const SkIPoint&, const SkPixmap&) { + return false; + } + + bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo* optionalInfo, SkBitmap::Allocator*); + +private: + const SkImageInfo fInfo; + const uint32_t fUniqueID; + + // This is our default impl, which may be different on different platforms. + // It is called from NewFromEncoded() after it has checked for any runtime factory. + // The SkData will never be NULL, as that will have been checked by NewFromEncoded. + static SkImageGenerator* NewFromEncodedImpl(SkData*); }; #endif // SkImageGenerator_DEFINED diff --git a/gfx/skia/skia/include/core/SkImageInfo.h b/gfx/skia/skia/include/core/SkImageInfo.h index 3d82dc805c79..4b82ae6e2fb3 100644 --- a/gfx/skia/skia/include/core/SkImageInfo.h +++ b/gfx/skia/skia/include/core/SkImageInfo.h @@ -9,21 +9,17 @@ #define SkImageInfo_DEFINED #include "SkMath.h" +#include "SkRect.h" #include "SkSize.h" -class SkWriteBuffer; class SkReadBuffer; +class SkWriteBuffer; /** - * Describes how to interpret the alpha compoent of a pixel. + * Describes how to interpret the alpha component of a pixel. */ enum SkAlphaType { - /** - * All pixels should be treated as opaque, regardless of the value stored - * in their alpha field. Used for legacy images that wrote 0 or garbarge - * in their alpha field, but intended the RGB to be treated as opaque. - */ - kIgnore_SkAlphaType, + kUnknown_SkAlphaType, /** * All pixels are stored as opaque. This differs slightly from kIgnore in @@ -52,11 +48,7 @@ enum SkAlphaType { }; static inline bool SkAlphaTypeIsOpaque(SkAlphaType at) { - SK_COMPILE_ASSERT(kIgnore_SkAlphaType < kOpaque_SkAlphaType, bad_alphatype_order); - SK_COMPILE_ASSERT(kPremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order); - SK_COMPILE_ASSERT(kUnpremul_SkAlphaType > kOpaque_SkAlphaType, bad_alphatype_order); - - return (unsigned)at <= kOpaque_SkAlphaType; + return kOpaque_SkAlphaType == at; } static inline bool SkAlphaTypeIsValid(unsigned value) { @@ -80,19 +72,16 @@ enum SkColorType { kRGBA_8888_SkColorType, kBGRA_8888_SkColorType, kIndex_8_SkColorType, + kGray_8_SkColorType, - kLastEnum_SkColorType = kIndex_8_SkColorType, + kLastEnum_SkColorType = kGray_8_SkColorType, #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) kN32_SkColorType = kBGRA_8888_SkColorType, #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) kN32_SkColorType = kRGBA_8888_SkColorType, #else -#error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order" -#endif - -#ifdef SK_SUPPORT_LEGACY_N32_NAME - kPMColor_SkColorType = kN32_SkColorType + #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order" #endif }; @@ -105,9 +94,10 @@ static int SkColorTypeBytesPerPixel(SkColorType ct) { 4, // RGBA_8888 4, // BGRA_8888 1, // kIndex_8 + 1, // kGray_8 }; - SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1), - size_mismatch_with_SkColorType_enum); + static_assert(SK_ARRAY_COUNT(gSize) == (size_t)(kLastEnum_SkColorType + 1), + "size_mismatch_with_SkColorType_enum"); SkASSERT((size_t)ct < SK_ARRAY_COUNT(gSize)); return gSize[ct]; @@ -121,6 +111,17 @@ static inline bool SkColorTypeIsValid(unsigned value) { return value <= kLastEnum_SkColorType; } +static inline size_t SkColorTypeComputeOffset(SkColorType ct, int x, int y, size_t rowBytes) { + int shift = 0; + switch (SkColorTypeBytesPerPixel(ct)) { + case 4: shift = 2; break; + case 2: shift = 1; break; + case 1: shift = 0; break; + default: return 0; + } + return y * rowBytes + (x << shift); +} + /////////////////////////////////////////////////////////////////////////////// /** @@ -133,73 +134,92 @@ bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType, /////////////////////////////////////////////////////////////////////////////// /** - * Describe an image's dimensions and pixel type. + * Describes the color space a YUV pixel. */ -struct SkImageInfo { - int fWidth; - int fHeight; - SkColorType fColorType; - SkAlphaType fAlphaType; +enum SkYUVColorSpace { + /** Standard JPEG color space. */ + kJPEG_SkYUVColorSpace, + /** SDTV standard Rec. 601 color space. Uses "studio swing" [16, 235] color + range. See http://en.wikipedia.org/wiki/Rec._601 for details. */ + kRec601_SkYUVColorSpace, + /** HDTV standard Rec. 709 color space. Uses "studio swing" [16, 235] color + range. See http://en.wikipedia.org/wiki/Rec._709 for details. */ + kRec709_SkYUVColorSpace, - static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at) { - SkImageInfo info = { - width, height, ct, at - }; - return info; + kLastEnum_SkYUVColorSpace = kRec709_SkYUVColorSpace +}; + +/////////////////////////////////////////////////////////////////////////////// + +enum SkColorProfileType { + kLinear_SkColorProfileType, + kSRGB_SkColorProfileType, + + kLastEnum_SkColorProfileType = kSRGB_SkColorProfileType +}; + +/** + * Describe an image's dimensions and pixel type. + * Used for both src images and render-targets (surfaces). + */ +struct SK_API SkImageInfo { +public: + SkImageInfo() + : fWidth(0) + , fHeight(0) + , fColorType(kUnknown_SkColorType) + , fAlphaType(kUnknown_SkAlphaType) + , fProfileType(kLinear_SkColorProfileType) + {} + + static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at, + SkColorProfileType pt = kLinear_SkColorProfileType) { + return SkImageInfo(width, height, ct, at, pt); } /** * Sets colortype to the native ARGB32 type. */ - static SkImageInfo MakeN32(int width, int height, SkAlphaType at) { - SkImageInfo info = { - width, height, kN32_SkColorType, at - }; - return info; + static SkImageInfo MakeN32(int width, int height, SkAlphaType at, + SkColorProfileType pt = kLinear_SkColorProfileType) { + return SkImageInfo(width, height, kN32_SkColorType, at, pt); } /** * Sets colortype to the native ARGB32 type, and the alphatype to premul. */ - static SkImageInfo MakeN32Premul(int width, int height) { - SkImageInfo info = { - width, height, kN32_SkColorType, kPremul_SkAlphaType - }; - return info; + static SkImageInfo MakeN32Premul(int width, int height, + SkColorProfileType pt = kLinear_SkColorProfileType) { + return SkImageInfo(width, height, kN32_SkColorType, kPremul_SkAlphaType, pt); } /** * Sets colortype to the native ARGB32 type, and the alphatype to premul. */ - static SkImageInfo MakeN32Premul(const SkISize& size) { - return MakeN32Premul(size.width(), size.height()); + static SkImageInfo MakeN32Premul(const SkISize& size, + SkColorProfileType pt = kLinear_SkColorProfileType) { + return MakeN32Premul(size.width(), size.height(), pt); } static SkImageInfo MakeA8(int width, int height) { - SkImageInfo info = { - width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType - }; - return info; + return SkImageInfo(width, height, kAlpha_8_SkColorType, kPremul_SkAlphaType, + kLinear_SkColorProfileType); } static SkImageInfo MakeUnknown(int width, int height) { - SkImageInfo info = { - width, height, kUnknown_SkColorType, kIgnore_SkAlphaType - }; - return info; + return SkImageInfo(width, height, kUnknown_SkColorType, kUnknown_SkAlphaType, + kLinear_SkColorProfileType); } static SkImageInfo MakeUnknown() { - SkImageInfo info = { - 0, 0, kUnknown_SkColorType, kIgnore_SkAlphaType - }; - return info; + return SkImageInfo(); } int width() const { return fWidth; } int height() const { return fHeight; } SkColorType colorType() const { return fColorType; } SkAlphaType alphaType() const { return fAlphaType; } + SkColorProfileType profileType() const { return fProfileType; } bool isEmpty() const { return fWidth <= 0 || fHeight <= 0; } @@ -207,14 +227,26 @@ struct SkImageInfo { return SkAlphaTypeIsOpaque(fAlphaType); } + bool isLinear() const { return kLinear_SkColorProfileType == fProfileType; } + bool isSRGB() const { return kSRGB_SkColorProfileType == fProfileType; } + SkISize dimensions() const { return SkISize::Make(fWidth, fHeight); } + SkIRect bounds() const { return SkIRect::MakeWH(fWidth, fHeight); } /** * Return a new ImageInfo with the same colortype and alphatype as this info, * but with the specified width and height. */ SkImageInfo makeWH(int newWidth, int newHeight) const { - return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType); + return SkImageInfo::Make(newWidth, newHeight, fColorType, fAlphaType, fProfileType); + } + + SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const { + return SkImageInfo::Make(fWidth, fHeight, fColorType, newAlphaType, fProfileType); + } + + SkImageInfo makeColorType(SkColorType newColorType) const { + return SkImageInfo::Make(fWidth, fHeight, newColorType, fAlphaType, fProfileType); } int bytesPerPixel() const { @@ -229,6 +261,12 @@ struct SkImageInfo { return (size_t)this->minRowBytes64(); } + size_t computeOffset(int x, int y, size_t rowBytes) const { + SkASSERT((unsigned)x < (unsigned)fWidth); + SkASSERT((unsigned)y < (unsigned)fHeight); + return SkColorTypeComputeOffset(fColorType, x, y, rowBytes); + } + bool operator==(const SkImageInfo& other) const { return 0 == memcmp(this, &other, sizeof(other)); } @@ -247,7 +285,11 @@ struct SkImageInfo { } size_t getSafeSize(size_t rowBytes) const { - return (size_t)this->getSafeSize64(rowBytes); + int64_t size = this->getSafeSize64(rowBytes); + if (!sk_64_isS32(size)) { + return 0; + } + return sk_64_asS32(size); } bool validRowBytes(size_t rowBytes) const { @@ -256,6 +298,21 @@ struct SkImageInfo { } SkDEBUGCODE(void validate() const;) + +private: + int fWidth; + int fHeight; + SkColorType fColorType; + SkAlphaType fAlphaType; + SkColorProfileType fProfileType; + + SkImageInfo(int width, int height, SkColorType ct, SkAlphaType at, SkColorProfileType pt) + : fWidth(width) + , fHeight(height) + , fColorType(ct) + , fAlphaType(at) + , fProfileType(pt) + {} }; #endif diff --git a/gfx/skia/skia/include/core/SkInstCnt.h b/gfx/skia/skia/include/core/SkInstCnt.h deleted file mode 100644 index e4b43d130b94..000000000000 --- a/gfx/skia/skia/include/core/SkInstCnt.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkInstCnt_DEFINED -#define SkInstCnt_DEFINED - -/* - * The instance counting system consists of three macros that create the - * instance counting machinery. A class is added to the system by adding: - * SK_DECLARE_INST_COUNT at the top of its declaration for derived classes - * SK_DECLARE_INST_COUNT_ROOT at the top of its declaration for a root class - * At the end of an application a call to all the "root" objects' - * CheckInstanceCount methods should be made - */ -#include "SkTypes.h" - -#if SK_ENABLE_INST_COUNT -// Static variables inside member functions below may be defined multiple times -// if Skia is being used as a dynamic library. Instance counting should be on -// only for static builds. See bug skia:2058. -#if defined(SKIA_DLL) -#error Instance counting works only when Skia is built as a static library. -#endif - -#include "SkOnce.h" -#include "SkTArray.h" -#include "SkThread.h" -extern bool gPrintInstCount; - -// The non-root classes just register themselves with their parent -#define SK_DECLARE_INST_COUNT(className) \ - SK_DECLARE_INST_COUNT_INTERNAL(className, \ - INHERITED::AddInstChild(CheckInstanceCount);) - -// The root classes registers a function to print out the memory stats when -// the app ends -#define SK_DECLARE_INST_COUNT_ROOT(className) \ - SK_DECLARE_INST_COUNT_INTERNAL(className, atexit(exitPrint);) - -#define SK_DECLARE_INST_COUNT_INTERNAL(className, initStep) \ - class SkInstanceCountHelper { \ - public: \ - SkInstanceCountHelper() { \ - SK_DECLARE_STATIC_ONCE(once); \ - SkOnce(&once, init); \ - sk_atomic_inc(GetInstanceCountPtr()); \ - } \ - \ - static void init() { \ - initStep \ - } \ - \ - SkInstanceCountHelper(const SkInstanceCountHelper&) { \ - sk_atomic_inc(GetInstanceCountPtr()); \ - } \ - \ - ~SkInstanceCountHelper() { \ - sk_atomic_dec(GetInstanceCountPtr()); \ - } \ - \ - static int32_t* GetInstanceCountPtr() { \ - static int32_t gInstanceCount; \ - return &gInstanceCount; \ - } \ - \ - static SkTArray*& GetChildren() { \ - static SkTArray* gChildren; \ - return gChildren; \ - } \ - \ - static void create_mutex(SkMutex** mutex) { \ - *mutex = SkNEW(SkMutex); \ - } \ - static SkBaseMutex& GetChildrenMutex() { \ - static SkMutex* childrenMutex; \ - SK_DECLARE_STATIC_ONCE(once); \ - SkOnce(&once, className::SkInstanceCountHelper::create_mutex, &childrenMutex);\ - return *childrenMutex; \ - } \ - \ - } fInstanceCountHelper; \ - \ - static int32_t GetInstanceCount() { \ - return *SkInstanceCountHelper::GetInstanceCountPtr(); \ - } \ - \ - static void exitPrint() { \ - CheckInstanceCount(0, true); \ - } \ - \ - static int CheckInstanceCount(int level = 0, bool cleanUp = false) { \ - if (gPrintInstCount && 0 != GetInstanceCount()) { \ - SkDebugf("%*c Leaked %s: %d\n", \ - 4*level, ' ', #className, \ - GetInstanceCount()); \ - } \ - if (NULL == SkInstanceCountHelper::GetChildren()) { \ - return GetInstanceCount(); \ - } \ - SkTArray* children = \ - SkInstanceCountHelper::GetChildren(); \ - int childCount = children->count(); \ - int count = GetInstanceCount(); \ - for (int i = 0; i < childCount; ++i) { \ - count -= (*(*children)[i])(level+1, cleanUp); \ - } \ - SkASSERT(count >= 0); \ - if (gPrintInstCount && childCount > 0 && count > 0) { \ - SkDebugf("%*c Leaked ???: %d\n", 4*(level + 1), ' ', count); \ - } \ - if (cleanUp) { \ - delete children; \ - SkInstanceCountHelper::GetChildren() = NULL; \ - } \ - return GetInstanceCount(); \ - } \ - \ - static void AddInstChild(int (*childCheckInstCnt)(int, bool)) { \ - if (CheckInstanceCount != childCheckInstCnt) { \ - SkAutoMutexAcquire ama(SkInstanceCountHelper::GetChildrenMutex()); \ - if (NULL == SkInstanceCountHelper::GetChildren()) { \ - SkInstanceCountHelper::GetChildren() = \ - new SkTArray; \ - } \ - SkInstanceCountHelper::GetChildren()->push_back(childCheckInstCnt); \ - } \ - } - -#else -// Typically SK_ENABLE_INST_COUNT=0. Make sure the class declares public typedef INHERITED by -// causing a compile-time error if the typedef is missing. This way SK_ENABLE_INST_COUNT=1 stays -// compiling. -#define SK_DECLARE_INST_COUNT(className) static void AddInstChild() { INHERITED::AddInstChild(); } -#define SK_DECLARE_INST_COUNT_ROOT(className) static void AddInstChild() { } -#endif - -// Following are deprecated. They are defined only for backwards API compatibility. -#define SK_DECLARE_INST_COUNT_TEMPLATE(className) SK_DECLARE_INST_COUNT(className) -#define SK_DEFINE_INST_COUNT(className) -#define SK_DEFINE_INST_COUNT_TEMPLATE(templateInfo, className) - -#endif // SkInstCnt_DEFINED diff --git a/gfx/skia/skia/include/core/SkMallocPixelRef.h b/gfx/skia/skia/include/core/SkMallocPixelRef.h index 63ed19ae3cea..ab337b9241ec 100644 --- a/gfx/skia/skia/include/core/SkMallocPixelRef.h +++ b/gfx/skia/skia/include/core/SkMallocPixelRef.h @@ -16,7 +16,6 @@ */ class SK_API SkMallocPixelRef : public SkPixelRef { public: - SK_DECLARE_INST_COUNT(SkMallocPixelRef) /** * Return a new SkMallocPixelRef with the provided pixel storage, rowBytes, * and optional colortable. The caller is responsible for managing the @@ -43,6 +42,12 @@ public: static SkMallocPixelRef* NewAllocate(const SkImageInfo& info, size_t rowBytes, SkColorTable*); + /** + * Identical to NewAllocate, except all pixel bytes are zeroed. + */ + static SkMallocPixelRef* NewZeroed(const SkImageInfo& info, + size_t rowBytes, SkColorTable*); + /** * Return a new SkMallocPixelRef with the provided pixel storage, * rowBytes, and optional colortable. On destruction, ReleaseProc @@ -50,6 +55,11 @@ public: * * This pixelref will ref() the specified colortable (if not NULL). * + * If ReleaseProc is NULL, the pixels will never be released. This + * can be useful if the pixels were stack allocated. However, such an + * SkMallocPixelRef must not live beyond its pixels (e.g. by copying + * an SkBitmap pointing to it, or drawing to an SkPicture). + * * Returns NULL on failure. */ typedef void (*ReleaseProc)(void* addr, void* context); @@ -77,9 +87,12 @@ public: class PRFactory : public SkPixelRefFactory { public: - virtual SkPixelRef* create(const SkImageInfo&, - size_t rowBytes, - SkColorTable*) SK_OVERRIDE; + SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) override; + }; + + class ZeroedPRFactory : public SkPixelRefFactory { + public: + SkPixelRef* create(const SkImageInfo&, size_t rowBytes, SkColorTable*) override; }; protected: @@ -88,11 +101,17 @@ protected: bool ownPixels); virtual ~SkMallocPixelRef(); - virtual bool onNewLockPixels(LockRec*) SK_OVERRIDE; - virtual void onUnlockPixels() SK_OVERRIDE; - virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE; + bool onNewLockPixels(LockRec*) override; + void onUnlockPixels() override; + size_t getAllocatedSizeInBytes() const override; private: + // Uses alloc to implement NewAllocate or NewZeroed. + static SkMallocPixelRef* NewUsing(void*(*alloc)(size_t), + const SkImageInfo&, + size_t rowBytes, + SkColorTable*); + void* fStorage; SkColorTable* fCTable; size_t fRB; diff --git a/gfx/skia/skia/include/core/SkMask.h b/gfx/skia/skia/include/core/SkMask.h index 5cfef970c502..7be6aff614ce 100644 --- a/gfx/skia/skia/include/core/SkMask.h +++ b/gfx/skia/skia/include/core/SkMask.h @@ -23,11 +23,10 @@ struct SkMask { k3D_Format, //!< 3 8bit per pixl planes: alpha, mul, add kARGB32_Format, //!< SkPMColor kLCD16_Format, //!< 565 alpha for r/g/b - kLCD32_Format //!< 888 alpha for r/g/b }; enum { - kCountMaskFormats = kLCD32_Format + 1 + kCountMaskFormats = kLCD16_Format + 1 }; uint8_t* fImage; @@ -86,26 +85,13 @@ struct SkMask { return row + (x - fBounds.fLeft); } - /** - * Return the address of the specified 32bit mask. In the debug build, - * this asserts that the mask's format is kLCD32_Format, and that (x,y) - * are contained in the mask's fBounds. - */ - uint32_t* getAddrLCD32(int x, int y) const { - SkASSERT(kLCD32_Format == fFormat); - SkASSERT(fBounds.contains(x, y)); - SkASSERT(fImage != NULL); - uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); - return row + (x - fBounds.fLeft); - } - /** * Return the address of the specified 32bit mask. In the debug build, * this asserts that the mask's format is 32bits, and that (x,y) * are contained in the mask's fBounds. */ uint32_t* getAddr32(int x, int y) const { - SkASSERT(kLCD32_Format == fFormat || kARGB32_Format == fFormat); + SkASSERT(kARGB32_Format == fFormat); SkASSERT(fBounds.contains(x, y)); SkASSERT(fImage != NULL); uint32_t* row = (uint32_t*)(fImage + (y - fBounds.fTop) * fRowBytes); @@ -116,7 +102,7 @@ struct SkMask { * Returns the address of the specified pixel, computing the pixel-size * at runtime based on the mask format. This will be slightly slower than * using one of the routines where the format is implied by the name - * e.g. getAddr8 or getAddrLCD32. + * e.g. getAddr8 or getAddr32. * * x,y must be contained by the mask's bounds (this is asserted in the * debug build, but not checked in the release build.) diff --git a/gfx/skia/skia/include/core/SkMaskFilter.h b/gfx/skia/skia/include/core/SkMaskFilter.h index 39925129a76d..1fe1d9adafc2 100644 --- a/gfx/skia/skia/include/core/SkMaskFilter.h +++ b/gfx/skia/skia/include/core/SkMaskFilter.h @@ -15,10 +15,14 @@ #include "SkMask.h" #include "SkPaint.h" -class GrContext; +class GrClip; +class GrDrawContext; class GrPaint; +class GrRenderTarget; +class GrTextureProvider; class SkBitmap; class SkBlitter; +class SkCachedData; class SkMatrix; class SkPath; class SkRasterClip; @@ -38,8 +42,6 @@ class SkStrokeRec; */ class SK_API SkMaskFilter : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkMaskFilter) - /** Returns the format of the resulting mask that this subclass will return when its filterMask() method is called. */ @@ -63,32 +65,44 @@ public: #if SK_SUPPORT_GPU /** - * Returns true if the filter can be expressed a single-pass GrEffect without requiring an + * Returns true if the filter can be expressed a single-pass GrProcessor without requiring an * explicit input mask. Per-pixel, the effect receives the incoming mask's coverage as * the input color and outputs the filtered covereage value. This means that each pixel's * filtered coverage must only depend on the unfiltered mask value for that pixel and not on * surrounding values. * - * If effect is non-NULL, a new GrEffect instance is stored in it. The caller assumes ownership - * of the effect and must unref it. + * If effect is non-NULL, a new GrProcessor instance is stored in it. The caller assumes + * ownership of the effect and must unref it. */ - virtual bool asNewEffect(GrEffect** effect, - GrTexture*, - const SkMatrix& ctm) const; + virtual bool asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix& ctm) const; /** - * If asNewEffect() fails the filter may be implemented on the GPU by a subclass overriding - * filterMaskGPU (declared below). That code path requires constructing a src mask as input. - * Since that is a potentially expensive operation, the subclass must also override this - * function to indicate whether filterTextureMaskGPU would succeeed if the mask were to be - * created. + * If asFragmentProcessor() fails the filter may be implemented on the GPU by a subclass + * overriding filterMaskGPU (declared below). That code path requires constructing a + * src mask as input. Since that is a potentially expensive operation, the subclass must also + * override this function to indicate whether filterTextureMaskGPU would succeeed if the mask + * were to be created. * * 'maskRect' returns the device space portion of the mask that the filter needs. The mask - * passed into 'filterMaskGPU' should have the same extent as 'maskRect' but be translated - * to the upper-left corner of the mask (i.e., (maskRect.fLeft, maskRect.fTop) appears at - * (0, 0) in the mask). + * passed into 'filterMaskGPU' should have the same extent as 'maskRect' but be + * translated to the upper-left corner of the mask (i.e., (maskRect.fLeft, maskRect.fTop) + * appears at (0, 0) in the mask). + * + * Logically, how this works is: + * canFilterMaskGPU is called + * if (it returns true) + * the returned mask rect is used for quick rejecting + * either directFilterMaskGPU or directFilterRRectMaskGPU is then called + * if (neither of them handle the blur) + * the mask rect is used to generate the mask + * filterMaskGPU is called to filter the mask + * + * TODO: this should work as: + * if (canFilterMaskGPU(devShape, ...)) // rect, rrect, drrect, path + * filterMaskGPU(devShape, ...) + * this would hide the RRect special case and the mask generation */ - virtual bool canFilterMaskGPU(const SkRect& devBounds, + virtual bool canFilterMaskGPU(const SkRRect& devRRect, const SkIRect& clipBounds, const SkMatrix& ctm, SkRect* maskRect) const; @@ -97,16 +111,22 @@ public: * Try to directly render the mask filter into the target. Returns * true if drawing was successful. */ - virtual bool directFilterMaskGPU(GrContext* context, + virtual bool directFilterMaskGPU(GrTextureProvider* texProvider, + GrDrawContext* drawContext, GrPaint* grp, + const GrClip&, + const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkPath& path) const; /** * Try to directly render a rounded rect mask filter into the target. Returns * true if drawing was successful. */ - virtual bool directFilterRRectMaskGPU(GrContext* context, + virtual bool directFilterRRectMaskGPU(GrTextureProvider* texProvider, + GrDrawContext* drawContext, GrPaint* grp, + const GrClip&, + const SkMatrix& viewMatrix, const SkStrokeRec& strokeRec, const SkRRect& rrect) const; @@ -155,8 +175,6 @@ public: protected: SkMaskFilter() {} - // empty for now, but lets get our subclass to remember to init us for the future - SkMaskFilter(SkReadBuffer& buffer) : INHERITED(buffer) {} enum FilterReturn { kFalse_FilterReturn, @@ -164,10 +182,17 @@ protected: kUnimplemented_FilterReturn }; - struct NinePatch { + class NinePatch : ::SkNoncopyable { + public: + NinePatch() : fCache(NULL) { + fMask.fImage = NULL; + } + ~NinePatch(); + SkMask fMask; // fBounds must have [0,0] in its top-left SkIRect fOuterRect; // width/height must be >= fMask.fBounds' SkIPoint fCenter; // identifies center row/col for stretching + SkCachedData* fCache; }; /** diff --git a/gfx/skia/skia/include/core/SkMath.h b/gfx/skia/skia/include/core/SkMath.h index 014f014debb7..e5069592d003 100644 --- a/gfx/skia/skia/include/core/SkMath.h +++ b/gfx/skia/skia/include/core/SkMath.h @@ -79,6 +79,9 @@ int SkCLZ_portable(uint32_t); if (mask) { DWORD index; _BitScanReverse(&index, mask); + // Suppress this bogus /analyze warning. The check for non-zero + // guarantees that _BitScanReverse will succeed. +#pragma warning(suppress : 6102) // Using 'index' from failed function call return index ^ 0x1F; } else { return 32; @@ -147,40 +150,12 @@ static inline int SkNextLog2(uint32_t value) { * Returns true if value is a power of 2. Does not explicitly check for * value <= 0. */ -static inline bool SkIsPow2(int value) { +template inline bool SkIsPow2(T value) { return (value & (value - 1)) == 0; } /////////////////////////////////////////////////////////////////////////////// -/** - * SkMulS16(a, b) multiplies a * b, but requires that a and b are both int16_t. - * With this requirement, we can generate faster instructions on some - * architectures. - */ -#ifdef SK_ARM_HAS_EDSP - static inline int32_t SkMulS16(S16CPU x, S16CPU y) { - SkASSERT((int16_t)x == x); - SkASSERT((int16_t)y == y); - int32_t product; - asm("smulbb %0, %1, %2 \n" - : "=r"(product) - : "r"(x), "r"(y) - ); - return product; - } -#else - #ifdef SK_DEBUG - static inline int32_t SkMulS16(S16CPU x, S16CPU y) { - SkASSERT((int16_t)x == x); - SkASSERT((int16_t)y == y); - return x * y; - } - #else - #define SkMulS16(x, y) ((x) * (y)) - #endif -#endif - /** * Return a*b/((1 << shift) - 1), rounding any fractional bits. * Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8 @@ -189,7 +164,7 @@ static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) { SkASSERT(a <= 32767); SkASSERT(b <= 32767); SkASSERT(shift > 0 && shift <= 8); - unsigned prod = SkMulS16(a, b) + (1 << (shift - 1)); + unsigned prod = a*b + (1 << (shift - 1)); return (prod + (prod >> shift)) >> shift; } @@ -200,7 +175,7 @@ static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) { static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) { SkASSERT(a <= 32767); SkASSERT(b <= 32767); - unsigned prod = SkMulS16(a, b) + 128; + unsigned prod = a*b + 128; return (prod + (prod >> 8)) >> 8; } diff --git a/gfx/skia/skia/include/core/SkMatrix.h b/gfx/skia/skia/include/core/SkMatrix.h index bfa03de7c5dd..97a53505ef37 100644 --- a/gfx/skia/skia/include/core/SkMatrix.h +++ b/gfx/skia/skia/include/core/SkMatrix.h @@ -10,16 +10,11 @@ #ifndef SkMatrix_DEFINED #define SkMatrix_DEFINED -#include "SkDynamicAnnotations.h" #include "SkRect.h" +struct SkRSXform; class SkString; -// TODO: can we remove these 3 (need to check chrome/android) -typedef SkScalar SkPersp; -#define SkScalarToPersp(x) (x) -#define SkPerspToScalar(x) (x) - /** \class SkMatrix The SkMatrix class holds a 3x3 matrix for transforming coordinates. @@ -27,8 +22,27 @@ typedef SkScalar SkPersp; using either reset() - to construct an identity matrix, or one of the set functions (e.g. setTranslate, setRotate, etc.). */ +SK_BEGIN_REQUIRE_DENSE class SK_API SkMatrix { public: + static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar sx, SkScalar sy) { + SkMatrix m; + m.setScale(sx, sy); + return m; + } + + static SkMatrix SK_WARN_UNUSED_RESULT MakeScale(SkScalar scale) { + SkMatrix m; + m.setScale(scale, scale); + return m; + } + + static SkMatrix SK_WARN_UNUSED_RESULT MakeTrans(SkScalar dx, SkScalar dy) { + SkMatrix m; + m.setTranslate(dx, dy); + return m; + } + /** Enum of bit fields for the mask return by getType(). Use this to identify the complexity of the matrix. */ @@ -60,6 +74,10 @@ public: return this->getType() == 0; } + bool isScaleTranslate() const { + return !(this->getType() & ~(kScale_Mask | kTranslate_Mask)); + } + /** Returns true if will map a rectangle to another rectangle. This can be true if the matrix is identity, scale-only, or rotates a multiple of 90 degrees. @@ -81,12 +99,12 @@ public: kPerspective_Mask); } - /** Returns true if the matrix contains only translation, rotation or uniform scale + /** Returns true if the matrix contains only translation, rotation/reflection or uniform scale Returns false if other transformation types are included or is degenerate */ bool isSimilarity(SkScalar tol = SK_ScalarNearlyZero) const; - /** Returns true if the matrix contains only translation, rotation or scale + /** Returns true if the matrix contains only translation, rotation/reflection or scale (non-uniform scale is allowed). Returns false if other transformation types are included or is degenerate */ @@ -132,8 +150,8 @@ public: SkScalar getSkewX() const { return fMat[kMSkewX]; } SkScalar getTranslateX() const { return fMat[kMTransX]; } SkScalar getTranslateY() const { return fMat[kMTransY]; } - SkPersp getPerspX() const { return fMat[kMPersp0]; } - SkPersp getPerspY() const { return fMat[kMPersp1]; } + SkScalar getPerspX() const { return fMat[kMPersp0]; } + SkScalar getPerspY() const { return fMat[kMPersp1]; } SkScalar& operator[](int index) { SkASSERT((unsigned)index < 9); @@ -153,12 +171,12 @@ public: void setSkewX(SkScalar v) { this->set(kMSkewX, v); } void setTranslateX(SkScalar v) { this->set(kMTransX, v); } void setTranslateY(SkScalar v) { this->set(kMTransY, v); } - void setPerspX(SkPersp v) { this->set(kMPersp0, v); } - void setPerspY(SkPersp v) { this->set(kMPersp1, v); } + void setPerspX(SkScalar v) { this->set(kMPersp0, v); } + void setPerspY(SkScalar v) { this->set(kMPersp1, v); } - void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, - SkScalar skewY, SkScalar scaleY, SkScalar transY, - SkPersp persp0, SkPersp persp1, SkPersp persp2) { + void setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, + SkScalar skewY, SkScalar scaleY, SkScalar transY, + SkScalar persp0, SkScalar persp1, SkScalar persp2) { fMat[kMScaleX] = scaleX; fMat[kMSkewX] = skewX; fMat[kMTransX] = transX; @@ -171,6 +189,23 @@ public: this->setTypeMask(kUnknown_Mask); } + /** + * Copy the 9 scalars for this matrix into buffer, in the same order as the kMScaleX + * enum... scalex, skewx, transx, skewy, scaley, transy, persp0, persp1, persp2 + */ + void get9(SkScalar buffer[9]) const { + memcpy(buffer, fMat, 9 * sizeof(SkScalar)); + } + + /** + * Set this matrix to the 9 scalars from the buffer, in the same order as the kMScaleX + * enum... scalex, skewx, transx, skewy, scaley, transy, persp0, persp1, persp2 + * + * Note: calling set9 followed by get9 may not return the exact same values. Since the matrix + * is used to map non-homogeneous coordinates, it is free to rescale the 9 values as needed. + */ + void set9(const SkScalar buffer[9]); + /** Set the matrix to identity */ void reset(); @@ -211,6 +246,9 @@ public: /** Set the matrix to rotate by the specified sine and cosine values. */ void setSinCos(SkScalar sinValue, SkScalar cosValue); + + SkMatrix& setRSXform(const SkRSXform&); + /** Set the matrix to skew by sx and sy, with a pivot point at (px, py). The pivot point is the coordinate that should remain unchanged by the specified transformation. @@ -332,6 +370,11 @@ public: @return true if the matrix can be represented by the rectangle mapping. */ bool setRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf); + static SkMatrix MakeRectToRect(const SkRect& src, const SkRect& dst, ScaleToFit stf) { + SkMatrix m; + m.setRectToRect(src, dst, stf); + return m; + } /** Set the matrix such that the specified src points would map to the specified dst points. count must be within [0..4]. @@ -349,7 +392,7 @@ public: bool SK_WARN_UNUSED_RESULT invert(SkMatrix* inverse) const { // Allow the trivial case to be inlined. if (this->isIdentity()) { - if (NULL != inverse) { + if (inverse) { inverse->reset(); } return true; @@ -369,7 +412,12 @@ public: and does not change the passed array. @param affine The array to fill with affine values. Ignored if NULL. */ - bool asAffine(SkScalar affine[6]) const; + bool SK_WARN_UNUSED_RESULT asAffine(SkScalar affine[6]) const; + + /** Set the matrix to the specified affine values. + * Note: these are passed in column major order. + */ + void setAffine(const SkScalar affine[6]); /** Apply this matrix to the array of points specified by src, and write the transformed points into the array of points specified by dst. @@ -381,7 +429,12 @@ public: @param count The number of points in src to read, and then transform into dst. */ - void mapPoints(SkPoint dst[], const SkPoint src[], int count) const; + void mapPoints(SkPoint dst[], const SkPoint src[], int count) const { + SkASSERT((dst && src && count > 0) || 0 == count); + // no partial overlap + SkASSERT(src == dst || &dst[count] <= &src[0] || &src[count] <= &dst[0]); + this->getMapPtsProc()(*this, dst, src, count); + } /** Apply this matrix to the array of points, overwriting it with the transformed values. @@ -437,6 +490,12 @@ public: this->getMapXYProc()(*this, x, y, result); } + SkPoint mapXY(SkScalar x, SkScalar y) const { + SkPoint result; + this->getMapXYProc()(*this, x, y, &result); + return result; + } + /** Apply this matrix to the array of vectors specified by src, and write the transformed vectors into the array of vectors specified by dst. This is similar to mapPoints, but ignores any translation in the matrix. @@ -460,6 +519,17 @@ public: this->mapVectors(vecs, vecs, count); } + void mapVector(SkScalar dx, SkScalar dy, SkVector* result) const { + SkVector vec = { dx, dy }; + this->mapVectors(result, &vec, 1); + } + + SkVector mapVector(SkScalar dx, SkScalar dy) const { + SkVector vec = { dx, dy }; + this->mapVectors(&vec, &vec, 1); + return vec; + } + /** Apply this matrix to the src rectangle, and write the transformed rectangle into dst. This is accomplished by transforming the 4 corners of src, and then setting dst to the bounds of those points. @@ -539,8 +609,8 @@ public: return 0 == memcmp(fMat, m.fMat, sizeof(fMat)); } - friend bool operator==(const SkMatrix& a, const SkMatrix& b); - friend bool operator!=(const SkMatrix& a, const SkMatrix& b) { + friend SK_API bool operator==(const SkMatrix& a, const SkMatrix& b); + friend SK_API bool operator!=(const SkMatrix& a, const SkMatrix& b) { return !(a == b); } @@ -560,8 +630,8 @@ public: */ size_t readFromMemory(const void* buffer, size_t length); - SkDEVCODE(void dump() const;) - SK_TO_STRING_NONVIRT() + void dump() const; + void toString(SkString*) const; /** * Calculates the minimum scaling factor of the matrix as computed from the SVD of the upper @@ -586,6 +656,19 @@ public: */ bool getMinMaxScales(SkScalar scaleFactors[2]) const; + /** + * Attempt to decompose this matrix into a scale-only component and whatever remains, where + * the scale component is to be applied first. + * + * M -> Remaining * Scale + * + * On success, return true and assign the scale and remaining components (assuming their + * respective parameters are not null). On failure return false and ignore the parameters. + * + * Possible reasons to fail: perspective, one or more scale factors are zero. + */ + bool decomposeScale(SkSize* scale, SkMatrix* remaining = NULL) const; + /** * Return a reference to a const identity matrix */ @@ -644,7 +727,36 @@ private: }; SkScalar fMat[9]; - mutable SkTRacy fTypeMask; + mutable uint32_t fTypeMask; + + /** Are all elements of the matrix finite? + */ + bool isFinite() const { return SkScalarsAreFinite(fMat, 9); } + + static void ComputeInv(SkScalar dst[9], const SkScalar src[9], double invDet, bool isPersp); + + void setScaleTranslate(SkScalar sx, SkScalar sy, SkScalar tx, SkScalar ty) { + fMat[kMScaleX] = sx; + fMat[kMSkewX] = 0; + fMat[kMTransX] = tx; + + fMat[kMSkewY] = 0; + fMat[kMScaleY] = sy; + fMat[kMTransY] = ty; + + fMat[kMPersp0] = 0; + fMat[kMPersp1] = 0; + fMat[kMPersp2] = 1; + + unsigned mask = 0; + if (sx != 1 || sy != 1) { + mask |= kScale_Mask; + } + if (tx || ty) { + mask |= kTranslate_Mask; + } + this->setTypeMask(mask | kRectStaysRect_Mask); + } uint8_t computeTypeMask() const; uint8_t computePerspectiveTypeMask() const; @@ -707,14 +819,14 @@ private: static void Scale_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); static void ScaleTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int count); - static void Rot_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); - static void RotTrans_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], - int count); static void Persp_pts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); + static void Affine_vpts(const SkMatrix&, SkPoint dst[], const SkPoint[], int); + static const MapPtsProc gMapPtsProcs[]; friend class SkPerspIter; }; +SK_END_REQUIRE_DENSE #endif diff --git a/gfx/skia/skia/include/core/SkMetaData.h b/gfx/skia/skia/include/core/SkMetaData.h index 5db437c980e1..c8ca7f141993 100644 --- a/gfx/skia/skia/include/core/SkMetaData.h +++ b/gfx/skia/skia/include/core/SkMetaData.h @@ -81,7 +81,7 @@ public: bool hasData(const char name[], const void* data, size_t byteCount) const { size_t len; const void* ptr = this->findData(name, &len); - return NULL != ptr && len == byteCount && !memcmp(ptr, data, len); + return ptr && len == byteCount && !memcmp(ptr, data, len); } void setS32(const char name[], int32_t value); diff --git a/gfx/skia/skia/include/core/SkMultiPictureDraw.h b/gfx/skia/skia/include/core/SkMultiPictureDraw.h new file mode 100644 index 000000000000..8d24e615e82c --- /dev/null +++ b/gfx/skia/skia/include/core/SkMultiPictureDraw.h @@ -0,0 +1,75 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkMultiPictureDraw_DEFINED +#define SkMultiPictureDraw_DEFINED + +#include "SkMatrix.h" +#include "SkTDArray.h" + +class SkCanvas; +class SkPaint; +class SkPicture; + +/** \class SkMultiPictureDraw + + The MultiPictureDraw object accepts several picture/canvas pairs and + then attempts to optimally draw the pictures into the canvases, sharing + as many resources as possible. +*/ +class SK_API SkMultiPictureDraw { +public: + /** + * Create an object to optimize the drawing of multiple pictures. + * @param reserve Hint for the number of add calls expected to be issued + */ + SkMultiPictureDraw(int reserve = 0); + ~SkMultiPictureDraw() { this->reset(); } + + /** + * Add a canvas/picture pair for later rendering. + * @param canvas the canvas in which to draw picture + * @param picture the picture to draw into canvas + * @param matrix if non-NULL, applied to the CTM when drawing + * @param paint if non-NULL, draw picture to a temporary buffer + * and then apply the paint when the result is drawn + */ + void add(SkCanvas* canvas, + const SkPicture* picture, + const SkMatrix* matrix = NULL, + const SkPaint* paint = NULL); + + /** + * Perform all the previously added draws. This will reset the state + * of this object. If flush is true, all canvases are flushed after + * draw. + */ + void draw(bool flush = false); + + /** + * Abandon all buffered draws and reset to the initial state. + */ + void reset(); + +private: + struct DrawData { + SkCanvas* fCanvas; // reffed + const SkPicture* fPicture; // reffed + SkMatrix fMatrix; + SkPaint* fPaint; // owned + + void init(SkCanvas*, const SkPicture*, const SkMatrix*, const SkPaint*); + void draw(); + + static void Reset(SkTDArray&); + }; + + SkTDArray fThreadSafeDrawData; + SkTDArray fGPUDrawData; +}; + +#endif diff --git a/gfx/skia/skia/include/core/SkOSFile.h b/gfx/skia/skia/include/core/SkOSFile.h index 1ca11ee932ad..39a16464583b 100644 --- a/gfx/skia/skia/include/core/SkOSFile.h +++ b/gfx/skia/skia/include/core/SkOSFile.h @@ -12,16 +12,10 @@ #ifndef SkOSFile_DEFINED #define SkOSFile_DEFINED +#include + #include "SkString.h" -#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS) - #include -#endif - -#include // ptrdiff_t - -struct SkFILE; - enum SkFILE_Flags { kRead_SkFILE_Flag = 0x01, kWrite_SkFILE_Flag = 0x02 @@ -33,30 +27,30 @@ const static char SkPATH_SEPARATOR = '\\'; const static char SkPATH_SEPARATOR = '/'; #endif -SkFILE* sk_fopen(const char path[], SkFILE_Flags); -void sk_fclose(SkFILE*); +FILE* sk_fopen(const char path[], SkFILE_Flags); +void sk_fclose(FILE*); -size_t sk_fgetsize(SkFILE*); +size_t sk_fgetsize(FILE*); /** Return true if the file could seek back to the beginning */ -bool sk_frewind(SkFILE*); +bool sk_frewind(FILE*); -size_t sk_fread(void* buffer, size_t byteCount, SkFILE*); -size_t sk_fwrite(const void* buffer, size_t byteCount, SkFILE*); +size_t sk_fread(void* buffer, size_t byteCount, FILE*); +size_t sk_fwrite(const void* buffer, size_t byteCount, FILE*); -char* sk_fgets(char* str, int size, SkFILE* f); +char* sk_fgets(char* str, int size, FILE* f); -void sk_fflush(SkFILE*); +void sk_fflush(FILE*); -bool sk_fseek(SkFILE*, size_t); -bool sk_fmove(SkFILE*, long); -size_t sk_ftell(SkFILE*); +bool sk_fseek(FILE*, size_t); +bool sk_fmove(FILE*, long); +size_t sk_ftell(FILE*); /** Maps a file into memory. Returns the address and length on success, NULL otherwise. * The mapping is read only. * When finished with the mapping, free the returned pointer with sk_fmunmap. */ -void* sk_fmmap(SkFILE* f, size_t* length); +void* sk_fmmap(FILE* f, size_t* length); /** Maps a file descriptor into memory. Returns the address and length on success, NULL otherwise. * The mapping is read only. @@ -70,12 +64,12 @@ void* sk_fdmmap(int fd, size_t* length); void sk_fmunmap(const void* addr, size_t length); /** Returns true if the two point at the exact same filesystem object. */ -bool sk_fidentical(SkFILE* a, SkFILE* b); +bool sk_fidentical(FILE* a, FILE* b); /** Returns the underlying file descriptor for the given file. * The return value will be < 0 on failure. */ -int sk_fileno(SkFILE* f); +int sk_fileno(FILE* f); /** Returns true if something (file, directory, ???) exists at this path, * and has the specified access flags. @@ -86,7 +80,7 @@ bool sk_exists(const char *path, SkFILE_Flags = (SkFILE_Flags)0); bool sk_isdir(const char *path); // Have we reached the end of the file? -int sk_feof(SkFILE *); +int sk_feof(FILE *); // Create a new directory at this path; returns true if successful. @@ -109,21 +103,16 @@ public: */ bool next(SkString* name, bool getDir = false); + static const size_t kStorageSize = 40; private: -#ifdef SK_BUILD_FOR_WIN - HANDLE fHandle; - uint16_t* fPath16; -#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_IOS) - DIR* fDIR; - SkString fPath, fSuffix; -#endif + SkAlignedSStorage fSelf; }; }; /** * Functions for modifying SkStrings which represent paths on the filesystem. */ -class SkOSPath { +class SkOSPath { public: /** * Assembles rootPath and relativePath into a single path, like this: @@ -133,7 +122,7 @@ public: * * Uses SkPATH_SEPARATOR, to work on all platforms. */ - static SkString SkPathJoin(const char *rootPath, const char *relativePath); + static SkString Join(const char* rootPath, const char* relativePath); /** * Return the name of the file, ignoring the directory structure. @@ -143,6 +132,17 @@ public: * @return SkString The basename of the file - anything beyond the * final slash, or the full name if there is no slash. */ - static SkString SkBasename(const char* fullPath); + static SkString Basename(const char* fullPath); + + /** + * Given a qualified file name returns the directory. + * Behaves like python's os.path.dirname. If the fullPath is + * /dir/subdir/ the return will be /dir/subdir/ + * @param fullPath Full path to the file. + * @return SkString The dir containing the file - anything preceding the + * final slash, or the full name if ending in a slash. + */ + static SkString Dirname(const char* fullPath); }; + #endif diff --git a/gfx/skia/skia/include/core/SkPackBits.h b/gfx/skia/skia/include/core/SkPackBits.h index f0614a084344..1e32ee087550 100644 --- a/gfx/skia/skia/include/core/SkPackBits.h +++ b/gfx/skia/skia/include/core/SkPackBits.h @@ -14,66 +14,33 @@ class SkPackBits { public: - /** Given the number of 16bit values that will be passed to Pack16, - returns the worst-case size needed for the dst[] buffer. - */ - static size_t ComputeMaxSize16(int count); - /** Given the number of 8bit values that will be passed to Pack8, returns the worst-case size needed for the dst[] buffer. */ static size_t ComputeMaxSize8(int count); - /** Write the src array into a packed format. The packing process may end - up writing more bytes than it read, so dst[] must be large enough. - @param src Input array of 16bit values - @param count Number of entries in src[] - @param dst Buffer (allocated by caller) to write the packed data - into - @return the number of bytes written to dst[] - */ - static size_t Pack16(const uint16_t src[], int count, uint8_t dst[]); - /** Write the src array into a packed format. The packing process may end up writing more bytes than it read, so dst[] must be large enough. @param src Input array of 8bit values - @param count Number of entries in src[] + @param srcSize Number of entries in src[] @param dst Buffer (allocated by caller) to write the packed data into + @param dstSize Number of bytes in the output buffer. @return the number of bytes written to dst[] */ - static size_t Pack8(const uint8_t src[], int count, uint8_t dst[]); - - /** Unpack the data in src[], and expand it into dst[]. The src[] data was - written by a previous call to Pack16. - @param src Input data to unpack, previously created by Pack16. - @param srcSize Number of bytes of src to unpack - @param dst Buffer (allocated by caller) to expand the src[] into. - @return the number of dst elements (not bytes) written into dst. - */ - static int Unpack16(const uint8_t src[], size_t srcSize, uint16_t dst[]); + static size_t Pack8(const uint8_t src[], size_t srcSize, uint8_t dst[], + size_t dstSize); /** Unpack the data in src[], and expand it into dst[]. The src[] data was written by a previous call to Pack8. @param src Input data to unpack, previously created by Pack8. @param srcSize Number of bytes of src to unpack @param dst Buffer (allocated by caller) to expand the src[] into. + @param dstSize Number of bytes in the output buffer. @return the number of bytes written into dst. */ - static int Unpack8(const uint8_t src[], size_t srcSize, uint8_t dst[]); - - /** Unpack the data from src[], skip the first dstSkip bytes, then write - dstWrite bytes into dst[]. The src[] data was written by a previous - call to Pack8. Return the number of bytes actually writtten into dst[] - @param src Input data to unpack, previously created by Pack8. - @param dst Buffer (allocated by caller) to expand the src[] into. - @param dstSkip Number of bytes of unpacked src to skip before writing - into dst - @param dstWrite Number of bytes of unpacked src to write into dst (after - skipping dstSkip bytes) - */ - static void Unpack8(uint8_t dst[], size_t dstSkip, size_t dstWrite, - const uint8_t src[]); + static int Unpack8(const uint8_t src[], size_t srcSize, uint8_t dst[], + size_t dstSize); }; #endif diff --git a/gfx/skia/skia/include/core/SkPaint.h b/gfx/skia/skia/include/core/SkPaint.h index 3874d98869c4..2090ed23377c 100644 --- a/gfx/skia/skia/include/core/SkPaint.h +++ b/gfx/skia/skia/include/core/SkPaint.h @@ -1,5 +1,3 @@ - - /* * Copyright 2006 The Android Open Source Project * @@ -7,26 +5,24 @@ * found in the LICENSE file. */ - #ifndef SkPaint_DEFINED #define SkPaint_DEFINED #include "SkColor.h" -#include "SkDrawLooper.h" +#include "SkFilterQuality.h" #include "SkMatrix.h" #include "SkXfermode.h" -#ifdef SK_BUILD_FOR_ANDROID -#include "SkPaintOptionsAndroid.h" -#endif class SkAnnotation; +class SkAutoDescriptor; class SkAutoGlyphCache; class SkColorFilter; +class SkData; class SkDescriptor; -struct SkDeviceProperties; +class SkDrawLooper; class SkReadBuffer; class SkWriteBuffer; -struct SkGlyph; +class SkGlyph; struct SkRect; class SkGlyphCache; class SkImageFilter; @@ -36,6 +32,7 @@ class SkPathEffect; struct SkPoint; class SkRasterizer; class SkShader; +class SkSurfaceProps; class SkTypeface; typedef const SkGlyph& (*SkDrawCacheProc)(SkGlyphCache*, const char**, @@ -59,11 +56,20 @@ public: SkPaint& operator=(const SkPaint&); + /** operator== may give false negatives: two paints that draw equivalently + may return false. It will never give false positives: two paints that + are not equivalent always return false. + */ SK_API friend bool operator==(const SkPaint& a, const SkPaint& b); friend bool operator!=(const SkPaint& a, const SkPaint& b) { return !(a == b); } + /** getHash() is a shallow hash, with the same limitations as operator==. + * If operator== returns true for two paints, getHash() returns the same value for each. + */ + uint32_t getHash() const; + void flatten(SkWriteBuffer&) const; void unflatten(SkReadBuffer&); @@ -110,8 +116,6 @@ public: kAutoHinting_Flag = 0x800, //!< mask to force Freetype's autohinter kVerticalText_Flag = 0x1000, kGenA8FromLCD_Flag = 0x2000, // hack for GDI -- do not use if you can help it - kDistanceFieldTextTEMP_Flag = 0x4000, //!< TEMPORARY mask to enable distance fields - // currently overrides LCD and subpixel rendering // when adding extra flags, note that the fFlags member is specified // with a bit-width and you'll have to expand it. @@ -278,56 +282,19 @@ public: */ void setDevKernText(bool devKernText); - /** Helper for getFlags(), returns true if kDistanceFieldTextTEMP_Flag bit is set - @return true if the distanceFieldText bit is set in the paint's flags. - */ - bool isDistanceFieldTextTEMP() const { - return SkToBool(this->getFlags() & kDistanceFieldTextTEMP_Flag); - } - - /** Helper for setFlags(), setting or clearing the kDistanceFieldTextTEMP_Flag bit - @param distanceFieldText true to set the kDistanceFieldTextTEMP_Flag bit in the paint's - flags, false to clear it. - */ - void setDistanceFieldTextTEMP(bool distanceFieldText); - - enum FilterLevel { - kNone_FilterLevel, - kLow_FilterLevel, - kMedium_FilterLevel, - kHigh_FilterLevel - }; - /** * Return the filter level. This affects the quality (and performance) of * drawing scaled images. */ - FilterLevel getFilterLevel() const { - return (FilterLevel)fBitfields.fFilterLevel; + SkFilterQuality getFilterQuality() const { + return (SkFilterQuality)fBitfields.fFilterQuality; } /** - * Set the filter level. This affects the quality (and performance) of + * Set the filter quality. This affects the quality (and performance) of * drawing scaled images. */ - void setFilterLevel(FilterLevel); - - /** - * If the predicate is true, set the filterLevel to Low, else set it to - * None. - */ - SK_ATTR_DEPRECATED("use setFilterLevel") - void setFilterBitmap(bool doFilter) { - this->setFilterLevel(doFilter ? kLow_FilterLevel : kNone_FilterLevel); - } - - /** - * Returns true if getFilterLevel() returns anything other than None. - */ - SK_ATTR_DEPRECATED("use getFilterLevel") - bool isFilterBitmap() const { - return kNone_FilterLevel != this->getFilterLevel(); - } + void setFilterQuality(SkFilterQuality quality); /** Styles apply to rect, oval, path, and text. Bitmaps are always drawn in "fill", and lines are always drawn in @@ -431,6 +398,15 @@ public: /** Cap enum specifies the settings for the paint's strokecap. This is the treatment that is applied to the beginning and end of each non-closed contour (e.g. lines). + + If the cap is round or square, the caps are drawn when the contour has + a zero length. Zero length contours can be created by following moveTo + with a lineTo at the same point, or a moveTo followed by a close. + + A dash with an on interval of zero also creates a zero length contour. + + The zero length contour draws the square cap without rotation, since + the no direction can be inferred. */ enum Cap { kButt_Cap, //!< begin/end contours with no extension @@ -487,11 +463,17 @@ public: * @param src input path * @param dst output path (may be the same as src) * @param cullRect If not null, the dst path may be culled to this rect. + * @param resScale If > 1, increase precision, else if (0 < res < 1) reduce precision + * in favor of speed/size. * @return true if the path should be filled, or false if it should be * drawn with a hairline (width == 0) */ - bool getFillPath(const SkPath& src, SkPath* dst, - const SkRect* cullRect = NULL) const; + bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect, + SkScalar resScale = 1) const; + + bool getFillPath(const SkPath& src, SkPath* dst) const { + return this->getFillPath(src, dst, NULL, 1); + } /** Get the paint's shader object.

@@ -841,8 +823,7 @@ public: to zero. Note: this does not look at the text-encoding setting in the paint, only at the typeface. */ - void glyphsToUnichars(const uint16_t glyphs[], int count, - SkUnichar text[]) const; + void glyphsToUnichars(const uint16_t glyphs[], int count, SkUnichar text[]) const; /** Return the number of drawable units in the specified text buffer. This looks at the current TextEncoding field of the paint. If you also @@ -861,12 +842,9 @@ public: * @param length Number of bytes of text to measure * @param bounds If not NULL, returns the bounds of the text, * relative to (0, 0). - * @param scale If not 0, return width as if the canvas were scaled - * by this value * @return The advance width of the text */ - SkScalar measureText(const void* text, size_t length, - SkRect* bounds, SkScalar scale = 0) const; + SkScalar measureText(const void* text, size_t length, SkRect* bounds) const; /** Return the width of the text. This will return the vertical measure * if isVerticalText() is true, in which case the returned value should @@ -877,22 +855,9 @@ public: * @return The advance width of the text */ SkScalar measureText(const void* text, size_t length) const { - return this->measureText(text, length, NULL, 0); + return this->measureText(text, length, NULL); } - /** Specify the direction the text buffer should be processed in breakText() - */ - enum TextBufferDirection { - /** When measuring text for breakText(), begin at the start of the text - buffer and proceed forward through the data. This is the default. - */ - kForward_TextBufferDirection, - /** When measuring text for breakText(), begin at the end of the text - buffer and proceed backwards through the data. - */ - kBackward_TextBufferDirection - }; - /** Return the number of bytes of text that were measured. If * isVerticalText() is true, then the vertical advances are used for * the measurement. @@ -903,15 +868,11 @@ public: * widths are <= maxWidth are measured. * @param measuredWidth Optional. If non-null, this returns the actual * width of the measured text. - * @param tbd Optional. The direction the text buffer should be - * traversed during measuring. * @return The number of bytes of text that were measured. Will be * <= length. */ size_t breakText(const void* text, size_t length, SkScalar maxWidth, - SkScalar* measuredWidth = NULL, - TextBufferDirection tbd = kForward_TextBufferDirection) - const; + SkScalar* measuredWidth = NULL) const; /** Return the advances for the text. These will be vertical advances if * isVerticalText() returns true. @@ -938,19 +899,13 @@ public: void getPosTextPath(const void* text, size_t length, const SkPoint pos[], SkPath* path) const; -#ifdef SK_BUILD_FOR_ANDROID - uint32_t getGenerationID() const; - void setGenerationID(uint32_t generationID); - - /** Returns the base glyph count for the strike associated with this paint - */ - unsigned getBaseGlyphCount(SkUnichar text) const; - - const SkPaintOptionsAndroid& getPaintOptionsAndroid() const { - return fPaintOptionsAndroid; - } - void setPaintOptionsAndroid(const SkPaintOptionsAndroid& options); -#endif + /** + * Return a rectangle that represents the union of the bounds of all + * of the glyphs, but each one positioned at (0,0). This may be conservatively large, and + * will not take into account any hinting, but will respect any text-scale-x or text-skew-x + * on this paint. + */ + SkRect getFontBounds() const; // returns true if the paint's settings (e.g. xfermode + alpha) resolve to // mean that we need not draw at all (e.g. SrcOver + 0-alpha) @@ -963,12 +918,7 @@ public: bounds (i.e. there is nothing complex like a patheffect that would make the bounds computation expensive. */ - bool canComputeFastBounds() const { - if (this->getLooper()) { - return this->getLooper()->canComputeFastBounds(*this); - } - return !this->getRasterizer(); - } + bool canComputeFastBounds() const; /** Only call this if canComputeFastBounds() returned true. This takes a raw rectangle (the raw bounds of a shape), and adjusts it for stylistic @@ -1035,11 +985,6 @@ public: SK_TO_STRING_NONVIRT() - struct FlatteningTraits { - static void Flatten(SkWriteBuffer& buffer, const SkPaint& paint); - static void Unflatten(SkReadBuffer& buffer, SkPaint* paint); - }; - private: SkTypeface* fTypeface; SkPathEffect* fPathEffect; @@ -1068,28 +1013,38 @@ private: unsigned fStyle : 2; unsigned fTextEncoding : 2; // 3 values unsigned fHinting : 2; - unsigned fFilterLevel : 2; + unsigned fFilterQuality : 2; //unsigned fFreeBits : 2; } fBitfields; uint32_t fBitfieldsUInt; }; - uint32_t fDirtyBits; SkDrawCacheProc getDrawCacheProc() const; - SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir, - bool needFullMetrics) const; + SkMeasureCacheProc getMeasureCacheProc(bool needFullMetrics) const; SkScalar measure_text(SkGlyphCache*, const char* text, size_t length, int* count, SkRect* bounds) const; - SkGlyphCache* detachCache(const SkDeviceProperties* deviceProperties, const SkMatrix*, + /* + * Allocs an SkDescriptor on the heap and return it to the caller as a refcnted + * SkData. Caller is responsible for managing the lifetime of this object. + */ + void getScalerContextDescriptor(SkAutoDescriptor*, const SkSurfaceProps& surfaceProps, + const SkMatrix*, bool ignoreGamma) const; + + SkGlyphCache* detachCache(const SkSurfaceProps* surfaceProps, const SkMatrix*, bool ignoreGamma) const; - void descriptorProc(const SkDeviceProperties* deviceProperties, const SkMatrix* deviceMatrix, + void descriptorProc(const SkSurfaceProps* surfaceProps, const SkMatrix* deviceMatrix, void (*proc)(SkTypeface*, const SkDescriptor*, void*), - void* context, bool ignoreGamma = false) const; + void* context, bool ignoreGamma) const; - static void Term(); + /* + * The luminance color is used to determine which Gamma Canonical color to map to. This is + * really only used by backends which want to cache glyph masks, and need some way to know if + * they need to generate new masks based off a given color. + */ + SkColor computeLuminanceColor() const; enum { /* This is the size we use when we ask for a glyph's path. We then @@ -1133,21 +1088,17 @@ private: friend class SkAutoGlyphCacheNoGamma; friend class SkCanvas; friend class SkDraw; - friend class SkGraphics; // So Term() can be called. friend class SkPDFDevice; friend class GrBitmapTextContext; + friend class GrAtlasTextContext; friend class GrDistanceFieldTextContext; friend class GrStencilAndCoverTextContext; + friend class GrPathRendering; + friend class GrTextContext; + friend class GrGLPathRendering; + friend class SkScalerContext; friend class SkTextToPathIter; friend class SkCanonicalizePaint; - -#ifdef SK_BUILD_FOR_ANDROID - SkPaintOptionsAndroid fPaintOptionsAndroid; - - // In order for the == operator to work properly this must be the last field - // in the struct so that we can do a memcmp to this field's offset. - uint32_t fGenerationID; -#endif }; #endif diff --git a/gfx/skia/skia/include/core/SkPaintOptionsAndroid.h b/gfx/skia/skia/include/core/SkPaintOptionsAndroid.h deleted file mode 100644 index ab84ec050e35..000000000000 --- a/gfx/skia/skia/include/core/SkPaintOptionsAndroid.h +++ /dev/null @@ -1,130 +0,0 @@ - -/* - * Copyright 2012 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - - -#ifndef SkPaintOptionsAndroid_DEFINED -#define SkPaintOptionsAndroid_DEFINED - -#include "SkTypes.h" -#include "SkString.h" - -class SkReadBuffer; -class SkWriteBuffer; - -/** \class SkLanguage - - The SkLanguage class represents a human written language, and is used by - text draw operations to determine which glyph to draw when drawing - characters with variants (ie Han-derived characters). -*/ -class SkLanguage { -public: - SkLanguage() { } - SkLanguage(const SkString& tag) : fTag(tag) { } - SkLanguage(const char* tag) : fTag(tag) { } - SkLanguage(const char* tag, size_t len) : fTag(tag, len) { } - SkLanguage(const SkLanguage& b) : fTag(b.fTag) { } - - /** Gets a BCP 47 language identifier for this SkLanguage. - @return a BCP 47 language identifier representing this language - */ - const SkString& getTag() const { return fTag; } - - /** Performs BCP 47 fallback to return an SkLanguage one step more general. - @return an SkLanguage one step more general - */ - SkLanguage getParent() const; - - bool operator==(const SkLanguage& b) const { - return fTag == b.fTag; - } - bool operator!=(const SkLanguage& b) const { - return fTag != b.fTag; - } - SkLanguage& operator=(const SkLanguage& b) { - fTag = b.fTag; - return *this; - } - -private: - //! BCP 47 language identifier - SkString fTag; -}; - -class SkPaintOptionsAndroid { -public: - SkPaintOptionsAndroid() { - fFontVariant = kDefault_Variant; - fUseFontFallbacks = false; - } - - SkPaintOptionsAndroid& operator=(const SkPaintOptionsAndroid& b) { - fLanguage = b.fLanguage; - fFontVariant = b.fFontVariant; - fUseFontFallbacks = b.fUseFontFallbacks; - return *this; - } - - bool operator==(const SkPaintOptionsAndroid& b) const { - return !(*this != b); - } - - bool operator!=(const SkPaintOptionsAndroid& b) const { - return fLanguage != b.fLanguage || - fFontVariant != b.fFontVariant || - fUseFontFallbacks != b.fUseFontFallbacks; - } - - void flatten(SkWriteBuffer&) const; - void unflatten(SkReadBuffer&); - - /** Return the paint's language value used for drawing text. - @return the paint's language value used for drawing text. - */ - const SkLanguage& getLanguage() const { return fLanguage; } - - /** Set the paint's language value used for drawing text. - @param language set the paint's language value for drawing text. - */ - void setLanguage(const SkLanguage& language) { fLanguage = language; } - void setLanguage(const char* languageTag) { fLanguage = SkLanguage(languageTag); } - - - enum FontVariant { - kDefault_Variant = 0x01, - kCompact_Variant = 0x02, - kElegant_Variant = 0x04, - kLast_Variant = kElegant_Variant, - }; - - /** Return the font variant - @return the font variant used by this paint object - */ - FontVariant getFontVariant() const { return fFontVariant; } - - /** Set the font variant - @param fontVariant set the paint's font variant for choosing fonts - */ - void setFontVariant(FontVariant fontVariant) { - SkASSERT((unsigned)fontVariant <= kLast_Variant); - fFontVariant = fontVariant; - } - - bool isUsingFontFallbacks() const { return fUseFontFallbacks; } - - void setUseFontFallbacks(bool useFontFallbacks) { - fUseFontFallbacks = useFontFallbacks; - } - -private: - SkLanguage fLanguage; - FontVariant fFontVariant; - bool fUseFontFallbacks; -}; - -#endif // #ifndef SkPaintOptionsAndroid_DEFINED diff --git a/gfx/skia/skia/include/core/SkPatch.h b/gfx/skia/skia/include/core/SkPatch.h deleted file mode 100644 index 2354423aba21..000000000000 --- a/gfx/skia/skia/include/core/SkPatch.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkPatch_DEFINED -#define SkPatch_DEFINED - -#include "SkColor.h" -#include "SkPreConfig.h" -#include "SkPoint.h" - -/** - * Class that represents a coons patch. - */ -class SK_API SkPatch { - -public: - /** - * Structure that holds the vertex data related to the tessellation of a SkPatch. It is passed - * as a parameter to the function getVertexData which sets the points, colors and texture - * coordinates of the vertices and the indices for them to be drawn as triangles. - */ - struct VertexData { - int fVertexCount, fIndexCount; - SkPoint* fPoints; - SkPoint* fTexCoords; - uint32_t* fColors; - uint16_t* fIndices; - - VertexData() - : fVertexCount(0) - , fIndexCount(0) - , fPoints(NULL) - , fTexCoords(NULL) - , fColors(NULL) - , fIndices(NULL) { } - - ~VertexData() { - SkDELETE_ARRAY(fPoints); - SkDELETE_ARRAY(fTexCoords); - SkDELETE_ARRAY(fColors); - SkDELETE_ARRAY(fIndices); - } - }; - - enum CubicCtrlPts { - kTopP0_CubicCtrlPts = 0, - kTopP1_CubicCtrlPts = 1, - kTopP2_CubicCtrlPts = 2, - kTopP3_CubicCtrlPts = 3, - - kRightP0_CubicCtrlPts = 3, - kRightP1_CubicCtrlPts = 4, - kRightP2_CubicCtrlPts = 5, - kRightP3_CubicCtrlPts = 6, - - kBottomP0_CubicCtrlPts = 9, - kBottomP1_CubicCtrlPts = 8, - kBottomP2_CubicCtrlPts = 7, - kBottomP3_CubicCtrlPts = 6, - - kLeftP0_CubicCtrlPts = 0, - kLeftP1_CubicCtrlPts = 11, - kLeftP2_CubicCtrlPts = 10, - kLeftP3_CubicCtrlPts = 9, - }; - - /** - * Points are in the following order: - * (top curve) - * 0 1 2 3 - * (left curve) 11 4 (right curve) - * 10 5 - * 9 8 7 6 - * (bottom curve) - * Used pointer to an array to guarantee that this method receives an array of 4 SkColors - */ - SkPatch(SkPoint points[12], SkColor colors[4]); - - /** - * Function that evaluates the coons patch interpolation. - * data refers to the pointer of the PatchData struct in which the tessellation data is set. - * divisions defines the number of steps in which the SkPatch is going to be subdivided per - * axis. - */ - bool getVertexData(SkPatch::VertexData* data, int divisions); - - void getTopPoints(SkPoint points[4]) { - points[0] = fCtrlPoints[kTopP0_CubicCtrlPts]; - points[1] = fCtrlPoints[kTopP1_CubicCtrlPts]; - points[2] = fCtrlPoints[kTopP2_CubicCtrlPts]; - points[3] = fCtrlPoints[kTopP3_CubicCtrlPts]; - } - - void getBottomPoints(SkPoint points[4]) { - points[0] = fCtrlPoints[kBottomP0_CubicCtrlPts]; - points[1] = fCtrlPoints[kBottomP1_CubicCtrlPts]; - points[2] = fCtrlPoints[kBottomP2_CubicCtrlPts]; - points[3] = fCtrlPoints[kBottomP3_CubicCtrlPts]; - } - - void getLeftPoints(SkPoint points[4]) { - points[0] = fCtrlPoints[kLeftP0_CubicCtrlPts]; - points[1] = fCtrlPoints[kLeftP1_CubicCtrlPts]; - points[2] = fCtrlPoints[kLeftP2_CubicCtrlPts]; - points[3] = fCtrlPoints[kLeftP3_CubicCtrlPts]; - } - - void getRightPoints(SkPoint points[4]) { - points[0] = fCtrlPoints[kRightP0_CubicCtrlPts]; - points[1] = fCtrlPoints[kRightP1_CubicCtrlPts]; - points[2] = fCtrlPoints[kRightP2_CubicCtrlPts]; - points[3] = fCtrlPoints[kRightP3_CubicCtrlPts]; - } - -private: - SkPoint fCtrlPoints[12]; - SkPMColor fCornerColors[4]; -}; - -#endif diff --git a/gfx/skia/skia/include/core/SkPath.h b/gfx/skia/skia/include/core/SkPath.h index bccc8d52c992..33db8ac24962 100644 --- a/gfx/skia/skia/include/core/SkPath.h +++ b/gfx/skia/skia/include/core/SkPath.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,11 +5,9 @@ * found in the LICENSE file. */ - #ifndef SkPath_DEFINED #define SkPath_DEFINED -#include "SkInstCnt.h" #include "SkMatrix.h" #include "SkPathRef.h" #include "SkTDArray.h" @@ -30,8 +27,6 @@ class SkWStream; */ class SK_API SkPath { public: - SK_DECLARE_INST_COUNT_ROOT(SkPath); - SkPath(); SkPath(const SkPath&); ~SkPath(); @@ -42,6 +37,11 @@ public: return !(a == b); } +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + /** Returns true if the caller is the only owner of the underlying path data */ + bool unique() const { return fPathRef->unique(); } +#endif + enum FillType { /** Specifies that "inside" is computed by a non-zero sum of signed edge crossings @@ -154,6 +154,17 @@ public: */ bool isOval(SkRect* rect) const { return fPathRef->isOval(rect); } + /** Returns true if the path is a round rect. + * + * @param rrect Returns the bounding rect and radii of this round rect. + * + * @return true if this path is a round rect. + * Tracking whether a path is a round rect is considered an + * optimization for performance and so some paths that are in + * fact round rects can report false. + */ + bool isRRect(SkRRect* rrect) const { return fPathRef->isRRect(rrect); } + /** Clear any lines and curves from the path, making it empty. This frees up internal storage associated with those segments. On Android, does not change fSourcePath. @@ -185,12 +196,29 @@ public: return fPathRef->isFinite(); } + /** Returns true if the path is volatile (i.e. should not be cached by devices.) + */ + bool isVolatile() const { + return SkToBool(fIsVolatile); + } + + /** Specify whether this path is volatile. Paths are not volatile by + default. Temporary paths that are discarded or modified after use should be + marked as volatile. This provides a hint to the device that the path + should not be cached. Providing this hint when appropriate can + improve performance by avoiding unnecessary overhead and resource + consumption on the device. + */ + void setIsVolatile(bool isVolatile) { + fIsVolatile = isVolatile; + } + /** Test a line for zero length @return true if the line is of zero length; otherwise false. */ - static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2) { - return p1.equalsWithinTolerance(p2); + static bool IsLineDegenerate(const SkPoint& p1, const SkPoint& p2, bool exact) { + return exact ? p1 == p2 : p1.equalsWithinTolerance(p2); } /** Test a quad for zero length @@ -198,8 +226,8 @@ public: @return true if the quad is of zero length; otherwise false. */ static bool IsQuadDegenerate(const SkPoint& p1, const SkPoint& p2, - const SkPoint& p3) { - return p1.equalsWithinTolerance(p2) && + const SkPoint& p3, bool exact) { + return exact ? p1 == p2 && p2 == p3 : p1.equalsWithinTolerance(p2) && p2.equalsWithinTolerance(p3); } @@ -208,8 +236,8 @@ public: @return true if the cubic is of zero length; otherwise false. */ static bool IsCubicDegenerate(const SkPoint& p1, const SkPoint& p2, - const SkPoint& p3, const SkPoint& p4) { - return p1.equalsWithinTolerance(p2) && + const SkPoint& p3, const SkPoint& p4, bool exact) { + return exact ? p1 == p2 && p2 == p3 && p3 == p4 : p1.equalsWithinTolerance(p2) && p2.equalsWithinTolerance(p3) && p3.equalsWithinTolerance(p4); } @@ -222,16 +250,6 @@ public: */ bool isLine(SkPoint line[2]) const; - /** Returns true if the path specifies a rectangle. If so, and if rect is - not null, set rect to the bounds of the path. If the path does not - specify a rectangle, return false and ignore rect. - - @param rect If not null, returns the bounds of the path if it specifies - a rectangle - @return true if the path specifies a rectangle - */ - bool isRect(SkRect* rect) const; - /** Return the number of points in the path */ int countPoints() const; @@ -266,10 +284,12 @@ public: //! Swap contents of this and other. Guaranteed not to throw void swap(SkPath& other); - /** Returns the bounds of the path's points. If the path contains 0 or 1 - points, the bounds is set to (0,0,0,0), and isEmpty() will return true. - Note: this bounds may be larger than the actual shape, since curves - do not extend as far as their control points. + /** + * Returns the bounds of the path's points. If the path contains zero points/verbs, this + * will return the "empty" rect [0, 0, 0, 0]. + * Note: this bounds may be larger than the actual shape, since curves + * do not extend as far as their control points. Additionally this bound encompases all points, + * even isolated moveTos either preceeding or following the last non-degenerate contour. */ const SkRect& getBounds() const { return fPathRef->getBounds(); @@ -450,26 +470,23 @@ public: void rCubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3); - /** Append the specified arc to the path as a new contour. If the start of - the path is different from the path's current last point, then an - automatic lineTo() is added to connect the current contour to the start - of the arc. However, if the path is empty, then we call moveTo() with - the first point of the arc. The sweep angle is treated mod 360. + /** + * Append the specified arc to the path. If the start of the arc is different from the path's + * current last point, then an automatic lineTo() is added to connect the current contour + * to the start of the arc. However, if the path is empty, then we call moveTo() with + * the first point of the arc. The sweep angle is treated mod 360. + * + * @param oval The bounding oval defining the shape and size of the arc + * @param startAngle Starting angle (in degrees) where the arc begins + * @param sweepAngle Sweep angle (in degrees) measured clockwise. This is treated mod 360. + * @param forceMoveTo If true, always begin a new contour with the arc + */ + void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool forceMoveTo); - @param oval The bounding oval defining the shape and size of the arc - @param startAngle Starting angle (in degrees) where the arc begins - @param sweepAngle Sweep angle (in degrees) measured clockwise. This is - treated mod 360. - @param forceMoveTo If true, always begin a new contour with the arc - */ - void arcTo(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, - bool forceMoveTo); - - /** Append a line and arc to the current path. This is the same as the - PostScript call "arct". - */ - void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, - SkScalar radius); + /** + * Append a line and arc to the current path. This is the same as the PostScript call "arct". + */ + void arcTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar radius); /** Append a line and arc to the current path. This is the same as the PostScript call "arct". @@ -484,25 +501,12 @@ public: void close(); enum Direction { - /** Direction either has not been or could not be computed */ - kUnknown_Direction, /** clockwise direction for adding closed contours */ kCW_Direction, /** counter-clockwise direction for adding closed contours */ kCCW_Direction, }; - /** - * Return the opposite of the specified direction. kUnknown is its own - * opposite. - */ - static Direction OppositeDirection(Direction dir) { - static const Direction gOppositeDir[] = { - kUnknown_Direction, kCCW_Direction, kCW_Direction - }; - return gOppositeDir[dir]; - } - /** * Returns whether or not a fill type is inverted * @@ -512,10 +516,10 @@ public: * kInverseEvenOdd_FillType -> true */ static bool IsInverseFillType(FillType fill) { - SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch); + static_assert(0 == kWinding_FillType, "fill_type_mismatch"); + static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch"); + static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch"); + static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch"); return (fill & 2) != 0; } @@ -528,65 +532,39 @@ public: * kInverseEvenOdd_FillType -> kEvenOdd_FillType */ static FillType ConvertToNonInverseFillType(FillType fill) { - SK_COMPILE_ASSERT(0 == kWinding_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(1 == kEvenOdd_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(2 == kInverseWinding_FillType, fill_type_mismatch); - SK_COMPILE_ASSERT(3 == kInverseEvenOdd_FillType, fill_type_mismatch); + static_assert(0 == kWinding_FillType, "fill_type_mismatch"); + static_assert(1 == kEvenOdd_FillType, "fill_type_mismatch"); + static_assert(2 == kInverseWinding_FillType, "fill_type_mismatch"); + static_assert(3 == kInverseEvenOdd_FillType, "fill_type_mismatch"); return (FillType)(fill & 1); } /** - * Tries to quickly compute the direction of the first non-degenerate - * contour. If it can be computed, return true and set dir to that - * direction. If it cannot be (quickly) determined, return false and ignore - * the dir parameter. If the direction was determined, it is cached to make - * subsequent calls return quickly. + * Chop a conic into N quads, stored continguously in pts[], where + * N = 1 << pow2. The amount of storage needed is (1 + 2 * N) */ - bool cheapComputeDirection(Direction* dir) const; + static int ConvertConicToQuads(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2, + SkScalar w, SkPoint pts[], int pow2); /** - * Returns true if the path's direction can be computed via - * cheapComputDirection() and if that computed direction matches the - * specified direction. If dir is kUnknown, returns true if the direction - * cannot be computed. + * Returns true if the path specifies a rectangle. + * + * If this returns false, then all output parameters are ignored, and left + * unchanged. If this returns true, then each of the output parameters + * are checked for NULL. If they are not, they return their value. + * + * @param rect If not null, set to the bounds of the rectangle. + * Note : this bounds may be smaller than the path's bounds, since it is just + * the bounds of the "drawable" parts of the path. e.g. a trailing MoveTo would + * be ignored in this rect, but not by the path's bounds + * @param isClosed If not null, set to true if the path is closed + * @param direction If not null, set to the rectangle's direction + * @return true if the path specifies a rectangle */ - bool cheapIsDirection(Direction dir) const { - Direction computedDir = kUnknown_Direction; - (void)this->cheapComputeDirection(&computedDir); - return computedDir == dir; - } + bool isRect(SkRect* rect, bool* isClosed = NULL, Direction* direction = NULL) const; - enum PathAsRect { - /** The path can not draw the same as its bounds. */ - kNone_PathAsRect, - /** The path draws the same as its bounds when filled. */ - kFill_PathAsRect, - /** The path draws the same as its bounds when stroked or filled. */ - kStroke_PathAsRect, - }; - - /** Returns kFill_PathAsRect or kStroke_PathAsRect if drawing the path (either filled or - stroked) will be equivalent to filling/stroking the path's bounding rect. If - either is true, and direction is not null, sets the direction of the contour. If the - path is not drawn equivalent to a rect, returns kNone_PathAsRect and ignores direction. - - @param direction If not null, set to the contour's direction when it is drawn as a rect - @return the path's PathAsRect type - */ - PathAsRect asRect(Direction* direction = NULL) const; - - /** Returns true if the path specifies a rectangle. If so, and if isClosed is - not null, set isClosed to true if the path is closed. Also, if returning true - and direction is not null, return the rect direction. If the path does not - specify a rectangle, return false and ignore isClosed and direction. - - @param isClosed If not null, set to true if the path is closed - @param direction If not null, set to the rectangle's direction - @return true if the path specifies a rectangle - */ - bool isRect(bool* isClosed, Direction* direction) const; - - /** Returns true if the path specifies a pair of nested rectangles. If so, and if + /** Returns true if the path specifies a pair of nested rectangles, or would draw a + pair of nested rectangles when filled. If so, and if rect is not null, set rect[0] to the outer rectangle and rect[1] to the inner rectangle. If so, and dirs is not null, set dirs[0] to the direction of the outer rectangle and dirs[1] to the direction of the inner rectangle. If @@ -597,16 +575,32 @@ public: @param dirs If not null, returns the direction of the rects @return true if the path describes a pair of nested rectangles */ - bool isNestedRects(SkRect rect[2], Direction dirs[2] = NULL) const; + bool isNestedFillRects(SkRect rect[2], Direction dirs[2] = NULL) const; /** * Add a closed rectangle contour to the path * @param rect The rectangle to add as a closed contour to the path - * @param dir The direction to wind the rectangle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the rectangle's contour. + * + * Note: the contour initial point index is 0 (as defined below). */ void addRect(const SkRect& rect, Direction dir = kCW_Direction); + /** + * Add a closed rectangle contour to the path + * @param rect The rectangle to add as a closed contour to the path + * @param dir The direction to wind the rectangle's contour. + * @param start Initial point of the contour (initial moveTo), expressed as + * a corner index, starting in the upper-left position, clock-wise: + * + * 0 1 + * *-------* + * | | + * *-------* + * 3 2 + */ + void addRect(const SkRect& rect, Direction dir, unsigned start); + /** * Add a closed rectangle contour to the path * @@ -618,8 +612,9 @@ public: * to the path * @param bottom The bottom of a rectangle to add as a closed contour to * the path - * @param dir The direction to wind the rectangle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the rectangle's contour. + * + * Note: the contour initial point index is 0 (as defined above). */ void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom, Direction dir = kCW_Direction); @@ -628,11 +623,31 @@ public: * Add a closed oval contour to the path * * @param oval The bounding oval to add as a closed contour to the path - * @param dir The direction to wind the oval's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the oval's contour. + * + * Note: the contour initial point index is 1 (as defined below). */ void addOval(const SkRect& oval, Direction dir = kCW_Direction); + /** + * Add a closed oval contour to the path + * + * @param oval The bounding oval to add as a closed contour to the path + * @param dir The direction to wind the oval's contour. + * @param start Initial point of the contour (initial moveTo), expressed + * as an ellipse vertex index, starting at the top, clock-wise + * (90/0/270/180deg order): + * + * 0 + * -*- + * | | + * 3 * * 1 + * | | + * -*- + * 2 + */ + void addOval(const SkRect& oval, Direction dir, unsigned start); + /** * Add a closed circle contour to the path * @@ -642,8 +657,7 @@ public: * closed contour to the path * @param radius The radius of a circle to add as a closed contour to the * path - * @param dir The direction to wind the circle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the circle's contour. */ void addCircle(SkScalar x, SkScalar y, SkScalar radius, Direction dir = kCW_Direction); @@ -661,8 +675,7 @@ public: * @param rect The bounds of a round-rectangle to add as a closed contour * @param rx The x-radius of the rounded corners on the round-rectangle * @param ry The y-radius of the rounded corners on the round-rectangle - * @param dir The direction to wind the rectangle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the rectangle's contour. */ void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry, Direction dir = kCW_Direction); @@ -673,8 +686,7 @@ public: * bottom-right, bottom-left. * @param rect The bounds of a round-rectangle to add as a closed contour * @param radii Array of 8 scalars, 4 [X,Y] pairs for each corner - * @param dir The direction to wind the rectangle's contour. Cannot be - * kUnknown_Direction. + * @param dir The direction to wind the rectangle's contour. * Note: The radii here now go through the same constraint handling as the * SkRRect radii (i.e., either radii at a corner being 0 implies a * sqaure corner and oversized radii are proportionally scaled down). @@ -685,11 +697,31 @@ public: /** * Add an SkRRect contour to the path * @param rrect The rounded rect to add as a closed contour - * @param dir The winding direction for the new contour. Cannot be - * kUnknown_Direction. + * @param dir The winding direction for the new contour. + * + * Note: the contour initial point index is either 6 (for dir == kCW_Direction) + * or 7 (for dir == kCCW_Direction), as defined below. + * */ void addRRect(const SkRRect& rrect, Direction dir = kCW_Direction); + /** + * Add an SkRRect contour to the path + * @param rrect The rounded rect to add as a closed contour + * @param dir The winding direction for the new contour. + * @param start Initial point of the contour (initial moveTo), expressed as + * an index of the radii minor/major points, ordered clock-wise: + * + * 0 1 + * *----* + * 7 * * 2 + * | | + * 6 * * 3 + * *----* + * 5 4 + */ + void addRRect(const SkRRect& rrect, Direction dir, unsigned start); + /** * Add a new contour made of just lines. This is just a fast version of * the following: @@ -848,11 +880,15 @@ public: @param pts The points representing the current verb and/or segment @param doConsumeDegerates If true, first scan for segments that are deemed degenerate (too short) and skip those. + @param exact if doConsumeDegenerates is true and exact is true, skip only + degenerate elements with lengths exactly equal to zero. If exact + is false, skip degenerate elements with lengths close to zero. If + doConsumeDegenerates is false, exact has no effect. @return The verb for the current segment */ - Verb next(SkPoint pts[4], bool doConsumeDegerates = true) { + Verb next(SkPoint pts[4], bool doConsumeDegerates = true, bool exact = false) { if (doConsumeDegerates) { - this->consumeDegenerateSegments(); + this->consumeDegenerateSegments(exact); } return this->doNext(pts); } @@ -892,7 +928,7 @@ public: inline const SkPoint& cons_moveTo(); Verb autoClose(SkPoint pts[2]); - void consumeDegenerateSegments(); + void consumeDegenerateSegments(bool exact); Verb doNext(SkPoint pts[4]); }; @@ -900,10 +936,14 @@ public: */ class SK_API RawIter { public: - RawIter(); - RawIter(const SkPath&); + RawIter() {} + RawIter(const SkPath& path) { + setPath(path); + } - void setPath(const SkPath&); + void setPath(const SkPath& path) { + fRawIter.setPathRef(*path.fPathRef.get()); + } /** Return the next verb in this iteration of the path. When all segments have been visited, return kDone_Verb. @@ -912,17 +952,17 @@ public: This must not be NULL. @return The verb for the current segment */ - Verb next(SkPoint pts[4]); + Verb next(SkPoint pts[4]) { + return (Verb) fRawIter.next(pts); + } - SkScalar conicWeight() const { return *fConicWeights; } + SkScalar conicWeight() const { + return fRawIter.conicWeight(); + } private: - const SkPoint* fPts; - const uint8_t* fVerbs; - const uint8_t* fVerbStop; - const SkScalar* fConicWeights; - SkPoint fMoveTo; - SkPoint fLastPt; + SkPathRef::Iter fRawIter; + friend class SkPath; }; /** @@ -931,8 +971,9 @@ public: */ bool contains(SkScalar x, SkScalar y) const; - void dump(SkWStream* , bool forceClose) const; + void dump(SkWStream* , bool forceClose, bool dumpAsHex) const; void dump() const; + void dumpHex() const; /** * Write the path to the buffer, and return the number of bytes written. @@ -955,37 +996,39 @@ public: */ uint32_t getGenerationID() const; -#ifdef SK_BUILD_FOR_ANDROID +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK static const int kPathRefGenIDBitCnt = 30; // leave room for the fill type (skbug.com/1762) - const SkPath* getSourcePath() const; - void setSourcePath(const SkPath* path); #else static const int kPathRefGenIDBitCnt = 32; #endif SkDEBUGCODE(void validate() const;) + SkDEBUGCODE(void experimentalValidateRef() const { fPathRef->validate(); } ) private: enum SerializationOffsets { // 1 free bit at 29 kUnused1_SerializationShift = 28, // 1 free bit kDirection_SerializationShift = 26, // requires 2 bits - kUnused2_SerializationShift = 25, // 1 free bit + kIsVolatile_SerializationShift = 25, // requires 1 bit // 1 free bit at 24 kConvexity_SerializationShift = 16, // requires 8 bits kFillType_SerializationShift = 8, // requires 8 bits - // 8 free bits at 0 + // low-8-bits are version }; - SkAutoTUnref fPathRef; + enum SerializationVersions { + kPathPrivFirstDirection_Version = 1, - int fLastMoveToIndex; - uint8_t fFillType; - mutable uint8_t fConvexity; - mutable uint8_t fDirection; -#ifdef SK_BUILD_FOR_ANDROID - const SkPath* fSourcePath; -#endif + kCurrent_Version = 1 + }; + + SkAutoTUnref fPathRef; + int fLastMoveToIndex; + uint8_t fFillType; + mutable uint8_t fConvexity; + mutable SkAtomic fFirstDirection;// SkPathPriv::FirstDirection + mutable SkBool8 fIsVolatile; /** Resets all fields other than fPathRef to their initial 'empty' values. * Assumes the caller has already emptied fPathRef. @@ -1000,7 +1043,7 @@ private: void copyFields(const SkPath& that); friend class Iter; - + friend class SkPathPriv; friend class SkPathStroker; /* Append, in reverse order, the first contour of path, ignoring path's @@ -1040,11 +1083,14 @@ private: ed.setBounds(rect); } + void setPt(int index, SkScalar x, SkScalar y); + friend class SkAutoPathBoundsUpdate; friend class SkAutoDisableOvalCheck; friend class SkAutoDisableDirectionCheck; friend class SkBench_AddPathTest; // perf test reversePathTo friend class PathTest_Private; // unit test reversePathTo + friend class ForceIsRRect_Private; // unit test isRRect }; #endif diff --git a/gfx/skia/skia/include/core/SkPathEffect.h b/gfx/skia/skia/include/core/SkPathEffect.h index 562025351e85..36e67e1de064 100644 --- a/gfx/skia/skia/include/core/SkPathEffect.h +++ b/gfx/skia/skia/include/core/SkPathEffect.h @@ -14,10 +14,10 @@ #include "SkPath.h" #include "SkPoint.h" #include "SkRect.h" -#include "SkStrokeRec.h" #include "SkTDArray.h" class SkPath; +class SkStrokeRec; /** \class SkPathEffect @@ -29,8 +29,6 @@ class SkPath; */ class SK_API SkPathEffect : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkPathEffect) - /** * Given a src path (input) and a stroke-rec (input and output), apply * this effect to the src path, returning the new path in dst, and return @@ -131,11 +129,16 @@ public: virtual DashType asADash(DashInfo* info) const; + SK_TO_STRING_PUREVIRT() SK_DEFINE_FLATTENABLE_TYPE(SkPathEffect) +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + /// Override for subclasses as appropriate. + virtual bool exposedInAndroidJavaAPI() const { return false; } +#endif + protected: SkPathEffect() {} - SkPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {} private: // illegal @@ -157,12 +160,14 @@ public: protected: SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1); - SkPairPathEffect(SkReadBuffer&); - virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; + + void flatten(SkWriteBuffer&) const override; // these are visible to our subclasses SkPathEffect* fPE0, *fPE1; + SK_TO_STRING_OVERRIDE() + private: typedef SkPathEffect INHERITED; }; @@ -180,18 +185,21 @@ public: and decremented in the destructor. */ static SkComposePathEffect* Create(SkPathEffect* outer, SkPathEffect* inner) { - return SkNEW_ARGS(SkComposePathEffect, (outer, inner)); + return new SkComposePathEffect(outer, inner); } virtual bool filterPath(SkPath* dst, const SkPath& src, - SkStrokeRec*, const SkRect*) const SK_OVERRIDE; + SkStrokeRec*, const SkRect*) const override; + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect) +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + bool exposedInAndroidJavaAPI() const override { return true; } +#endif + protected: - SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner) - : INHERITED(outer, inner) {} - explicit SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {} + SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner) : INHERITED(outer, inner) {} private: // illegal @@ -214,18 +222,21 @@ public: and decremented in the destructor. */ static SkSumPathEffect* Create(SkPathEffect* first, SkPathEffect* second) { - return SkNEW_ARGS(SkSumPathEffect, (first, second)); + return new SkSumPathEffect(first, second); } virtual bool filterPath(SkPath* dst, const SkPath& src, - SkStrokeRec*, const SkRect*) const SK_OVERRIDE; + SkStrokeRec*, const SkRect*) const override; + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect) +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + bool exposedInAndroidJavaAPI() const override { return true; } +#endif + protected: - SkSumPathEffect(SkPathEffect* first, SkPathEffect* second) - : INHERITED(first, second) {} - explicit SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {} + SkSumPathEffect(SkPathEffect* first, SkPathEffect* second) : INHERITED(first, second) {} private: // illegal diff --git a/gfx/skia/skia/include/core/SkPathMeasure.h b/gfx/skia/skia/include/core/SkPathMeasure.h index bc46b4a38b19..f6e606f0c06d 100644 --- a/gfx/skia/skia/include/core/SkPathMeasure.h +++ b/gfx/skia/skia/include/core/SkPathMeasure.h @@ -11,6 +11,8 @@ #include "SkPath.h" #include "SkTDArray.h" +struct SkConic; + class SK_API SkPathMeasure : SkNoncopyable { public: SkPathMeasure(); @@ -101,6 +103,7 @@ private: void buildSegments(); SkScalar compute_quad_segs(const SkPoint pts[3], SkScalar distance, int mint, int maxt, int ptIndex); + SkScalar compute_conic_segs(const SkConic&, SkScalar distance, int mint, int maxt, int ptIndex); SkScalar compute_cubic_segs(const SkPoint pts[3], SkScalar distance, int mint, int maxt, int ptIndex); const Segment* distanceToSegment(SkScalar distance, SkScalar* t); diff --git a/gfx/skia/skia/include/core/SkPathRef.h b/gfx/skia/skia/include/core/SkPathRef.h index ba68fcba3c60..86f55c9bcae2 100644 --- a/gfx/skia/skia/include/core/SkPathRef.h +++ b/gfx/skia/skia/include/core/SkPathRef.h @@ -9,9 +9,9 @@ #ifndef SkPathRef_DEFINED #define SkPathRef_DEFINED -#include "SkDynamicAnnotations.h" #include "SkMatrix.h" #include "SkPoint.h" +#include "SkRRect.h" #include "SkRect.h" #include "SkRefCnt.h" #include "SkTDArray.h" @@ -37,8 +37,6 @@ class SkWBuffer; class SK_API SkPathRef : public ::SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkPathRef); - class Editor { public: Editor(SkAutoTUnref* pathRef, @@ -103,12 +101,39 @@ public: void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); } + void setIsRRect(bool isRRect) { fPathRef->setIsRRect(isRRect); } + void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); } private: SkPathRef* fPathRef; }; + class SK_API Iter { + public: + Iter(); + Iter(const SkPathRef&); + + void setPathRef(const SkPathRef&); + + /** Return the next verb in this iteration of the path. When all + segments have been visited, return kDone_Verb. + + @param pts The points representing the current verb and/or segment + This must not be NULL. + @return The verb for the current segment + */ + uint8_t next(SkPoint pts[4]); + + SkScalar conicWeight() const { return *fConicWeights; } + + private: + const SkPoint* fPts; + const uint8_t* fVerbs; + const uint8_t* fVerbStop; + const SkScalar* fConicWeights; + }; + public: /** * Gets a path ref with no verbs or points. @@ -144,13 +169,21 @@ public: * fact ovals can report false. */ bool isOval(SkRect* rect) const { - if (fIsOval && NULL != rect) { - *rect = getBounds(); + if (fIsOval && rect) { + *rect = this->getBounds(); } return SkToBool(fIsOval); } + bool isRRect(SkRRect* rrect) const { + if (fIsRRect && rrect) { + *rrect = this->getRRect(); + } + return SkToBool(fIsRRect); + } + + bool hasComputedBounds() const { return !fBoundsIsDirty; } @@ -167,6 +200,8 @@ public: return fBounds; } + SkRRect getRRect() const; + /** * Transforms a path ref by a matrix, allocating a new one only if necessary. */ @@ -183,19 +218,7 @@ public: */ static void Rewind(SkAutoTUnref* pathRef); - virtual ~SkPathRef() { - SkDEBUGCODE(this->validate();) - sk_free(fPoints); - - SkDEBUGCODE(fPoints = NULL;) - SkDEBUGCODE(fVerbs = NULL;) - SkDEBUGCODE(fVerbCnt = 0x9999999;) - SkDEBUGCODE(fPointCnt = 0xAAAAAAA;) - SkDEBUGCODE(fPointCnt = 0xBBBBBBB;) - SkDEBUGCODE(fGenerationID = 0xEEEEEEEE;) - SkDEBUGCODE(fEditorsAttached = 0x7777777;) - } - + virtual ~SkPathRef(); int countPoints() const { SkDEBUGCODE(this->validate();) return fPointCnt; } int countVerbs() const { SkDEBUGCODE(this->validate();) return fVerbCnt; } int countWeights() const { SkDEBUGCODE(this->validate();) return fConicWeights.count(); } @@ -254,8 +277,18 @@ public: */ uint32_t genID() const; + struct GenIDChangeListener { + virtual ~GenIDChangeListener() {} + virtual void onChange() = 0; + }; + + void addGenIDChangeListener(GenIDChangeListener* listener); + + SkDEBUGCODE(void validate() const;) + private: enum SerializationOffsets { + kIsRRect_SerializationShift = 26, // requires 1 bit kIsFinite_SerializationShift = 25, // requires 1 bit kIsOval_SerializationShift = 24, // requires 1 bit kSegmentMask_SerializationShift = 0 // requires 4 bits @@ -271,6 +304,7 @@ private: fGenerationID = kEmptyGenID; fSegmentMask = 0; fIsOval = false; + fIsRRect = false; SkDEBUGCODE(fEditorsAttached = 0;) SkDEBUGCODE(this->validate();) } @@ -279,13 +313,7 @@ private: // Return true if the computed bounds are finite. static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { - int count = ref.countPoints(); - if (count <= 1) { // we ignore just 1 point (moveto) - bounds->setEmpty(); - return count ? ref.points()->isFinite() : true; - } else { - return bounds->setBoundsCheck(ref.points(), count); - } + return bounds->setBoundsCheck(ref.points(), ref.countPoints()); } // called, if dirty, by getBounds() @@ -293,9 +321,9 @@ private: SkDEBUGCODE(this->validate();) // TODO(mtklein): remove fBoundsIsDirty and fIsFinite, // using an inverted rect instead of fBoundsIsDirty and always recalculating fIsFinite. - //SkASSERT(fBoundsIsDirty); + SkASSERT(fBoundsIsDirty); - fIsFinite = ComputePtBounds(fBounds.get(), *this); + fIsFinite = ComputePtBounds(&fBounds, *this); fBoundsIsDirty = false; } @@ -303,7 +331,7 @@ private: SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom); fBounds = rect; fBoundsIsDirty = false; - fIsFinite = fBounds->isFinite(); + fIsFinite = fBounds.isFinite(); } /** Makes additional room but does not change the counts or change the genID */ @@ -324,6 +352,7 @@ private: fSegmentMask = 0; fIsOval = false; + fIsRRect = false; size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCount; size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * reservePoints; @@ -416,31 +445,35 @@ private: return reinterpret_cast(fVerbs) - reinterpret_cast(fPoints); } - SkDEBUGCODE(void validate() const;) - /** * Called the first time someone calls CreateEmpty to actually create the singleton. */ - static SkPathRef* CreateEmptyImpl(); + friend SkPathRef* sk_create_empty_pathref(); void setIsOval(bool isOval) { fIsOval = isOval; } + void setIsRRect(bool isRRect) { fIsRRect = isRRect; } + + // called only by the editor. Note that this is not a const function. SkPoint* getPoints() { SkDEBUGCODE(this->validate();) fIsOval = false; + fIsRRect = false; return fPoints; } + const SkPoint* getPoints() const { + SkDEBUGCODE(this->validate();) + return fPoints; + } + + void callGenIDChangeListeners(); + enum { kMinSize = 256, }; - mutable SkTRacyReffable fBounds; - mutable SkTRacy fBoundsIsDirty; - mutable SkTRacy fIsFinite; // only meaningful if bounds are valid - - SkBool8 fIsOval; - uint8_t fSegmentMask; + mutable SkRect fBounds; SkPoint* fPoints; // points to begining of the allocation uint8_t* fVerbs; // points just past the end of the allocation (verbs grow backwards) @@ -455,7 +488,17 @@ private: mutable uint32_t fGenerationID; SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use at any time. + SkTDArray fGenIDChangeListeners; // pointers are owned + + mutable uint8_t fBoundsIsDirty; + mutable SkBool8 fIsFinite; // only meaningful if bounds are valid + + SkBool8 fIsOval; + SkBool8 fIsRRect; + uint8_t fSegmentMask; + friend class PathRefTest_Private; + friend class ForceIsRRect_Private; // unit test isRRect typedef SkRefCnt INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkPicture.h b/gfx/skia/skia/include/core/SkPicture.h index 21ebef32cd66..720747e9a323 100644 --- a/gfx/skia/skia/include/core/SkPicture.h +++ b/gfx/skia/skia/include/core/SkPicture.h @@ -1,4 +1,3 @@ - /* * Copyright 2007 The Android Open Source Project * @@ -6,72 +5,33 @@ * found in the LICENSE file. */ - #ifndef SkPicture_DEFINED #define SkPicture_DEFINED -#include "SkBitmap.h" -#include "SkDrawPictureCallback.h" #include "SkImageDecoder.h" #include "SkRefCnt.h" -#include "SkTDArray.h" +#include "SkTypes.h" -#if SK_SUPPORT_GPU class GrContext; -#endif - -class SkBBHFactory; -class SkBBoxHierarchy; +class SkBigPicture; +class SkBitmap; class SkCanvas; -class SkData; class SkPictureData; -class SkPictureRecord; +class SkPixelSerializer; +class SkRefCntSet; class SkStream; +class SkTypefacePlayback; class SkWStream; - struct SkPictInfo; -class SkRecord; - /** \class SkPicture - The SkPicture class records the drawing commands made to a canvas, to - be played back at a later time. + An SkPicture records drawing commands made to a canvas to be played back at a later time. + This base class handles serialization and a few other miscellany. */ class SK_API SkPicture : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkPicture) - - // AccelData provides a base class for device-specific acceleration - // data. It is added to the picture via a call to a device's optimize - // method. - class AccelData : public SkRefCnt { - public: - typedef uint8_t Domain; - typedef uint32_t Key; - - AccelData(Key key) : fKey(key) { } - - const Key& getKey() const { return fKey; } - - // This entry point allows user's to get a unique domain prefix - // for their keys - static Domain GenerateDomain(); - private: - Key fKey; - - typedef SkRefCnt INHERITED; - }; - -#ifdef SK_SUPPORT_LEGACY_DEFAULT_PICTURE_CTOR - SkPicture(); -#endif - - /** PRIVATE / EXPERIMENTAL -- do not call */ - void EXPERIMENTAL_addAccelData(const AccelData*) const; - - /** PRIVATE / EXPERIMENTAL -- do not call */ - const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key) const; + virtual ~SkPicture(); /** * Function signature defining a function that sets up an SkBitmap from encoded data. On @@ -88,7 +48,7 @@ public: /** * Recreate a picture that was serialized into a stream. - * @param SkStream Serialized picture data. + * @param SkStream Serialized picture data. Ownership is unchanged by this call. * @param proc Function pointer for installing pixelrefs on SkBitmaps representing the * encoded bitmap data from the stream. * @return A new SkPicture representing the serialized data, or NULL if the stream is @@ -107,59 +67,45 @@ public: */ static SkPicture* CreateFromBuffer(SkReadBuffer&); - virtual ~SkPicture(); - -#ifdef SK_SUPPORT_LEGACY_PICTURE_CLONE /** - * Creates a thread-safe clone of the picture that is ready for playback. - */ - SkPicture* clone() const; -#endif + * Subclasses of this can be passed to playback(). During the playback + * of the picture, this callback will periodically be invoked. If its + * abort() returns true, then picture playback will be interrupted. + * + * The resulting drawing is undefined, as there is no guarantee how often the + * callback will be invoked. If the abort happens inside some level of nested + * calls to save(), restore will automatically be called to return the state + * to the same level it was before the playback call was made. + */ + class SK_API AbortCallback { + public: + AbortCallback() {} + virtual ~AbortCallback() {} + virtual bool abort() = 0; + }; - /** Replays the drawing commands on the specified canvas. + /** Replays the drawing commands on the specified canvas. Note that + this has the effect of unfurling this picture into the destination + canvas. Using the SkCanvas::drawPicture entry point gives the destination + canvas the option of just taking a ref. @param canvas the canvas receiving the drawing commands. + @param callback a callback that allows interruption of playback */ - void draw(SkCanvas* canvas, SkDrawPictureCallback* = NULL) const; + virtual void playback(SkCanvas*, AbortCallback* = NULL) const = 0; - /** Return the width of the picture's recording canvas. This - value reflects what was passed to setSize(), and does not necessarily - reflect the bounds of what has been recorded into the picture. - @return the width of the picture's recording canvas - */ - int width() const { return fWidth; } + /** Return a cull rect for this picture. + Ops recorded into this picture that attempt to draw outside the cull might not be drawn. + */ + virtual SkRect cullRect() const = 0; - /** Return the height of the picture's recording canvas. This - value reflects what was passed to setSize(), and does not necessarily - reflect the bounds of what has been recorded into the picture. - @return the height of the picture's recording canvas - */ - int height() const { return fHeight; } - - /** Return a non-zero, unique value representing the picture. This call is - only valid when not recording. Between a beginRecording/endRecording - pair it will just return 0 (the invalid ID). Each beginRecording/ - endRecording pair will cause a different generation ID to be returned. - */ + /** Returns a non-zero value unique among all pictures. */ uint32_t uniqueID() const; /** - * Function to encode an SkBitmap to an SkData. A function with this - * signature can be passed to serialize() and SkWriteBuffer. - * Returning NULL will tell the SkWriteBuffer to use - * SkBitmap::flatten() to store the bitmap. - * - * @param pixelRefOffset DEPRECATED -- caller assumes it will return 0. - * @return SkData If non-NULL, holds encoded data representing the passed - * in bitmap. The caller is responsible for calling unref(). + * Serialize to a stream. If non NULL, serializer will be used to serialize + * bitmaps and images in the picture. */ - typedef SkData* (*EncodeBitmap)(size_t* pixelRefOffset, const SkBitmap& bm); - - /** - * Serialize to a stream. If non NULL, encoder will be used to encode - * any bitmaps in the picture. - * encoder will never be called with a NULL pixelRefOffset. - */ - void serialize(SkWStream*, EncodeBitmap encoder = NULL) const; + void serialize(SkWStream*, SkPixelSerializer* = NULL) const; /** * Serialize to a buffer. @@ -170,7 +116,21 @@ public: * Returns true if any bitmaps may be produced when this SkPicture * is replayed. */ - bool willPlayBackBitmaps() const; + virtual bool willPlayBackBitmaps() const = 0; + + /** Return the approximate number of operations in this picture. This + * number may be greater or less than the number of SkCanvas calls + * recorded: some calls may be recorded as more than one operation, or some + * calls may be optimized away. + */ + virtual int approximateOpCount() const = 0; + + /** Return true if this picture contains text. + */ + virtual bool hasText() const = 0; + + /** Returns the approximate byte size of this picture, not including large ref'd objects. */ + virtual size_t approximateBytesUsed() const = 0; /** Return true if the SkStream/Buffer represents a serialized picture, and fills out SkPictInfo. After this function returns, the data source is not @@ -181,116 +141,67 @@ public: If false is returned, SkPictInfo is unmodified. */ static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*); - static bool InternalOnly_BufferIsSKP(SkReadBuffer&, SkPictInfo*); + static bool InternalOnly_BufferIsSKP(SkReadBuffer*, SkPictInfo*); - /** Return true if the picture is suitable for rendering on the GPU. - */ + /** Return true if the picture is suitable for rendering on the GPU. */ + bool suitableForGpuRasterization(GrContext*, const char** whyNot = NULL) const; -#if SK_SUPPORT_GPU - bool suitableForGpuRasterization(GrContext*, const char ** = NULL) const; -#endif + // Sent via SkMessageBus from destructor. + struct DeletionMessage { int32_t fUniqueID; }; // TODO: -> uint32_t? - class DeletionListener : public SkRefCnt { - public: - virtual void onDeletion(uint32_t pictureID) = 0; - }; + // Returns NULL if this is not an SkBigPicture. + virtual const SkBigPicture* asSkBigPicture() const { return NULL; } - // Takes ref on listener. - void addDeletionListener(DeletionListener* listener) const; + // Global setting to enable or disable security precautions for serialization. + static void SetPictureIOSecurityPrecautionsEnabled_Dangerous(bool set); + static bool PictureIOSecurityPrecautionsEnabled(); private: - // V2 : adds SkPixelRef's generation ID. - // V3 : PictInfo tag at beginning, and EOF tag at the end - // V4 : move SkPictInfo to be the header - // V5 : don't read/write FunctionPtr on cross-process (we can detect that) - // V6 : added serialization of SkPath's bounds (and packed its flags tighter) - // V7 : changed drawBitmapRect(IRect) to drawBitmapRectToRect(Rect) - // V8 : Add an option for encoding bitmaps - // V9 : Allow the reader and writer of an SKP disagree on whether to support - // SK_SUPPORT_HINTING_SCALE_FACTOR - // V10: add drawRRect, drawOval, clipRRect - // V11: modify how readBitmap and writeBitmap store their info. - // V12: add conics to SkPath, use new SkPathRef flattening - // V13: add flag to drawBitmapRectToRect - // parameterize blurs by sigma rather than radius - // V14: Add flags word to PathRef serialization - // V15: Remove A1 bitmap config (and renumber remaining configs) - // V16: Move SkPath's isOval flag to SkPathRef - // V17: SkPixelRef now writes SkImageInfo - // V18: SkBitmap now records x,y for its pixelref origin, instead of offset. - // V19: encode matrices and regions into the ops stream - // V20: added bool to SkPictureImageFilter's serialization (to allow SkPicture serialization) - // V21: add pushCull, popCull - // V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes - // V23: SkPaint::FilterLevel became a real enum - // V24: SkTwoPointConicalGradient now has fFlipped flag for gradient flipping - // V25: SkDashPathEffect now only writes phase and interval array when flattening - // V26: Removed boolean from SkColorShader for inheriting color from SkPaint. - // V27: Remove SkUnitMapper from gradients (and skia). - // V28: No longer call bitmap::flatten inside SkWriteBuffer::writeBitmap. - // V29: Removed SaveFlags parameter from save(). - // V30: Remove redundant SkMatrix from SkLocalMatrixShader. + // Subclass whitelist. + SkPicture(); + friend class SkBigPicture; + friend class SkEmptyPicture; + template friend class SkMiniPicture; - // Note: If the picture version needs to be increased then please follow the - // steps to generate new SKPs in (only accessible to Googlers): http://goo.gl/qATVcw + void serialize(SkWStream*, SkPixelSerializer*, SkRefCntSet* typefaces) const; + static SkPicture* CreateFromStream(SkStream*, + InstallPixelRefProc proc, + SkTypefacePlayback*); + friend class SkPictureData; + + virtual int numSlowPaths() const = 0; + friend struct SkPathCounter; + + // V35: Store SkRect (rather then width & height) in header + // V36: Remove (obsolete) alphatype from SkColorTable + // V37: Added shadow only option to SkDropShadowImageFilter (last version to record CLEAR) + // V38: Added PictureResolution option to SkPictureImageFilter + // V39: Added FilterLevel option to SkPictureImageFilter + // V40: Remove UniqueID serialization from SkImageFilter. + // V41: Added serialization of SkBitmapSource's filterQuality parameter + // V42: Added a bool to SkPictureShader serialization to indicate did-we-serialize-a-picture? + // V43: Added DRAW_IMAGE and DRAW_IMAGE_RECT opt codes to serialized data // Only SKPs within the min/current picture version range (inclusive) can be read. - static const uint32_t MIN_PICTURE_VERSION = 19; - static const uint32_t CURRENT_PICTURE_VERSION = 30; + static const uint32_t MIN_PICTURE_VERSION = 35; // Produced by Chrome M39. + static const uint32_t CURRENT_PICTURE_VERSION = 43; - mutable uint32_t fUniqueID; + static_assert(MIN_PICTURE_VERSION <= 41, + "Remove kFontFileName and related code from SkFontDescriptor.cpp."); - // TODO: make SkPictureData const when clone method goes away - SkAutoTDelete fData; - int fWidth, fHeight; - mutable SkAutoTUnref fAccelData; + static_assert(MIN_PICTURE_VERSION <= 42, + "Remove COMMENT API handlers from SkPicturePlayback.cpp"); - mutable SkTDArray fDeletionListeners; // pointers are refed + static_assert(MIN_PICTURE_VERSION <= 43, + "Remove SkBitmapSourceDeserializer."); - void needsNewGenID() { fUniqueID = SK_InvalidGenID; } - void callDeletionListeners(); - - // Create a new SkPicture from an existing SkPictureData. The new picture - // takes ownership of 'data'. - SkPicture(SkPictureData* data, int width, int height); - - SkPicture(int width, int height, const SkPictureRecord& record, bool deepCopyOps); - - // An OperationList encapsulates a set of operation offsets into the picture byte - // stream along with the CTMs needed for those operation. - class OperationList : ::SkNoncopyable { - public: - // The following three entry points should only be accessed if - // 'valid' returns true. - int numOps() const { return fOps.count(); } - // The offset in the picture of the operation to execute. - uint32_t offset(int index) const; - // The CTM that must be installed for the operation to behave correctly - const SkMatrix& matrix(int index) const; - - SkTDArray fOps; - }; - - /** PRIVATE / EXPERIMENTAL -- do not call - Return the operations required to render the content inside 'queryRect'. - */ - const OperationList* EXPERIMENTAL_getActiveOps(const SkIRect& queryRect) const; - - void createHeader(SkPictInfo* info) const; static bool IsValidPictInfo(const SkPictInfo& info); + static SkPicture* Forwardport(const SkPictInfo&, const SkPictureData*); - friend class SkPictureData; // to access OperationList - friend class SkPictureRecorder; // just for SkPicture-based constructor - friend class SkGpuDevice; // for EXPERIMENTAL_getActiveOps/OperationList - friend class GrGatherCanvas; // needs to know if old or new picture - friend class SkPicturePlayback; // to get fData & OperationList - friend class SkPictureReplacementPlayback; // to access OperationList + SkPictInfo createHeader() const; + SkPictureData* backport() const; - typedef SkRefCnt INHERITED; - - SkPicture(int width, int height, SkRecord*); // Takes ownership. - SkAutoTDelete fRecord; - bool fRecordWillPlayBackBitmaps; // TODO: const + mutable uint32_t fUniqueID; }; #endif diff --git a/gfx/skia/skia/include/core/SkPictureRecorder.h b/gfx/skia/skia/include/core/SkPictureRecorder.h index bd22d5560647..6f95860b70af 100644 --- a/gfx/skia/skia/include/core/SkPictureRecorder.h +++ b/gfx/skia/skia/include/core/SkPictureRecorder.h @@ -8,6 +8,7 @@ #ifndef SkPictureRecorder_DEFINED #define SkPictureRecorder_DEFINED +#include "../private/SkMiniRecorder.h" #include "SkBBHFactory.h" #include "SkPicture.h" #include "SkRefCnt.h" @@ -19,6 +20,7 @@ namespace android { #endif class SkCanvas; +class SkDrawable; class SkPictureRecord; class SkRecord; class SkRecorder; @@ -28,42 +30,75 @@ public: SkPictureRecorder(); ~SkPictureRecorder(); + enum RecordFlags { + // This flag indicates that, if some BHH is being computed, saveLayer + // information should also be extracted at the same time. + kComputeSaveLayerInfo_RecordFlag = 0x01, + + // If you call drawPicture() or drawDrawable() on the recording canvas, this flag forces + // that object to playback its contents immediately rather than reffing the object. + kPlaybackDrawPicture_RecordFlag = 0x02, + }; + /** Returns the canvas that records the drawing commands. - @param width the base width for the picture, as if the recording - canvas' bitmap had this width. - @param height the base width for the picture, as if the recording - canvas' bitmap had this height. + @param bounds the cull rect used when recording this picture. Any drawing the falls outside + of this rect is undefined, and may be drawn or it may not. @param bbhFactory factory to create desired acceleration structure @param recordFlags optional flags that control recording. @return the canvas. */ - SkCanvas* beginRecording(int width, int height, + SkCanvas* beginRecording(const SkRect& bounds, SkBBHFactory* bbhFactory = NULL, uint32_t recordFlags = 0); - /** Same as beginRecording(), using a new faster backend. */ - SkCanvas* EXPERIMENTAL_beginRecording(int width, int height, - SkBBHFactory* bbhFactory = NULL); + SkCanvas* beginRecording(SkScalar width, SkScalar height, + SkBBHFactory* bbhFactory = NULL, + uint32_t recordFlags = 0) { + return this->beginRecording(SkRect::MakeWH(width, height), bbhFactory, recordFlags); + } /** Returns the recording canvas if one is active, or NULL if recording is not active. This does not alter the refcnt on the canvas (if present). */ SkCanvas* getRecordingCanvas(); - /** Signal that the caller is done recording. This invalidates the canvas - returned by beginRecording/getRecordingCanvas, and returns the - created SkPicture. Note that the returned picture has its creation - ref which the caller must take ownership of. - */ - SkPicture* endRecording(); + /** + * Signal that the caller is done recording. This invalidates the canvas returned by + * beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who + * must call unref() when they are done using it. + * + * The returned picture is immutable. If during recording drawables were added to the canvas, + * these will have been "drawn" into a recording canvas, so that this resulting picture will + * reflect their current state, but will not contain a live reference to the drawables + * themselves. + */ + SkPicture* SK_WARN_UNUSED_RESULT endRecordingAsPicture(); - /** Enable/disable all the picture recording optimizations (i.e., - those in SkPictureRecord). It is mainly intended for testing the - existing optimizations (i.e., to actually have the pattern - appear in an .skp we have to disable the optimization). Call right - after 'beginRecording'. - */ - void internalOnly_EnableOpts(bool enableOpts); + /** + * Signal that the caller is done recording, and update the cull rect to use for bounding + * box hierarchy (BBH) generation. The behavior is the same as calling + * endRecordingAsPicture(), except that this method updates the cull rect initially passed + * into beginRecording. + * @param cullRect the new culling rectangle to use as the overall bound for BBH generation + * and subsequent culling operations. + * @return the picture containing the recorded content. + */ + SkPicture* SK_WARN_UNUSED_RESULT endRecordingAsPicture(const SkRect& cullRect); + + /** + * Signal that the caller is done recording. This invalidates the canvas returned by + * beginRecording/getRecordingCanvas. Ownership of the object is passed to the caller, who + * must call unref() when they are done using it. + * + * Unlike endRecordingAsPicture(), which returns an immutable picture, the returned drawable + * may contain live references to other drawables (if they were added to the recording canvas) + * and therefore this drawable will reflect the current state of those nested drawables anytime + * it is drawn or a new picture is snapped from it (by calling drawable->newPictureSnapshot()). + */ + SkDrawable* SK_WARN_UNUSED_RESULT endRecordingAsDrawable(); + + // Legacy API -- use endRecordingAsPicture instead. + SkPicture* SK_WARN_UNUSED_RESULT endRecording() { return this->endRecordingAsPicture(); } private: void reset(); @@ -77,15 +112,13 @@ private: friend class SkPictureRecorderReplayTester; // for unit testing void partialReplay(SkCanvas* canvas) const; - int fWidth; - int fHeight; - - // One of these two canvases will be non-NULL. - SkAutoTUnref fPictureRecord; // beginRecording() - SkAutoTUnref fRecorder; // EXPERIMENTAL_beginRecording() - - // Used by EXPERIMENTAL_beginRecording(). - SkAutoTDelete fRecord; + bool fActivelyRecording; + uint32_t fFlags; + SkRect fCullRect; + SkAutoTUnref fBBH; + SkAutoTUnref fRecorder; + SkAutoTUnref fRecord; + SkMiniRecorder fMiniRecorder; typedef SkNoncopyable INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkPixelRef.h b/gfx/skia/skia/include/core/SkPixelRef.h index afab7fad9e04..4591ed82bffb 100644 --- a/gfx/skia/skia/include/core/SkPixelRef.h +++ b/gfx/skia/skia/include/core/SkPixelRef.h @@ -8,36 +8,23 @@ #ifndef SkPixelRef_DEFINED #define SkPixelRef_DEFINED +#include "../private/SkAtomics.h" #include "SkBitmap.h" -#include "SkDynamicAnnotations.h" -#include "SkRefCnt.h" -#include "SkString.h" +#include "SkFilterQuality.h" #include "SkImageInfo.h" +#include "../private/SkMutex.h" +#include "SkPixmap.h" +#include "SkRefCnt.h" #include "SkSize.h" +#include "SkString.h" #include "SkTDArray.h" -//#define xed - -#ifdef SK_DEBUG - /** - * Defining SK_IGNORE_PIXELREF_SETPRELOCKED will force all pixelref - * subclasses to correctly handle lock/unlock pixels. For performance - * reasons, simple malloc-based subclasses call setPreLocked() to skip - * the overhead of implementing these calls. - * - * This build-flag disables that optimization, to add in debugging our - * call-sites, to ensure that they correctly balance their calls of - * lock and unlock. - */ -// #define SK_IGNORE_PIXELREF_SETPRELOCKED -#endif - class SkColorTable; class SkData; struct SkIRect; -class SkMutex; class GrTexture; +class SkDiscardableMemory; /** \class SkPixelRef @@ -49,10 +36,7 @@ class GrTexture; */ class SK_API SkPixelRef : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkPixelRef) - explicit SkPixelRef(const SkImageInfo&); - SkPixelRef(const SkImageInfo&, SkBaseMutex* mutex); virtual ~SkPixelRef(); const SkImageInfo& info() const { @@ -75,6 +59,8 @@ public: * Calling lockPixels returns a LockRec struct (on success). */ struct LockRec { + LockRec() : fPixels(NULL), fColorTable(NULL) {} + void* fPixels; SkColorTable* fColorTable; size_t fRowBytes; @@ -86,11 +72,7 @@ public: } }; - /** - * Returns true if the lockcount > 0 - */ - bool isLocked() const { return fLockCount > 0; } - + SkDEBUGCODE(bool isLocked() const { return fLockCount > 0; }) SkDEBUGCODE(int getLockCount() const { return fLockCount; }) /** @@ -127,6 +109,18 @@ public: */ uint32_t getGenerationID() const; +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + /** Returns a non-zero, unique value corresponding to this SkPixelRef. + Unlike the generation ID, this ID remains the same even when the pixels + are changed. IDs are not reused (until uint32_t wraps), so it is safe + to consider this ID unique even after this SkPixelRef is deleted. + + Can be used as a key which uniquely identifies this SkPixelRef + regardless of changes to its pixels or deletion of this object. + */ + uint32_t getStableID() const { return fStableID; } +#endif + /** * Call this if you have changed the contents of the pixels. This will in- * turn cause a different generation ID value to be returned from @@ -144,7 +138,7 @@ public: /** Returns true if this pixelref is marked as immutable, meaning that the contents of its pixels will not change for the lifetime of the pixelref. */ - bool isImmutable() const { return fIsImmutable; } + bool isImmutable() const { return fMutability != kMutable; } /** Marks this pixelref is immutable, meaning that the contents of its pixels will not change for the lifetime of the pixelref. This state can @@ -185,36 +179,31 @@ public: return this->onRefEncodedData(); } - /** - * Experimental -- tells the caller if it is worth it to call decodeInto(). - * Just an optimization at this point, to avoid checking the cache first. - * We may remove/change this call in the future. - */ - bool implementsDecodeInto() { - return this->onImplementsDecodeInto(); - } + struct LockRequest { + SkISize fSize; + SkFilterQuality fQuality; + }; - /** - * Return a decoded instance of this pixelRef in bitmap. If this cannot be - * done, return false and the bitmap parameter is ignored/unchanged. - * - * pow2 is the requeste power-of-two downscale that the caller needs. This - * can be ignored, and the "original" size can be returned, but if the - * underlying codec can efficiently return a smaller size, that should be - * done. Some examples: - * - * To request the "base" version (original scale), pass 0 for pow2 - * To request 1/2 scale version (1/2 width, 1/2 height), pass 1 for pow2 - * To request 1/4 scale version (1/4 width, 1/4 height), pass 2 for pow2 - * ... - * - * If this returns true, then bitmap must be "locked" such that - * bitmap->getPixels() will return the correct address. - */ - bool decodeInto(int pow2, SkBitmap* bitmap) { - SkASSERT(pow2 >= 0); - return this->onDecodeInto(pow2, bitmap); - } + struct LockResult { + LockResult() : fPixels(NULL), fCTable(NULL) {} + + void (*fUnlockProc)(void* ctx); + void* fUnlockContext; + + const void* fPixels; + SkColorTable* fCTable; // should be NULL unless colortype is kIndex8 + size_t fRowBytes; + SkISize fSize; + + void unlock() { + if (fUnlockProc) { + fUnlockProc(fUnlockContext); + fUnlockProc = NULL; // can't unlock twice! + } + } + }; + + bool requestLock(const LockRequest&, LockResult*); /** Are we really wrapping a texture instead of a bitmap? */ @@ -227,9 +216,13 @@ public: * If all planes and rowBytes are not NULL, then it should copy the associated Y,U,V data * into those planes of memory supplied by the caller. It should validate that the sizes * match what it expected. If the sizes do not match, it should return false. + * + * If colorSpace is not NULL, the YUV color space of the data should be stored in the address + * it points at. */ - bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]) { - return this->onGetYUV8Planes(sizes, planes, rowBytes); + bool getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], + SkYUVColorSpace* colorSpace) { + return this->onGetYUV8Planes(sizes, planes, rowBytes, colorSpace); } bool readPixels(SkBitmap* dst, const SkIRect* subset = NULL); @@ -237,32 +230,17 @@ public: /** * Makes a deep copy of this PixelRef, respecting the requested config. * @param colorType Desired colortype. + * @param profileType Desired colorprofiletype. * @param subset Subset of this PixelRef to copy. Must be fully contained within the bounds of * of this PixelRef. * @return A new SkPixelRef, or NULL if either there is an error (e.g. the destination could * not be created with the given config), or this PixelRef does not support deep * copies. */ - virtual SkPixelRef* deepCopy(SkColorType colortype, const SkIRect* subset) { + virtual SkPixelRef* deepCopy(SkColorType, SkColorProfileType, const SkIRect* /*subset*/) { return NULL; } -#ifdef SK_BUILD_FOR_ANDROID - /** - * Acquire a "global" ref on this object. - * The default implementation just calls ref(), but subclasses can override - * this method to implement additional behavior. - */ - virtual void globalRef(void* data=NULL); - - /** - * Release a "global" ref on this object. - * The default implementation just calls unref(), but subclasses can override - * this method to implement additional behavior. - */ - virtual void globalUnref(); -#endif - // Register a listener that may be called the next time our generation ID changes. // // We'll only call the listener if we're confident that we are the only SkPixelRef with this @@ -279,6 +257,19 @@ public: // Takes ownership of listener. void addGenIDChangeListener(GenIDChangeListener* listener); + // Call when this pixelref is part of the key to a resourcecache entry. This allows the cache + // to know automatically those entries can be purged when this pixelref is changed or deleted. + void notifyAddedToCache() { + fAddedToCache.store(true); + } + + virtual SkDiscardableMemory* diagnostic_only_getDiscardable() const { return NULL; } + + /** + * Returns true if the pixels are generated on-the-fly (when required). + */ + bool isLazyGenerated() const { return this->onIsLazyGenerated(); } + protected: /** * On success, returns true and fills out the LockRec for the pixels. On @@ -302,11 +293,6 @@ protected: /** Default impl returns true */ virtual bool onLockPixelsAreWritable() const; - // returns false; - virtual bool onImplementsDecodeInto(); - // returns false; - virtual bool onDecodeInto(int pow2, SkBitmap* bitmap); - /** * For pixelrefs that don't have access to their raw pixels, they may be * able to make a copy of them (e.g. if the pixels are on the GPU). @@ -318,8 +304,12 @@ protected: // default impl returns NULL. virtual SkData* onRefEncodedData(); + // default impl does nothing. + virtual void onNotifyPixelsChanged(); + // default impl returns false. - virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3]); + virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3], + SkYUVColorSpace* colorSpace); /** * Returns the size (in bytes) of the internally allocated memory. @@ -331,10 +321,14 @@ protected: */ virtual size_t getAllocatedSizeInBytes() const; + virtual bool onRequestLock(const LockRequest&, LockResult*); + + virtual bool onIsLazyGenerated() const { return false; } + /** Return the mutex associated with this pixelref. This value is assigned in the constructor, and cannot change during the lifetime of the object. */ - SkBaseMutex* mutex() const { return fMutex; } + SkBaseMutex* mutex() const { return &fMutex; } // only call from constructor. Flags this to always be locked, removing // the need to grab the mutex and call onLockPixels/onUnlockPixels. @@ -342,7 +336,7 @@ protected: void setPreLocked(void*, size_t rowBytes, SkColorTable*); private: - SkBaseMutex* fMutex; // must remain in scope for the life of this object + mutable SkMutex fMutex; // mostly const. fInfo.fAlpahType can be changed at runtime. const SkImageInfo fInfo; @@ -351,28 +345,51 @@ private: LockRec fRec; int fLockCount; - mutable SkTRacy fGenerationID; - mutable SkTRacy fUniqueGenerationID; + bool lockPixelsInsideMutex(); + + // Bottom bit indicates the Gen ID is unique. + bool genIDIsUnique() const { return SkToBool(fTaggedGenID.load() & 1); } + mutable SkAtomic fTaggedGenID; + +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + const uint32_t fStableID; +#endif SkTDArray fGenIDChangeListeners; // pointers are owned SkString fURI; - // can go from false to true, but never from true to false - bool fIsImmutable; + // Set true by caches when they cache content that's derived from the current pixels. + SkAtomic fAddedToCache; + + enum { + kMutable, // PixelRefs begin mutable. + kTemporarilyImmutable, // Considered immutable, but can revert to mutable. + kImmutable, // Once set to this state, it never leaves. + } fMutability : 8; // easily fits inside a byte + // only ever set in constructor, const after that - bool fPreLocked; + bool fPreLocked; void needsNewGenID(); void callGenIDChangeListeners(); - void setMutex(SkBaseMutex* mutex); + void setTemporarilyImmutable(); + void restoreMutability(); + friend class SkSurface_Raster; // For the two methods above. + + bool isPreLocked() const { return fPreLocked; } + friend class SkImage_Raster; // When copying a bitmap to another with the same shape and config, we can safely // clone the pixelref generation ID too, which makes them equivalent under caching. friend class SkBitmap; // only for cloneGenID void cloneGenID(const SkPixelRef&); + void setImmutableWithID(uint32_t genID); + friend class SkImage_Gpu; + friend class SkImageCacherator; + typedef SkRefCnt INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkPixelSerializer.h b/gfx/skia/skia/include/core/SkPixelSerializer.h new file mode 100644 index 000000000000..d08920990981 --- /dev/null +++ b/gfx/skia/skia/include/core/SkPixelSerializer.h @@ -0,0 +1,52 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPixelSerializer_DEFINED +#define SkPixelSerializer_DEFINED + +#include "SkRefCnt.h" + +class SkData; +struct SkImageInfo; + +/** + * Interface for serializing pixels, e.g. SkBitmaps in an SkPicture. + */ +class SkPixelSerializer : public SkRefCnt { +public: + virtual ~SkPixelSerializer() {} + + /** + * Call to determine if the client wants to serialize the encoded data. If + * false, serialize another version (e.g. the result of encodePixels). + */ + bool useEncodedData(const void* data, size_t len) { + return this->onUseEncodedData(data, len); + } + + /** + * Call to get the client's version of encoding these pixels. If it + * returns NULL, serialize the raw pixels. + */ + SkData* encodePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes) { + return this->onEncodePixels(info, pixels, rowBytes); + } + +protected: + /** + * Return true if you want to serialize the encoded data, false if you want + * another version serialized (e.g. the result of encodePixels). + */ + virtual bool onUseEncodedData(const void* data, size_t len) = 0; + + /** + * If you want to encode these pixels, return the encoded data as an SkData + * Return null if you want to serialize the raw pixels. + */ + virtual SkData* onEncodePixels(const SkImageInfo&, const void* pixels, size_t rowBytes) = 0; +}; +#endif // SkPixelSerializer_DEFINED diff --git a/gfx/skia/skia/include/core/SkPixmap.h b/gfx/skia/skia/include/core/SkPixmap.h new file mode 100644 index 000000000000..da97025cab03 --- /dev/null +++ b/gfx/skia/skia/include/core/SkPixmap.h @@ -0,0 +1,265 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPixmap_DEFINED +#define SkPixmap_DEFINED + +#include "SkColor.h" +#include "SkFilterQuality.h" +#include "SkImageInfo.h" + +class SkColorTable; +struct SkMask; + +/** + * Pairs SkImageInfo with actual pixels and rowbytes. This class does not try to manage the + * lifetime of the pixel memory (nor the colortable if provided). + */ +class SK_API SkPixmap { +public: + SkPixmap() + : fPixels(NULL), fCTable(NULL), fRowBytes(0), fInfo(SkImageInfo::MakeUnknown(0, 0)) + {} + + SkPixmap(const SkImageInfo& info, const void* addr, size_t rowBytes, + SkColorTable* ctable = NULL) + : fPixels(addr), fCTable(ctable), fRowBytes(rowBytes), fInfo(info) + { + if (kIndex_8_SkColorType == info.colorType()) { + SkASSERT(ctable); + } else { + SkASSERT(NULL == ctable); + } + } + + void reset(); + void reset(const SkImageInfo& info, const void* addr, size_t rowBytes, + SkColorTable* ctable = NULL); + void reset(const SkImageInfo& info) { + this->reset(info, NULL, 0, NULL); + } + + /** + * If supported, set this pixmap to point to the pixels in the specified mask and return true. + * On failure, return false and set this pixmap to empty. + */ + bool SK_WARN_UNUSED_RESULT reset(const SkMask&); + + /** + * Computes the intersection of area and this pixmap. If that intersection is non-empty, + * set subset to that intersection and return true. + * + * On failure, return false and ignore the subset parameter. + */ + bool SK_WARN_UNUSED_RESULT extractSubset(SkPixmap* subset, const SkIRect& area) const; + + const SkImageInfo& info() const { return fInfo; } + size_t rowBytes() const { return fRowBytes; } + const void* addr() const { return fPixels; } + SkColorTable* ctable() const { return fCTable; } + + int width() const { return fInfo.width(); } + int height() const { return fInfo.height(); } + SkColorType colorType() const { return fInfo.colorType(); } + SkAlphaType alphaType() const { return fInfo.alphaType(); } + bool isOpaque() const { return fInfo.isOpaque(); } + + SkIRect bounds() const { return SkIRect::MakeWH(this->width(), this->height()); } + + uint64_t getSize64() const { return sk_64_mul(fInfo.height(), fRowBytes); } + uint64_t getSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); } + size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); } + + const uint32_t* addr32() const { + SkASSERT(4 == SkColorTypeBytesPerPixel(fInfo.colorType())); + return reinterpret_cast(fPixels); + } + + const uint16_t* addr16() const { + SkASSERT(2 == SkColorTypeBytesPerPixel(fInfo.colorType())); + return reinterpret_cast(fPixels); + } + + const uint8_t* addr8() const { + SkASSERT(1 == SkColorTypeBytesPerPixel(fInfo.colorType())); + return reinterpret_cast(fPixels); + } + + const uint32_t* addr32(int x, int y) const { + SkASSERT((unsigned)x < (unsigned)fInfo.width()); + SkASSERT((unsigned)y < (unsigned)fInfo.height()); + return (const uint32_t*)((const char*)this->addr32() + y * fRowBytes + (x << 2)); + } + const uint16_t* addr16(int x, int y) const { + SkASSERT((unsigned)x < (unsigned)fInfo.width()); + SkASSERT((unsigned)y < (unsigned)fInfo.height()); + return (const uint16_t*)((const char*)this->addr16() + y * fRowBytes + (x << 1)); + } + const uint8_t* addr8(int x, int y) const { + SkASSERT((unsigned)x < (unsigned)fInfo.width()); + SkASSERT((unsigned)y < (unsigned)fInfo.height()); + return (const uint8_t*)((const char*)this->addr8() + y * fRowBytes + (x << 0)); + } + const void* addr(int x, int y) const { + return (const char*)fPixels + fInfo.computeOffset(x, y, fRowBytes); + } + + // Writable versions + + void* writable_addr() const { return const_cast(fPixels); } + uint32_t* writable_addr32(int x, int y) const { + return const_cast(this->addr32(x, y)); + } + uint16_t* writable_addr16(int x, int y) const { + return const_cast(this->addr16(x, y)); + } + uint8_t* writable_addr8(int x, int y) const { + return const_cast(this->addr8(x, y)); + } + + // copy methods + + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + int srcX, int srcY) const; + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes) const { + return this->readPixels(dstInfo, dstPixels, dstRowBytes, 0, 0); + } + bool readPixels(const SkPixmap& dst, int srcX, int srcY) const { + return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), srcX, srcY); + } + bool readPixels(const SkPixmap& dst) const { + return this->readPixels(dst.info(), dst.writable_addr(), dst.rowBytes(), 0, 0); + } + + /** + * Copy the pixels from this pixmap into the dst pixmap, converting as needed into dst's + * colortype/alphatype. If the conversion cannot be performed, false is returned. + * + * If dst's dimensions differ from the src dimension, the image will be scaled, applying the + * specified filter-quality. + */ + bool scalePixels(const SkPixmap& dst, SkFilterQuality) const; + + /** + * Returns true if pixels were written to (e.g. if colorType is kUnknown_SkColorType, this + * will return false). If subset does not intersect the bounds of this pixmap, returns false. + */ + bool erase(SkColor, const SkIRect& subset) const; + + bool erase(SkColor color) const { return this->erase(color, this->bounds()); } + +private: + const void* fPixels; + SkColorTable* fCTable; + size_t fRowBytes; + SkImageInfo fInfo; +}; + +///////////////////////////////////////////////////////////////////////////////////////////// + +class SK_API SkAutoPixmapStorage : public SkPixmap { +public: + SkAutoPixmapStorage(); + ~SkAutoPixmapStorage(); + + /** + * Try to allocate memory for the pixels needed to match the specified Info. On success + * return true and fill out the pixmap to point to that memory. The storage will be freed + * when this object is destroyed, or if another call to tryAlloc() or alloc() is made. + * + * On failure, return false and reset() the pixmap to empty. + */ + bool tryAlloc(const SkImageInfo&); + + /** + * Allocate memory for the pixels needed to match the specified Info and fill out the pixmap + * to point to that memory. The storage will be freed when this object is destroyed, + * or if another call to tryAlloc() or alloc() is made. + * + * If the memory cannot be allocated, calls sk_throw(). + */ + void alloc(const SkImageInfo&); + + // We wrap these so we can clear our internal storage + + void reset() { + this->freeStorage(); + this->INHERITED::reset(); + } + void reset(const SkImageInfo& info, const void* addr, size_t rb, SkColorTable* ctable = NULL) { + this->freeStorage(); + this->INHERITED::reset(info, addr, rb, ctable); + } + void reset(const SkImageInfo& info) { + this->freeStorage(); + this->INHERITED::reset(info); + } + bool SK_WARN_UNUSED_RESULT reset(const SkMask& mask) { + this->freeStorage(); + return this->INHERITED::reset(mask); + } + +private: + void* fStorage; + + void freeStorage() { + sk_free(fStorage); + fStorage = NULL; + } + + typedef SkPixmap INHERITED; +}; + +///////////////////////////////////////////////////////////////////////////////////////////// + +class SK_API SkAutoPixmapUnlock : ::SkNoncopyable { +public: + SkAutoPixmapUnlock() : fUnlockProc(NULL), fIsLocked(false) {} + SkAutoPixmapUnlock(const SkPixmap& pm, void (*unlock)(void*), void* ctx) + : fUnlockProc(unlock), fUnlockContext(ctx), fPixmap(pm), fIsLocked(true) + {} + ~SkAutoPixmapUnlock() { this->unlock(); } + + /** + * Return the currently locked pixmap. Undefined if it has been unlocked. + */ + const SkPixmap& pixmap() const { + SkASSERT(this->isLocked()); + return fPixmap; + } + + bool isLocked() const { return fIsLocked; } + + /** + * Unlocks the pixmap. Can safely be called more than once as it will only call the underlying + * unlock-proc once. + */ + void unlock() { + if (fUnlockProc) { + SkASSERT(fIsLocked); + fUnlockProc(fUnlockContext); + fUnlockProc = NULL; + fIsLocked = false; + } + } + + /** + * If there is a currently locked pixmap, unlock it, then copy the specified pixmap + * and (optional) unlock proc/context. + */ + void reset(const SkPixmap& pm, void (*unlock)(void*), void* ctx); + +private: + void (*fUnlockProc)(void*); + void* fUnlockContext; + SkPixmap fPixmap; + bool fIsLocked; + + friend class SkBitmap; +}; + +#endif diff --git a/gfx/skia/skia/include/core/SkPngChunkReader.h b/gfx/skia/skia/include/core/SkPngChunkReader.h new file mode 100644 index 000000000000..f424dd8cfc2b --- /dev/null +++ b/gfx/skia/skia/include/core/SkPngChunkReader.h @@ -0,0 +1,45 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPngChunkReader_DEFINED +#define SkPngChunkReader_DEFINED + +#include "SkTypes.h" +#include "SkRefCnt.h" + +/** + * SkPngChunkReader + * + * Base class for optional callbacks to retrieve meta/chunk data out of a PNG + * encoded image as it is being decoded. + * Used by SkImageDecoder and SkCodec. + */ +class SkPngChunkReader : public SkRefCnt { +public: + /** + * This will be called by the decoder when it sees an unknown chunk. + * + * Use by SkCodec: + * Depending on the location of the unknown chunks, this callback may be + * called by + * - the factory (NewFromStream/NewFromData) + * - getPixels + * - startScanlineDecode + * - the first call to getScanlines/skipScanlines + * The callback may be called from a different thread (e.g. if the SkCodec + * is passed to another thread), and it may be called multiple times, if + * the SkCodec is used multiple times. + * + * @param tag Name for this type of chunk. + * @param data Data to be interpreted by the subclass. + * @param length Number of bytes of data in the chunk. + * @return true to continue decoding, or false to indicate an error, which + * will cause the decoder to not return the image. + */ + virtual bool readChunk(const char tag[], const void* data, size_t length) = 0; +}; +#endif // SkPngChunkReader_DEFINED diff --git a/gfx/skia/skia/include/core/SkPoint.h b/gfx/skia/skia/include/core/SkPoint.h index 8a0480ae7304..52d01ae88ce5 100644 --- a/gfx/skia/skia/include/core/SkPoint.h +++ b/gfx/skia/skia/include/core/SkPoint.h @@ -212,7 +212,16 @@ struct SK_API SkPoint { v[2].set(r, b); v[3].set(r, t); } - void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b, size_t stride); + + void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b, size_t stride) { + SkASSERT(stride >= sizeof(SkPoint)); + + ((SkPoint*)((intptr_t)this + 0 * stride))->set(l, t); + ((SkPoint*)((intptr_t)this + 1 * stride))->set(l, b); + ((SkPoint*)((intptr_t)this + 2 * stride))->set(r, b); + ((SkPoint*)((intptr_t)this + 3 * stride))->set(r, t); + } + static void Offset(SkPoint points[], int count, const SkPoint& offset) { Offset(points, count, offset.fX, offset.fY); @@ -249,25 +258,25 @@ struct SK_API SkPoint { /** Set the point (vector) to be unit-length in the same direction as it already points. If the point has a degenerate length (i.e. nearly 0) - then return false and do nothing; otherwise return true. + then set it to (0,0) and return false; otherwise return true. */ bool normalize(); /** Set the point (vector) to be unit-length in the same direction as the x,y params. If the vector (x,y) has a degenerate length (i.e. nearly 0) - then return false and do nothing, otherwise return true. + then set it to (0,0) and return false, otherwise return true. */ bool setNormalize(SkScalar x, SkScalar y); /** Scale the point (vector) to have the specified length, and return that length. If the original length is degenerately small (nearly zero), - do nothing and return false, otherwise return true. + set it to (0,0) and return false, otherwise return true. */ bool setLength(SkScalar length); /** Set the point (vector) to have the specified length in the same direction as (x,y). If the vector (x,y) has a degenerate length - (i.e. nearly 0) then return false and do nothing, otherwise return true. + (i.e. nearly 0) then set it to (0,0) and return false, otherwise return true. */ bool setLength(SkScalar x, SkScalar y, SkScalar length); @@ -339,6 +348,16 @@ struct SK_API SkPoint { fY -= v.fY; } + SkPoint operator*(SkScalar scale) const { + return Make(fX * scale, fY * scale); + } + + SkPoint& operator*=(SkScalar scale) { + fX *= scale; + fY *= scale; + return *this; + } + /** * Returns true if both X and Y are finite (not infinity or NaN) */ @@ -414,7 +433,7 @@ struct SK_API SkPoint { static SkScalar Length(SkScalar x, SkScalar y); /** Normalize pt, returning its previous length. If the prev length is too - small (degenerate), return 0 and leave pt unchanged. This uses the same + small (degenerate), set pt to (0,0) and return 0. This uses the same tolerance as CanNormalize. Note that this method may be significantly more expensive than diff --git a/gfx/skia/skia/include/core/SkPoint3.h b/gfx/skia/skia/include/core/SkPoint3.h new file mode 100644 index 000000000000..af24a8df58ea --- /dev/null +++ b/gfx/skia/skia/include/core/SkPoint3.h @@ -0,0 +1,124 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPoint3_DEFINED +#define SkPoint3_DEFINED + +#include "SkScalar.h" + +struct SK_API SkPoint3 { + SkScalar fX, fY, fZ; + + static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z) { + SkPoint3 pt; + pt.set(x, y, z); + return pt; + } + + SkScalar x() const { return fX; } + SkScalar y() const { return fY; } + SkScalar z() const { return fZ; } + + void set(SkScalar x, SkScalar y, SkScalar z) { fX = x; fY = y; fZ = z; } + + friend bool operator==(const SkPoint3& a, const SkPoint3& b) { + return a.fX == b.fX && a.fY == b.fY && a.fZ == b.fZ; + } + + friend bool operator!=(const SkPoint3& a, const SkPoint3& b) { + return !(a == b); + } + + /** Returns the Euclidian distance from (0,0,0) to (x,y,z) + */ + static SkScalar Length(SkScalar x, SkScalar y, SkScalar z); + + /** Return the Euclidian distance from (0,0,0) to the point + */ + SkScalar length() const { return SkPoint3::Length(fX, fY, fZ); } + + /** Set the point (vector) to be unit-length in the same direction as it + already points. If the point has a degenerate length (i.e., nearly 0) + then set it to (0,0,0) and return false; otherwise return true. + */ + bool normalize(); + + /** Return a new point whose X, Y and Z coordinates are scaled. + */ + SkPoint3 makeScale(SkScalar scale) const { + SkPoint3 p; + p.set(scale * fX, scale * fY, scale * fZ); + return p; + } + + /** Scale the point's coordinates by scale. + */ + void scale(SkScalar value) { + fX *= value; + fY *= value; + fZ *= value; + } + + /** Return a new point whose X, Y and Z coordinates are the negative of the + original point's + */ + SkPoint3 operator-() const { + SkPoint3 neg; + neg.fX = -fX; + neg.fY = -fY; + neg.fZ = -fZ; + return neg; + } + + /** Returns a new point whose coordinates are the difference between + a and b (i.e., a - b) + */ + friend SkPoint3 operator-(const SkPoint3& a, const SkPoint3& b) { + SkPoint3 v; + v.set(a.fX - b.fX, a.fY - b.fY, a.fZ - b.fZ); + return v; + } + + /** Returns a new point whose coordinates are the sum of a and b (a + b) + */ + friend SkPoint3 operator+(const SkPoint3& a, const SkPoint3& b) { + SkPoint3 v; + v.set(a.fX + b.fX, a.fY + b.fY, a.fZ + b.fZ); + return v; + } + + /** Add v's coordinates to the point's + */ + void operator+=(const SkPoint3& v) { + fX += v.fX; + fY += v.fY; + fZ += v.fZ; + } + + /** Subtract v's coordinates from the point's + */ + void operator-=(const SkPoint3& v) { + fX -= v.fX; + fY -= v.fY; + fZ -= v.fZ; + } + + /** Returns the dot product of a and b, treating them as 3D vectors + */ + static SkScalar DotProduct(const SkPoint3& a, const SkPoint3& b) { + return a.fX * b.fX + a.fY * b.fY + a.fZ * b.fZ; + } + + SkScalar dot(const SkPoint3& vec) const { + return DotProduct(*this, vec); + } +}; + +typedef SkPoint3 SkVector3; +typedef SkPoint3 SkColor3f; + +#endif diff --git a/gfx/skia/skia/include/core/SkPostConfig.h b/gfx/skia/skia/include/core/SkPostConfig.h index d513d20633a9..d23eddf2e624 100644 --- a/gfx/skia/skia/include/core/SkPostConfig.h +++ b/gfx/skia/skia/include/core/SkPostConfig.h @@ -5,10 +5,12 @@ * found in the LICENSE file. */ +// IWYU pragma: private, include "SkTypes.h" + #ifndef SkPostConfig_DEFINED #define SkPostConfig_DEFINED -#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_WINCE) +#if defined(SK_BUILD_FOR_WIN32) # define SK_BUILD_FOR_WIN #endif @@ -24,13 +26,12 @@ /** * Matrix calculations may be float or double. - * The default is double, as that is faster given our impl uses doubles - * for intermediate calculations. + * The default is float, as that's what Chromium's using. */ #if defined(SK_MSCALAR_IS_DOUBLE) && defined(SK_MSCALAR_IS_FLOAT) # error "cannot define both SK_MSCALAR_IS_DOUBLE and SK_MSCALAR_IS_FLOAT" #elif !defined(SK_MSCALAR_IS_DOUBLE) && !defined(SK_MSCALAR_IS_FLOAT) -# define SK_MSCALAR_IS_DOUBLE +# define SK_MSCALAR_IS_FLOAT #endif #if defined(SK_CPU_LENDIAN) && defined(SK_CPU_BENDIAN) @@ -68,6 +69,15 @@ # endif #endif +// As usual, there are two ways to increase alignment... the MSVC way and the everyone-else way. +#ifndef SK_STRUCT_ALIGN + #ifdef _MSC_VER + #define SK_STRUCT_ALIGN(N) __declspec(align(N)) + #else + #define SK_STRUCT_ALIGN(N) __attribute__((aligned(N))) + #endif +#endif + #if !defined(SK_SUPPORT_GPU) # define SK_SUPPORT_GPU 1 #endif @@ -88,23 +98,10 @@ # endif #endif -#if defined(SK_ZLIB_INCLUDE) && defined(SK_SYSTEM_ZLIB) -# error "cannot define both SK_ZLIB_INCLUDE and SK_SYSTEM_ZLIB" -#elif defined(SK_ZLIB_INCLUDE) || defined(SK_SYSTEM_ZLIB) -# define SK_HAS_ZLIB -#endif - /////////////////////////////////////////////////////////////////////////////// -#ifndef SkNEW -# define SkNEW(type_name) (new type_name) -# define SkNEW_ARGS(type_name, args) (new type_name args) -# define SkNEW_ARRAY(type_name, count) (new type_name[(count)]) -# define SkNEW_PLACEMENT(buf, type_name) (new (buf) type_name) -# define SkNEW_PLACEMENT_ARGS(buf, type_name, args) (new (buf) type_name args) -# define SkDELETE(obj) (delete (obj)) -# define SkDELETE_ARRAY(array) (delete[] (array)) -#endif +// TODO(mdempsky): Move elsewhere as appropriate. +#include #ifndef SK_CRASH # ifdef SK_BUILD_FOR_WIN @@ -120,23 +117,6 @@ /////////////////////////////////////////////////////////////////////////////// -/** - * SK_ENABLE_INST_COUNT controlls printing how many reference counted objects - * are still held on exit. - * Defaults to 1 in DEBUG and 0 in RELEASE. - */ -#ifndef SK_ENABLE_INST_COUNT -# ifdef SK_DEBUG -// Only enabled for static builds, because instance counting relies on static -// variables in functions defined in header files. -# define SK_ENABLE_INST_COUNT !defined(SKIA_DLL) -# else -# define SK_ENABLE_INST_COUNT 0 -# endif -#endif - -/////////////////////////////////////////////////////////////////////////////// - #ifdef SK_BUILD_FOR_WIN # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN @@ -167,8 +147,23 @@ # #endif +#if defined(GOOGLE3) + // Used as argument to DumpStackTrace in SK_ALWAYSBREAK. + void SkDebugfForDumpStackTrace(const char* data, void* unused); +#endif + #ifndef SK_ALWAYSBREAK -# ifdef SK_DEBUG +# if defined(GOOGLE3) + void DumpStackTrace(int skip_count, void w(const char*, void*), + void* arg); +# define SK_ALWAYSBREAK(cond) do { \ + if (cond) break; \ + SkNO_RETURN_HINT(); \ + SkDebugf("%s:%d: failed assertion \"%s\"\n", __FILE__, __LINE__, #cond); \ + DumpStackTrace(0, SkDebugfForDumpStackTrace, nullptr); \ + SK_CRASH(); \ + } while (false) +# elif defined(SK_DEBUG) # define SK_ALWAYSBREAK(cond) do { \ if (cond) break; \ SkNO_RETURN_HINT(); \ @@ -229,26 +224,7 @@ SK_ ## C3 ## 32_SHIFT == 24) #endif -////////////////////////////////////////////////////////////////////// - -// TODO: rebaseline as needed so we can remove this flag entirely. -// - all platforms have int64_t now -// - we have slightly different fixed math results because of this check -// since we don't define this for linux/android -#if defined(SK_BUILD_FOR_WIN32) || defined(SK_BUILD_FOR_MAC) -# ifndef SkLONGLONG -# define SkLONGLONG int64_t -# endif -#endif - ////////////////////////////////////////////////////////////////////////////////////////////// -#ifndef SK_BUILD_FOR_WINCE -# include -# include -#else -# define _CMNINTRIN_DECLARE_ONLY -# include "cmnintrin.h" -#endif #if defined SK_DEBUG && defined SK_BUILD_FOR_WIN32 # ifdef free @@ -293,29 +269,6 @@ ////////////////////////////////////////////////////////////////////// -#ifndef SK_OVERRIDE -# if defined(_MSC_VER) -# define SK_OVERRIDE override -# elif defined(__clang__) - // Using __attribute__((override)) on clang does not appear to always work. - // Clang defaults to C++03 and warns about using override. Squelch that. Intentionally no - // push/pop here so all users of SK_OVERRIDE ignore the warning too. This is like passing - // -Wno-c++11-extensions, except that GCC won't die (because it won't see this pragma). -# pragma clang diagnostic ignored "-Wc++11-extensions" -# -# if __has_feature(cxx_override_control) -# define SK_OVERRIDE override -# elif defined(__has_extension) && __has_extension(cxx_override_control) -# define SK_OVERRIDE override -# endif -# endif -# ifndef SK_OVERRIDE -# define SK_OVERRIDE -# endif -#endif - -////////////////////////////////////////////////////////////////////// - #if !defined(SK_UNUSED) # define SK_UNUSED SK_ATTRIBUTE(unused) #endif @@ -347,14 +300,25 @@ # endif #endif +#if defined(SK_BUILD_FOR_WIN) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 + #define SK_VECTORCALL __vectorcall +#elif defined(SK_CPU_ARM32) + #define SK_VECTORCALL __attribute__((pcs("aapcs-vfp"))) +#else + #define SK_VECTORCALL +#endif + ////////////////////////////////////////////////////////////////////// -#if defined(__clang__) || defined(__GNUC__) -# define SK_PREFETCH(ptr) __builtin_prefetch(ptr) -# define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) +#if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1 + #define SK_PREFETCH(ptr) _mm_prefetch(reinterpret_cast(ptr), _MM_HINT_T0) + #define SK_WRITE_PREFETCH(ptr) _mm_prefetch(reinterpret_cast(ptr), _MM_HINT_T0) +#elif defined(__GNUC__) + #define SK_PREFETCH(ptr) __builtin_prefetch(ptr) + #define SK_WRITE_PREFETCH(ptr) __builtin_prefetch(ptr, 1) #else -# define SK_PREFETCH(ptr) -# define SK_WRITE_PREFETCH(ptr) + #define SK_PREFETCH(ptr) + #define SK_WRITE_PREFETCH(ptr) #endif ////////////////////////////////////////////////////////////////////// @@ -385,33 +349,14 @@ ////////////////////////////////////////////////////////////////////// -#ifndef SK_ATOMICS_PLATFORM_H -# if defined(_MSC_VER) -# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_win.h" +#ifndef SK_EGL +# if defined(SK_BUILD_FOR_ANDROID) +# define SK_EGL 1 # else -# define SK_ATOMICS_PLATFORM_H "../../src/ports/SkAtomics_sync.h" +# define SK_EGL 0 # endif #endif -#ifndef SK_MUTEX_PLATFORM_H -# if defined(SK_BUILD_FOR_WIN) -# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_win.h" -# else -# define SK_MUTEX_PLATFORM_H "../../src/ports/SkMutex_pthread.h" -# endif -#endif - -#ifndef SK_BARRIERS_PLATFORM_H -# if SK_HAS_COMPILER_FEATURE(thread_sanitizer) -# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_tsan.h" -# elif defined(SK_CPU_ARM32) || defined(SK_CPU_ARM64) -# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_arm.h" -# else -# define SK_BARRIERS_PLATFORM_H "../../src/ports/SkBarriers_x86.h" -# endif -#endif - - ////////////////////////////////////////////////////////////////////// #if defined(SK_GAMMA_EXPONENT) && defined(SK_GAMMA_SRGB) @@ -422,4 +367,10 @@ # define SK_GAMMA_EXPONENT (2.2f) #endif +////////////////////////////////////////////////////////////////////// + +#ifndef GR_TEST_UTILS +# define GR_TEST_UTILS 1 +#endif + #endif // SkPostConfig_DEFINED diff --git a/gfx/skia/skia/include/core/SkPreConfig.h b/gfx/skia/skia/include/core/SkPreConfig.h index c7331113dc5f..a1a3037b9485 100644 --- a/gfx/skia/skia/include/core/SkPreConfig.h +++ b/gfx/skia/skia/include/core/SkPreConfig.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,42 +5,32 @@ * found in the LICENSE file. */ +// IWYU pragma: private, include "SkTypes.h" #ifndef SkPreConfig_DEFINED #define SkPreConfig_DEFINED -#ifdef WEBKIT_VERSION_MIN_REQUIRED - #include "config.h" -#endif - // Allows embedders that want to disable macros that take arguments to just // define that symbol to be one of these -// #define SK_NOTHING_ARG1(arg1) #define SK_NOTHING_ARG2(arg1, arg2) #define SK_NOTHING_ARG3(arg1, arg2, arg3) ////////////////////////////////////////////////////////////////////// -#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_PALM) && !defined(SK_BUILD_FOR_WINCE) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) && !defined(SK_BUILD_FOR_SDL) && !defined(SK_BUILD_FOR_BREW) && !defined(SK_BUILD_FOR_NACL) +#if !defined(SK_BUILD_FOR_ANDROID) && !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_WIN32) && !defined(SK_BUILD_FOR_UNIX) && !defined(SK_BUILD_FOR_MAC) #ifdef __APPLE__ #include "TargetConditionals.h" #endif - #if defined(PALMOS_SDK_VERSION) - #define SK_BUILD_FOR_PALM - #elif defined(UNDER_CE) - #define SK_BUILD_FOR_WINCE - #elif defined(WIN32) - #define SK_BUILD_FOR_WIN32 - #elif defined(__SYMBIAN32__) + #if defined(WIN32) || defined(__SYMBIAN32__) #define SK_BUILD_FOR_WIN32 #elif defined(ANDROID) #define SK_BUILD_FOR_ANDROID - #elif defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ - defined(__sun) || defined(__NetBSD__) || defined(__DragonFly__) || \ - defined(__GLIBC__) || defined(__GNU__) + #elif defined(linux) || defined(__linux) || defined(__FreeBSD__) || \ + defined(__OpenBSD__) || defined(__sun) || defined(__NetBSD__) || \ + defined(__DragonFly__) || defined(__GLIBC__) || defined(__GNU__) #define SK_BUILD_FOR_UNIX #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #define SK_BUILD_FOR_IOS @@ -125,12 +114,18 @@ #define SK_CPU_SSE_LEVEL_SSSE3 31 #define SK_CPU_SSE_LEVEL_SSE41 41 #define SK_CPU_SSE_LEVEL_SSE42 42 +#define SK_CPU_SSE_LEVEL_AVX 51 +#define SK_CPU_SSE_LEVEL_AVX2 52 // Are we in GCC? #ifndef SK_CPU_SSE_LEVEL // These checks must be done in descending order to ensure we set the highest // available SSE level. - #if defined(__SSE4_2__) + #if defined(__AVX2__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2 + #elif defined(__AVX__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX + #elif defined(__SSE4_2__) #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE42 #elif defined(__SSE4_1__) #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE41 @@ -147,9 +142,13 @@ #ifndef SK_CPU_SSE_LEVEL // These checks must be done in descending order to ensure we set the highest // available SSE level. 64-bit intel guarantees at least SSE2 support. - #if defined(_M_X64) || defined(_M_AMD64) - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 - #elif defined (_M_IX86_FP) + #if defined(__AVX2__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX2 + #elif defined(__AVX__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_AVX + #elif defined(_M_X64) || defined(_M_AMD64) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 + #elif defined(_M_IX86_FP) #if _M_IX86_FP >= 2 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 #elif _M_IX86_FP == 1 @@ -183,12 +182,6 @@ #else #define SK_ARM_ARCH 3 #endif - - #if defined(__thumb2__) && (SK_ARM_ARCH >= 6) \ - || !defined(__thumb__) && ((SK_ARM_ARCH > 5) || defined(__ARM_ARCH_5E__) \ - || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)) - #define SK_ARM_HAS_EDSP - #endif #endif #endif @@ -197,6 +190,12 @@ #define SK_CPU_ARM64 #endif +// All 64-bit ARM chips have NEON. Many 32-bit ARM chips do too. +// TODO: Why don't we want NEON on iOS? +#if !defined(SK_ARM_HAS_NEON) && !defined(SK_BUILD_FOR_IOS) && defined(__ARM_NEON) + #define SK_ARM_HAS_NEON +#endif + ////////////////////////////////////////////////////////////////////// #if !defined(SKIA_IMPLEMENTATION) diff --git a/gfx/skia/skia/include/core/SkRRect.h b/gfx/skia/skia/include/core/SkRRect.h index d3f48cd48474..8d8cdbf02c79 100644 --- a/gfx/skia/skia/include/core/SkRRect.h +++ b/gfx/skia/skia/include/core/SkRRect.h @@ -52,9 +52,6 @@ public: * by type(). The subtypes become progressively less restrictive. */ enum Type { - // !< Internal indicator that the sub type must be computed. - kUnknown_Type = -1, - // !< The RR is empty kEmpty_Type, @@ -90,12 +87,7 @@ public: */ Type getType() const { SkDEBUGCODE(this->validate();) - - if (kUnknown_Type == fType) { - this->computeType(); - } - SkASSERT(kUnknown_Type != fType); - return fType; + return static_cast(fType); } Type type() const { return this->getType(); } @@ -104,8 +96,13 @@ public: inline bool isRect() const { return kRect_Type == this->getType(); } inline bool isOval() const { return kOval_Type == this->getType(); } inline bool isSimple() const { return kSimple_Type == this->getType(); } + // TODO: should isSimpleCircular & isCircle take a tolerance? This could help + // instances where the mapping to device space is noisy. inline bool isSimpleCircular() const { - return this->isSimple() && fRadii[0].fX == fRadii[0].fY; + return this->isSimple() && SkScalarNearlyEqual(fRadii[0].fX, fRadii[0].fY); + } + inline bool isCircle() const { + return this->isOval() && SkScalarNearlyEqual(fRadii[0].fX, fRadii[0].fY); } inline bool isNinePatch() const { return kNinePatch_Type == this->getType(); } inline bool isComplex() const { return kComplex_Type == this->getType(); } @@ -130,32 +127,48 @@ public: * Set this RR to match the supplied rect. All radii will be 0. */ void setRect(const SkRect& rect) { - if (rect.isEmpty()) { + fRect = rect; + fRect.sort(); + + if (fRect.isEmpty()) { this->setEmpty(); return; } - fRect = rect; memset(fRadii, 0, sizeof(fRadii)); fType = kRect_Type; SkDEBUGCODE(this->validate();) } + static SkRRect MakeRect(const SkRect& r) { + SkRRect rr; + rr.setRect(r); + return rr; + } + + static SkRRect MakeOval(const SkRect& oval) { + SkRRect rr; + rr.setOval(oval); + return rr; + } + /** * Set this RR to match the supplied oval. All x radii will equal half the * width and all y radii will equal half the height. */ void setOval(const SkRect& oval) { - if (oval.isEmpty()) { + fRect = oval; + fRect.sort(); + + if (fRect.isEmpty()) { this->setEmpty(); return; } - SkScalar xRad = SkScalarHalf(oval.width()); - SkScalar yRad = SkScalarHalf(oval.height()); + SkScalar xRad = SkScalarHalf(fRect.width()); + SkScalar yRad = SkScalarHalf(fRect.height()); - fRect = oval; for (int i = 0; i < 4; ++i) { fRadii[i].set(xRad, yRad); } @@ -292,23 +305,20 @@ public: */ bool transform(const SkMatrix& matrix, SkRRect* dst) const; -#ifdef SK_DEVELOPER - /** - * Prints the rrect using SkDebugf. This is intended for Skia development debugging. Don't - * rely on the existence of this function or the formatting of its output. - */ - void dump() const; -#endif + void dump(bool asHex) const; + void dump() const { this->dump(false); } + void dumpHex() const { this->dump(true); } private: SkRect fRect; // Radii order is UL, UR, LR, LL. Use Corner enum to index into fRadii[] SkVector fRadii[4]; - mutable Type fType; + // use an explicitly sized type so we're sure the class is dense (no uninitialized bytes) + int32_t fType; // TODO: add padding so we can use memcpy for flattening and not copy // uninitialized data - void computeType() const; + void computeType(); bool checkCornerContainment(SkScalar x, SkScalar y) const; // to access fRadii directly diff --git a/gfx/skia/skia/include/core/SkRSXform.h b/gfx/skia/skia/include/core/SkRSXform.h new file mode 100644 index 000000000000..7af6e67c128d --- /dev/null +++ b/gfx/skia/skia/include/core/SkRSXform.h @@ -0,0 +1,67 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkRSXform_DEFINED +#define SkRSXform_DEFINED + +#include "SkScalar.h" + +/** + * A compressed form of a rotation+scale matrix. + * + * [ fSCos -fSSin fTx ] + * [ fSSin fSCos fTy ] + * [ 0 0 1 ] + */ +struct SkRSXform { + static SkRSXform Make(SkScalar scos, SkScalar ssin, SkScalar tx, SkScalar ty) { + SkRSXform xform = { scos, ssin, tx, ty }; + return xform; + } + + /* + * Initialize a new xform based on the scale, rotation (in radians), final tx,ty location + * and anchor-point ax,ay within the src quad. + * + * Note: the anchor point is not normalized (e.g. 0...1) but is in pixels of the src image. + */ + static SkRSXform MakeFromRadians(SkScalar scale, SkScalar radians, SkScalar tx, SkScalar ty, + SkScalar ax, SkScalar ay) { + const SkScalar s = SkScalarSin(radians) * scale; + const SkScalar c = SkScalarCos(radians) * scale; + return Make(c, s, tx + -c * ax + s * ay, ty + -s * ax - c * ay); + } + + SkScalar fSCos; + SkScalar fSSin; + SkScalar fTx; + SkScalar fTy; + + bool rectStaysRect() const { + return 0 == fSCos || 0 == fSSin; + } + + void setIdentity() { + fSCos = 1; + fSSin = fTx = fTy = 0; + } + + void set(SkScalar scos, SkScalar ssin, SkScalar tx, SkScalar ty) { + fSCos = scos; + fSSin = ssin; + fTx = tx; + fTy = ty; + } + + void toQuad(SkScalar width, SkScalar height, SkPoint quad[4]) const; + void toQuad(const SkSize& size, SkPoint quad[4]) const { + this->toQuad(size.width(), size.height(), quad); + } +}; + +#endif + diff --git a/gfx/skia/skia/include/core/SkRasterizer.h b/gfx/skia/skia/include/core/SkRasterizer.h index d6e514c26321..1881ccef2455 100644 --- a/gfx/skia/skia/include/core/SkRasterizer.h +++ b/gfx/skia/skia/include/core/SkRasterizer.h @@ -20,8 +20,6 @@ struct SkIRect; class SK_API SkRasterizer : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkRasterizer) - /** Turn the path into a mask, respecting the specified local->device matrix. */ bool rasterize(const SkPath& path, const SkMatrix& matrix, @@ -32,8 +30,6 @@ public: protected: SkRasterizer() {} - SkRasterizer(SkReadBuffer& buffer) : INHERITED(buffer) {} - virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix, const SkIRect* clipBounds, SkMask* mask, SkMask::CreateMode mode) const; diff --git a/gfx/skia/skia/include/core/SkRect.h b/gfx/skia/skia/include/core/SkRect.h index d699156ebf2e..fe276e6710b0 100644 --- a/gfx/skia/skia/include/core/SkRect.h +++ b/gfx/skia/skia/include/core/SkRect.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,13 +5,14 @@ * found in the LICENSE file. */ - #ifndef SkRect_DEFINED #define SkRect_DEFINED #include "SkPoint.h" #include "SkSize.h" +struct SkRect; + /** \struct SkIRect SkIRect holds four 32 bit integer coordinates for a rectangle @@ -77,6 +77,8 @@ struct SK_API SkIRect { */ int height() const { return fBottom - fTop; } + SkISize size() const { return SkISize::Make(this->width(), this->height()); } + /** * Since the center of an integer rect may fall on a factional value, this * method is defined to return (right + left) >> 1. @@ -160,17 +162,24 @@ struct SK_API SkIRect { /** * Return a new IRect, built as an offset of this rect. */ - SkIRect makeOffset(int dx, int dy) const { + SkIRect makeOffset(int32_t dx, int32_t dy) const { return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); } /** * Return a new IRect, built as an inset of this rect. */ - SkIRect makeInset(int dx, int dy) const { + SkIRect makeInset(int32_t dx, int32_t dy) const { return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); } + /** + * Return a new Rect, built as an outset of this rect. + */ + SkIRect makeOutset(int32_t dx, int32_t dy) const { + return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); + } + /** Offset set the rectangle by adding dx to its left and right, and adding dy to its top and bottom. */ @@ -244,6 +253,10 @@ struct SK_API SkIRect { fRight >= r.fRight && fBottom >= r.fBottom; } + /** Returns true if the specified rectangle r is inside or equal to this rectangle. + */ + bool contains(const SkRect& r) const; + /** Return true if this rectangle contains the specified rectangle. For speed, this method does not check if either this or the specified rectangles are empty, and if either is, its return value is undefined. @@ -267,8 +280,7 @@ struct SK_API SkIRect { intersection, otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(const SkIRect& r) { - SkASSERT(&r); + bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& r) { return this->intersect(r.fLeft, r.fTop, r.fRight, r.fBottom); } @@ -276,7 +288,7 @@ struct SK_API SkIRect { that intersection, otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(const SkIRect& a, const SkIRect& b) { + bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& a, const SkIRect& b) { if (!a.isEmpty() && !b.isEmpty() && a.fLeft < b.fRight && b.fLeft < a.fRight && @@ -296,7 +308,7 @@ struct SK_API SkIRect { If either is, then the return result is undefined. In the debug build, we assert that both rectangles are non-empty. */ - bool intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) { + bool SK_WARN_UNUSED_RESULT intersectNoEmptyCheck(const SkIRect& a, const SkIRect& b) { SkASSERT(!a.isEmpty() && !b.isEmpty()); if (a.fLeft < b.fRight && b.fLeft < a.fRight && @@ -315,7 +327,8 @@ struct SK_API SkIRect { otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(int32_t left, int32_t top, int32_t right, int32_t bottom) { + bool SK_WARN_UNUSED_RESULT intersect(int32_t left, int32_t top, + int32_t right, int32_t bottom) { if (left < right && top < bottom && !this->isEmpty() && fLeft < right && left < fRight && fTop < bottom && top < fBottom) { if (fLeft < left) fLeft = left; @@ -331,8 +344,8 @@ struct SK_API SkIRect { */ static bool Intersects(const SkIRect& a, const SkIRect& b) { return !a.isEmpty() && !b.isEmpty() && // check for empties - a.fLeft < b.fRight && b.fLeft < a.fRight && - a.fTop < b.fBottom && b.fTop < a.fBottom; + a.fLeft < b.fRight && b.fLeft < a.fRight && + a.fTop < b.fBottom && b.fTop < a.fBottom; } /** @@ -395,6 +408,12 @@ struct SK_API SkRect { return r; } + static SkRect SK_WARN_UNUSED_RESULT MakeIWH(int w, int h) { + SkRect r; + r.set(0, 0, SkIntToScalar(w), SkIntToScalar(h)); + return r; + } + static SkRect SK_WARN_UNUSED_RESULT MakeSize(const SkSize& size) { SkRect r; r.set(0, 0, size.width(), size.height()); @@ -595,7 +614,7 @@ struct SK_API SkRect { SkRect makeOffset(SkScalar dx, SkScalar dy) const { return MakeLTRB(fLeft + dx, fTop + dy, fRight + dx, fBottom + dy); } - + /** * Return a new Rect, built as an inset of this rect. */ @@ -603,6 +622,13 @@ struct SK_API SkRect { return MakeLTRB(fLeft + dx, fTop + dy, fRight - dx, fBottom - dy); } + /** + * Return a new Rect, built as an outset of this rect. + */ + SkRect makeOutset(SkScalar dx, SkScalar dy) const { + return MakeLTRB(fLeft - dx, fTop - dy, fRight + dx, fBottom + dy); + } + /** Offset set the rectangle by adding dx to its left and right, and adding dy to its top and bottom. */ @@ -650,42 +676,54 @@ struct SK_API SkRect { intersection, otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(const SkRect& r); - bool intersect2(const SkRect& r); + bool SK_WARN_UNUSED_RESULT intersect(const SkRect& r); /** If this rectangle intersects the rectangle specified by left, top, right, bottom, return true and set this rectangle to that intersection, otherwise return false and do not change this rectangle. If either rectangle is empty, do nothing and return false. */ - bool intersect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom); + bool SK_WARN_UNUSED_RESULT intersect(SkScalar left, SkScalar top, + SkScalar right, SkScalar bottom); + /** + * If rectangles a and b intersect, return true and set this rectangle to + * that intersection, otherwise return false and do not change this + * rectangle. If either rectangle is empty, do nothing and return false. + */ + bool SK_WARN_UNUSED_RESULT intersect(const SkRect& a, const SkRect& b); + + +private: + static bool Intersects(SkScalar al, SkScalar at, SkScalar ar, SkScalar ab, + SkScalar bl, SkScalar bt, SkScalar br, SkScalar bb) { + SkScalar L = SkMaxScalar(al, bl); + SkScalar R = SkMinScalar(ar, br); + SkScalar T = SkMaxScalar(at, bt); + SkScalar B = SkMinScalar(ab, bb); + return L < R && T < B; + } + +public: /** * Return true if this rectangle is not empty, and the specified sides of * a rectangle are not empty, and they intersect. */ bool intersects(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) const { - return // first check that both are not empty - left < right && top < bottom && - fLeft < fRight && fTop < fBottom && - // now check for intersection - fLeft < right && left < fRight && - fTop < bottom && top < fBottom; + return Intersects(fLeft, fTop, fRight, fBottom, left, top, right, bottom); } - /** If rectangles a and b intersect, return true and set this rectangle to - * that intersection, otherwise return false and do not change this - * rectangle. If either rectangle is empty, do nothing and return false. - */ - bool intersect(const SkRect& a, const SkRect& b); + bool intersects(const SkRect& r) const { + return Intersects(fLeft, fTop, fRight, fBottom, + r.fLeft, r.fTop, r.fRight, r.fBottom); + } /** * Return true if rectangles a and b are not empty and intersect. */ static bool Intersects(const SkRect& a, const SkRect& b) { - return !a.isEmpty() && !b.isEmpty() && - a.fLeft < b.fRight && b.fLeft < a.fRight && - a.fTop < b.fBottom && b.fTop < a.fBottom; + return Intersects(a.fLeft, a.fTop, a.fRight, a.fBottom, + b.fLeft, b.fTop, b.fRight, b.fBottom); } /** @@ -702,8 +740,27 @@ struct SK_API SkRect { void join(const SkRect& r) { this->join(r.fLeft, r.fTop, r.fRight, r.fBottom); } - // alias for join() - void growToInclude(const SkRect& r) { this->join(r); } + + void joinNonEmptyArg(const SkRect& r) { + SkASSERT(!r.isEmpty()); + // if we are empty, just assign + if (fLeft >= fRight || fTop >= fBottom) { + *this = r; + } else { + this->joinPossiblyEmptyRect(r); + } + } + + /** + * Joins the rectangle with another without checking if either are empty (may produce unexpected + * results if either rect is inverted). + */ + void joinPossiblyEmptyRect(const SkRect& r) { + fLeft = SkMinScalar(fLeft, r.left()); + fTop = SkMinScalar(fTop, r.top()); + fRight = SkMaxScalar(fRight, r.right()); + fBottom = SkMaxScalar(fBottom, r.bottom()); + } /** * Grow the rect to include the specified (x,y). After this call, the @@ -747,6 +804,16 @@ struct SK_API SkRect { fRight >= r.fRight && fBottom >= r.fBottom; } + /** + * Returns true if the specified rectangle r is inside or equal to this rectangle. + */ + bool contains(const SkIRect& r) const { + // todo: can we eliminate the this->isEmpty check? + return !r.isEmpty() && !this->isEmpty() && + fLeft <= SkIntToScalar(r.fLeft) && fTop <= SkIntToScalar(r.fTop) && + fRight >= SkIntToScalar(r.fRight) && fBottom >= SkIntToScalar(r.fBottom); + } + /** * Set the dst rectangle by rounding this rectangle's coordinates to their * nearest integer values using SkScalarRoundToInt. @@ -786,15 +853,16 @@ struct SK_API SkRect { } /** - * Expand this rectangle by rounding its coordinates "out", choosing the - * floor of top and left, and the ceil of right and bottom. If this rect - * is already on integer coordinates, then it will be unchanged. + * Set the dst rectangle by rounding "out" this rectangle, choosing the + * SkScalarFloorToScalar of top and left, and the SkScalarCeilToScalar of right and bottom. + * + * It is safe for this == dst */ - void roundOut() { - this->set(SkScalarFloorToScalar(fLeft), - SkScalarFloorToScalar(fTop), - SkScalarCeilToScalar(fRight), - SkScalarCeilToScalar(fBottom)); + void roundOut(SkRect* dst) const { + dst->set(SkScalarFloorToScalar(fLeft), + SkScalarFloorToScalar(fTop), + SkScalarCeilToScalar(fRight), + SkScalarCeilToScalar(fBottom)); } /** @@ -809,39 +877,50 @@ struct SK_API SkRect { SkScalarFloorToInt(fRight), SkScalarFloorToInt(fBottom)); } - /** - * Return a new SkIRect which is contains the rounded coordinates of this - * rect using SkScalarRoundToInt. - */ + //! Returns the result of calling round(&dst) SkIRect round() const { SkIRect ir; this->round(&ir); return ir; } - + + //! Returns the result of calling roundOut(&dst) + SkIRect roundOut() const { + SkIRect ir; + this->roundOut(&ir); + return ir; + } + /** * Swap top/bottom or left/right if there are flipped (i.e. if width() * or height() would have returned a negative value.) This should be called * if the edges are computed separately, and may have crossed over each * other. When this returns, left <= right && top <= bottom */ - void sort(); + void sort() { + if (fLeft > fRight) { + SkTSwap(fLeft, fRight); + } + + if (fTop > fBottom) { + SkTSwap(fTop, fBottom); + } + } /** * cast-safe way to treat the rect as an array of (4) SkScalars. */ const SkScalar* asScalars() const { return &fLeft; } -#ifdef SK_DEVELOPER - /** - * Dumps the rect using SkDebugf. This is intended for Skia development debugging. Don't - * rely on the existence of this function or the formatting of its output. - */ - void dump() const { - SkDebugf("{ l: %f, t: %f, r: %f, b: %f }", fLeft, fTop, fRight, fBottom); - } -#endif - + void dump(bool asHex) const; + void dump() const { this->dump(false); } + void dumpHex() const { this->dump(true); } }; +inline bool SkIRect::contains(const SkRect& r) const { + return !r.isEmpty() && !this->isEmpty() && // check for empties + (SkScalar)fLeft <= r.fLeft && (SkScalar)fTop <= r.fTop && + (SkScalar)fRight >= r.fRight && (SkScalar)fBottom >= r.fBottom; +} + #endif diff --git a/gfx/skia/skia/include/core/SkRefCnt.h b/gfx/skia/skia/include/core/SkRefCnt.h index ce38c67bd56a..6c608ac93936 100644 --- a/gfx/skia/skia/include/core/SkRefCnt.h +++ b/gfx/skia/skia/include/core/SkRefCnt.h @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,14 +5,12 @@ * found in the LICENSE file. */ - #ifndef SkRefCnt_DEFINED #define SkRefCnt_DEFINED -#include "SkDynamicAnnotations.h" -#include "SkThread.h" -#include "SkInstCnt.h" -#include "SkTemplates.h" +#include "../private/SkAtomics.h" +#include "../private/SkUniquePtr.h" +#include "SkTypes.h" /** \class SkRefCntBase @@ -27,8 +24,6 @@ */ class SK_API SkRefCntBase : SkNoncopyable { public: - SK_DECLARE_INST_COUNT_ROOT(SkRefCntBase) - /** Default construct, initializing the reference count to 1. */ SkRefCntBase() : fRefCnt(1) {} @@ -49,22 +44,28 @@ public: * Ensures that all previous owner's actions are complete. */ bool unique() const { - // We believe we're reading fRefCnt in a safe way here, so we stifle the TSAN warning about - // an unproctected read. Generally, don't read fRefCnt, and don't stifle this warning. - bool const unique = (1 == SK_ANNOTATE_UNPROTECTED_READ(fRefCnt)); - if (unique) { - // Acquire barrier (L/SL), if not provided by load of fRefCnt. - // Prevents user's 'unique' code from happening before decrements. - //TODO: issue the barrier. + if (1 == sk_atomic_load(&fRefCnt, sk_memory_order_acquire)) { + // The acquire barrier is only really needed if we return true. It + // prevents code conditioned on the result of unique() from running + // until previous owners are all totally done calling unref(). + return true; } - return unique; + return false; } /** Increment the reference count. Must be balanced by a call to unref(). */ void ref() const { +#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK + // Android employs some special subclasses that enable the fRefCnt to + // go to zero, but not below, prior to reusing the object. This breaks + // the use of unique() on such objects and as such should be removed + // once the Android code is fixed. + SkASSERT(fRefCnt >= 0); +#else SkASSERT(fRefCnt > 0); - sk_atomic_inc(&fRefCnt); // No barrier required. +#endif + (void)sk_atomic_fetch_add(&fRefCnt, +1, sk_memory_order_relaxed); // No barrier required. } /** Decrement the reference count. If the reference count is 1 before the @@ -73,12 +74,11 @@ public: */ void unref() const { SkASSERT(fRefCnt > 0); - // Release barrier (SL/S), if not provided below. - if (sk_atomic_dec(&fRefCnt) == 1) { - // Acquire barrier (L/SL), if not provided above. - // Prevents code in dispose from happening before the decrement. - sk_membar_acquire__after_atomic_dec(); - internal_dispose(); + // A release here acts in place of all releases we "should" have been doing in ref(). + if (1 == sk_atomic_fetch_add(&fRefCnt, -1, sk_memory_order_acq_rel)) { + // Like unique(), the acquire is only needed on success, to make sure + // code in internal_dispose() doesn't happen before the decrement. + this->internal_dispose(); } } @@ -108,7 +108,7 @@ private: */ virtual void internal_dispose() const { this->internal_dispose_restore_refcnt_to_1(); - SkDELETE(this); + delete this; } // The following friends are those which override internal_dispose() @@ -142,7 +142,7 @@ class SK_API SkRefCnt : public SkRefCntBase { }; } while (0) -/** Call obj->ref() and return obj. The obj must not be NULL. +/** Call obj->ref() and return obj. The obj must not be nullptr. */ template static inline T* SkRef(T* obj) { SkASSERT(obj); @@ -168,76 +168,27 @@ template static inline void SkSafeUnref(T* obj) { } template static inline void SkSafeSetNull(T*& obj) { - if (NULL != obj) { + if (obj) { obj->unref(); - obj = NULL; + obj = nullptr; } } /////////////////////////////////////////////////////////////////////////////// +template struct SkTUnref { + void operator()(T* t) { t->unref(); } +}; + /** * Utility class that simply unref's its argument in the destructor. */ -template class SkAutoTUnref : SkNoncopyable { +template class SkAutoTUnref : public skstd::unique_ptr> { public: - explicit SkAutoTUnref(T* obj = NULL) : fObj(obj) {} - ~SkAutoTUnref() { SkSafeUnref(fObj); } + explicit SkAutoTUnref(T* obj = nullptr) : skstd::unique_ptr>(obj) {} - T* get() const { return fObj; } - - T* reset(T* obj) { - SkSafeUnref(fObj); - fObj = obj; - return obj; - } - - void swap(SkAutoTUnref* other) { - T* tmp = fObj; - fObj = other->fObj; - other->fObj = tmp; - } - - /** - * Return the hosted object (which may be null), transferring ownership. - * The reference count is not modified, and the internal ptr is set to NULL - * so unref() will not be called in our destructor. A subsequent call to - * detach() will do nothing and return null. - */ - T* detach() { - T* obj = fObj; - fObj = NULL; - return obj; - } - - /** - * BlockRef is a type which inherits from B, cannot be created, - * cannot be deleted, and makes ref and unref private. - */ - template class BlockRef : public B { - private: - BlockRef(); - ~BlockRef(); - void ref() const; - void unref() const; - }; - - /** If T is const, the type returned from operator-> will also be const. */ - typedef typename SkTConstType, SkTIsConst::value>::type BlockRefType; - - /** - * SkAutoTUnref assumes ownership of the ref. As a result, it is an error - * for the user to ref or unref through SkAutoTUnref. Therefore - * SkAutoTUnref::operator-> returns BlockRef*. This prevents use of - * skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref(). - */ - BlockRefType *operator->() const { - return static_cast(fObj); - } - operator T*() { return fObj; } - -private: - T* fObj; + T* detach() { return this->release(); } + operator T*() const { return this->get(); } }; // Can't use the #define trick below to guard a bare SkAutoTUnref(...) because it's templated. :( @@ -247,4 +198,31 @@ public: }; #define SkAutoUnref(...) SK_REQUIRE_LOCAL_VAR(SkAutoUnref) +// This is a variant of SkRefCnt that's Not Virtual, so weighs 4 bytes instead of 8 or 16. +// There's only benefit to using this if the deriving class does not otherwise need a vtable. +template +class SkNVRefCnt : SkNoncopyable { +public: + SkNVRefCnt() : fRefCnt(1) {} + ~SkNVRefCnt() { SkASSERTF(1 == fRefCnt, "NVRefCnt was %d", fRefCnt); } + + // Implementation is pretty much the same as SkRefCntBase. All required barriers are the same: + // - unique() needs acquire when it returns true, and no barrier if it returns false; + // - ref() doesn't need any barrier; + // - unref() needs a release barrier, and an acquire if it's going to call delete. + + bool unique() const { return 1 == sk_atomic_load(&fRefCnt, sk_memory_order_acquire); } + void ref() const { (void)sk_atomic_fetch_add(&fRefCnt, +1, sk_memory_order_relaxed); } + void unref() const { + if (1 == sk_atomic_fetch_add(&fRefCnt, -1, sk_memory_order_acq_rel)) { + SkDEBUGCODE(fRefCnt = 1;) // restore the 1 for our destructor's assert + delete (const Derived*)this; + } + } + void deref() const { this->unref(); } + +private: + mutable int32_t fRefCnt; +}; + #endif diff --git a/gfx/skia/skia/include/core/SkRegion.h b/gfx/skia/skia/include/core/SkRegion.h index 20366bc63822..eb0f1367aba4 100644 --- a/gfx/skia/skia/include/core/SkRegion.h +++ b/gfx/skia/skia/include/core/SkRegion.h @@ -59,7 +59,6 @@ public: * resulting region is non-empty. */ bool set(const SkRegion& src) { - SkASSERT(&src); *this = src; return !this->isEmpty(); } diff --git a/gfx/skia/skia/include/core/SkScalar.h b/gfx/skia/skia/include/core/SkScalar.h index 3056b7297e13..4efa8417afd4 100644 --- a/gfx/skia/skia/include/core/SkScalar.h +++ b/gfx/skia/skia/include/core/SkScalar.h @@ -9,70 +9,31 @@ #define SkScalar_DEFINED #include "SkFixed.h" -#include "SkFloatingPoint.h" +#include "../private/SkFloatingPoint.h" -//#define SK_SUPPORT_DEPRECATED_SCALARROUND +// TODO: move this sort of check into SkPostConfig.h +#define SK_SCALAR_IS_DOUBLE 0 +#undef SK_SCALAR_IS_FLOAT +#define SK_SCALAR_IS_FLOAT 1 -typedef float SkScalar; -/** SK_Scalar1 is defined to be 1.0 represented as an SkScalar -*/ -#define SK_Scalar1 (1.0f) -/** SK_Scalar1 is defined to be 1/2 represented as an SkScalar -*/ -#define SK_ScalarHalf (0.5f) -/** SK_ScalarInfinity is defined to be infinity as an SkScalar -*/ -#define SK_ScalarInfinity SK_FloatInfinity -/** SK_ScalarNegativeInfinity is defined to be negative infinity as an SkScalar -*/ -#define SK_ScalarNegativeInfinity SK_FloatNegativeInfinity -/** SK_ScalarMax is defined to be the largest value representable as an SkScalar -*/ -#define SK_ScalarMax (3.402823466e+38f) -/** SK_ScalarMin is defined to be the smallest value representable as an SkScalar -*/ -#define SK_ScalarMin (-SK_ScalarMax) -/** SK_ScalarNaN is defined to be 'Not a Number' as an SkScalar -*/ -#define SK_ScalarNaN SK_FloatNaN -/** SkScalarIsNaN(n) returns true if argument is not a number -*/ -static inline bool SkScalarIsNaN(float x) { return x != x; } +#if SK_SCALAR_IS_FLOAT -/** Returns true if x is not NaN and not infinite */ -static inline bool SkScalarIsFinite(float x) { - // We rely on the following behavior of infinities and nans - // 0 * finite --> 0 - // 0 * infinity --> NaN - // 0 * NaN --> NaN - float prod = x * 0; - // At this point, prod will either be NaN or 0 - // Therefore we can return (prod == prod) or (0 == prod). - return !SkScalarIsNaN(prod); -} +typedef float SkScalar; -/** SkIntToScalar(n) returns its integer argument as an SkScalar -*/ -#define SkIntToScalar(n) ((float)(n)) -/** SkFixedToScalar(n) returns its SkFixed argument as an SkScalar -*/ -#define SkFixedToScalar(x) SkFixedToFloat(x) -/** SkScalarToFixed(n) returns its SkScalar argument as an SkFixed -*/ -#define SkScalarToFixed(x) SkFloatToFixed(x) +#define SK_Scalar1 1.0f +#define SK_ScalarHalf 0.5f +#define SK_ScalarSqrt2 1.41421356f +#define SK_ScalarPI 3.14159265f +#define SK_ScalarTanPIOver8 0.414213562f +#define SK_ScalarRoot2Over2 0.707106781f +#define SK_ScalarMax 3.402823466e+38f +#define SK_ScalarInfinity SK_FloatInfinity +#define SK_ScalarNegativeInfinity SK_FloatNegativeInfinity +#define SK_ScalarNaN SK_FloatNaN -#define SkScalarToFloat(n) (n) -#ifndef SK_SCALAR_TO_FLOAT_EXCLUDED -#define SkFloatToScalar(n) (n) -#endif - -#define SkScalarToDouble(n) (double)(n) -#define SkDoubleToScalar(n) (float)(n) - -/** SkScalarFraction(x) returns the signed fractional part of the argument -*/ -#define SkScalarFraction(x) sk_float_mod(x, 1.0f) +#define SkFixedToScalar(x) SkFixedToFloat(x) +#define SkScalarToFixed(x) SkFloatToFixed(x) #define SkScalarFloorToScalar(x) sk_float_floor(x) #define SkScalarCeilToScalar(x) sk_float_ceil(x) @@ -81,7 +42,111 @@ static inline bool SkScalarIsFinite(float x) { #define SkScalarFloorToInt(x) sk_float_floor2int(x) #define SkScalarCeilToInt(x) sk_float_ceil2int(x) #define SkScalarRoundToInt(x) sk_float_round2int(x) -#define SkScalarTruncToInt(x) static_cast(x) + +#define SkScalarAbs(x) sk_float_abs(x) +#define SkScalarCopySign(x, y) sk_float_copysign(x, y) +#define SkScalarMod(x, y) sk_float_mod(x,y) +#define SkScalarFraction(x) sk_float_mod(x, 1.0f) +#define SkScalarSqrt(x) sk_float_sqrt(x) +#define SkScalarPow(b, e) sk_float_pow(b, e) + +#define SkScalarSin(radians) (float)sk_float_sin(radians) +#define SkScalarCos(radians) (float)sk_float_cos(radians) +#define SkScalarTan(radians) (float)sk_float_tan(radians) +#define SkScalarASin(val) (float)sk_float_asin(val) +#define SkScalarACos(val) (float)sk_float_acos(val) +#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x) +#define SkScalarExp(x) (float)sk_float_exp(x) +#define SkScalarLog(x) (float)sk_float_log(x) +#define SkScalarLog2(x) (float)sk_float_log2(x) + +#else // SK_SCALAR_IS_DOUBLE + +typedef double SkScalar; + +#define SK_Scalar1 1.0 +#define SK_ScalarHalf 0.5 +#define SK_ScalarSqrt2 1.414213562373095 +#define SK_ScalarPI 3.141592653589793 +#define SK_ScalarTanPIOver8 0.4142135623731 +#define SK_ScalarRoot2Over2 0.70710678118655 +#define SK_ScalarMax 1.7976931348623157+308 +#define SK_ScalarInfinity SK_DoubleInfinity +#define SK_ScalarNegativeInfinity SK_DoubleNegativeInfinity +#define SK_ScalarNaN SK_DoubleNaN + +#define SkFixedToScalar(x) SkFixedToDouble(x) +#define SkScalarToFixed(x) SkDoubleToFixed(x) + +#define SkScalarFloorToScalar(x) floor(x) +#define SkScalarCeilToScalar(x) ceil(x) +#define SkScalarRoundToScalar(x) floor((x) + 0.5) + +#define SkScalarFloorToInt(x) (int)floor(x) +#define SkScalarCeilToInt(x) (int)ceil(x) +#define SkScalarRoundToInt(x) (int)floor((x) + 0.5) + +#define SkScalarAbs(x) abs(x) +#define SkScalarCopySign(x, y) copysign(x, y) +#define SkScalarMod(x, y) fmod(x,y) +#define SkScalarFraction(x) fmod(x, 1.0) +#define SkScalarSqrt(x) sqrt(x) +#define SkScalarPow(b, e) pow(b, e) + +#define SkScalarSin(radians) sin(radians) +#define SkScalarCos(radians) cos(radians) +#define SkScalarTan(radians) tan(radians) +#define SkScalarASin(val) asin(val) +#define SkScalarACos(val) acos(val) +#define SkScalarATan2(y, x) atan2(y,x) +#define SkScalarExp(x) exp(x) +#define SkScalarLog(x) log(x) +#define SkScalarLog2(x) log2(x) + +#endif + +////////////////////////////////////////////////////////////////////////////////////////////////// + +#define SkIntToScalar(x) static_cast(x) +#define SkScalarTruncToInt(x) static_cast(x) + +#define SkScalarToFloat(x) static_cast(x) +#define SkFloatToScalar(x) static_cast(x) +#define SkScalarToDouble(x) static_cast(x) +#define SkDoubleToScalar(x) static_cast(x) + +#define SK_ScalarMin (-SK_ScalarMax) + +static inline bool SkScalarIsNaN(SkScalar x) { return x != x; } + +/** Returns true if x is not NaN and not infinite + */ +static inline bool SkScalarIsFinite(SkScalar x) { + // We rely on the following behavior of infinities and nans + // 0 * finite --> 0 + // 0 * infinity --> NaN + // 0 * NaN --> NaN + SkScalar prod = x * 0; + // At this point, prod will either be NaN or 0 + return !SkScalarIsNaN(prod); +} + +static inline bool SkScalarsAreFinite(SkScalar a, SkScalar b) { + SkScalar prod = 0; + prod *= a; + prod *= b; + // At this point, prod will either be NaN or 0 + return !SkScalarIsNaN(prod); +} + +static inline bool SkScalarsAreFinite(const SkScalar array[], int count) { + SkScalar prod = 0; + for (int i = 0; i < count; ++i) { + prod *= array[i]; + } + // At this point, prod will either be NaN or 0 + return !SkScalarIsNaN(prod); +} /** * Variant of SkScalarRoundToInt, that performs the rounding step (adding 0.5) explicitly using @@ -103,88 +168,38 @@ static inline int SkDScalarRoundToInt(SkScalar x) { return (int)floor(xx); } -/** Returns the absolute value of the specified SkScalar -*/ -#define SkScalarAbs(x) sk_float_abs(x) -/** Return x with the sign of y - */ -#define SkScalarCopySign(x, y) sk_float_copysign(x, y) -/** Returns the value pinned between 0 and max inclusive -*/ -inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) { - return x < 0 ? 0 : x > max ? max : x; +static inline SkScalar SkScalarClampMax(SkScalar x, SkScalar max) { + x = SkTMin(x, max); + x = SkTMax(x, 0); + return x; } -/** Returns the value pinned between min and max inclusive -*/ -inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) { - return x < min ? min : x > max ? max : x; + +static inline SkScalar SkScalarPin(SkScalar x, SkScalar min, SkScalar max) { + return SkTPin(x, min, max); } -/** Returns the specified SkScalar squared (x*x) -*/ -inline SkScalar SkScalarSquare(SkScalar x) { return x * x; } -/** Returns the product of two SkScalars -*/ -#define SkScalarMul(a, b) ((float)(a) * (b)) -/** Returns the product of two SkScalars plus a third SkScalar -*/ -#define SkScalarMulAdd(a, b, c) ((float)(a) * (b) + (c)) -/** Returns the quotient of two SkScalars (a/b) -*/ -#define SkScalarDiv(a, b) ((float)(a) / (b)) -/** Returns the mod of two SkScalars (a mod b) -*/ -#define SkScalarMod(x,y) sk_float_mod(x,y) -/** Returns the product of the first two arguments, divided by the third argument -*/ -#define SkScalarMulDiv(a, b, c) ((float)(a) * (b) / (c)) -/** Returns the multiplicative inverse of the SkScalar (1/x) -*/ + +SkScalar SkScalarSinCos(SkScalar radians, SkScalar* cosValue); + +static inline SkScalar SkScalarSquare(SkScalar x) { return x * x; } + +#define SkScalarMul(a, b) ((SkScalar)(a) * (b)) +#define SkScalarMulAdd(a, b, c) ((SkScalar)(a) * (b) + (c)) +#define SkScalarMulDiv(a, b, c) ((SkScalar)(a) * (b) / (c)) #define SkScalarInvert(x) (SK_Scalar1 / (x)) #define SkScalarFastInvert(x) (SK_Scalar1 / (x)) -/** Returns the square root of the SkScalar -*/ -#define SkScalarSqrt(x) sk_float_sqrt(x) -/** Returns b to the e -*/ -#define SkScalarPow(b, e) sk_float_pow(b, e) -/** Returns the average of two SkScalars (a+b)/2 -*/ -#define SkScalarAve(a, b) (((a) + (b)) * 0.5f) -/** Returns one half of the specified SkScalar -*/ -#define SkScalarHalf(a) ((a) * 0.5f) - -#define SK_ScalarSqrt2 1.41421356f -#define SK_ScalarPI 3.14159265f -#define SK_ScalarTanPIOver8 0.414213562f -#define SK_ScalarRoot2Over2 0.707106781f +#define SkScalarAve(a, b) (((a) + (b)) * SK_ScalarHalf) +#define SkScalarHalf(a) ((a) * SK_ScalarHalf) #define SkDegreesToRadians(degrees) ((degrees) * (SK_ScalarPI / 180)) #define SkRadiansToDegrees(radians) ((radians) * (180 / SK_ScalarPI)) -float SkScalarSinCos(SkScalar radians, SkScalar* cosValue); -#define SkScalarSin(radians) (float)sk_float_sin(radians) -#define SkScalarCos(radians) (float)sk_float_cos(radians) -#define SkScalarTan(radians) (float)sk_float_tan(radians) -#define SkScalarASin(val) (float)sk_float_asin(val) -#define SkScalarACos(val) (float)sk_float_acos(val) -#define SkScalarATan2(y, x) (float)sk_float_atan2(y,x) -#define SkScalarExp(x) (float)sk_float_exp(x) -#define SkScalarLog(x) (float)sk_float_log(x) -inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; } -inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; } +static inline SkScalar SkMaxScalar(SkScalar a, SkScalar b) { return a > b ? a : b; } +static inline SkScalar SkMinScalar(SkScalar a, SkScalar b) { return a < b ? a : b; } static inline bool SkScalarIsInt(SkScalar x) { - return x == (float)(int)x; + return x == (SkScalar)(int)x; } -// DEPRECATED : use ToInt or ToScalar variant -#ifdef SK_SUPPORT_DEPRECATED_SCALARROUND -# define SkScalarFloor(x) SkScalarFloorToInt(x) -# define SkScalarCeil(x) SkScalarCeilToInt(x) -# define SkScalarRound(x) SkScalarRoundToInt(x) -#endif - /** * Returns -1 || 0 || 1 depending on the sign of value: * -1 if x < 0 @@ -209,7 +224,7 @@ static inline bool SkScalarNearlyZero(SkScalar x, } static inline bool SkScalarNearlyEqual(SkScalar x, SkScalar y, - SkScalar tolerance = SK_ScalarNearlyZero) { + SkScalar tolerance = SK_ScalarNearlyZero) { SkASSERT(tolerance >= 0); return SkScalarAbs(x-y) <= tolerance; } diff --git a/gfx/skia/skia/include/core/SkShader.h b/gfx/skia/skia/include/core/SkShader.h index e5af40dd7a18..34cb648022ca 100644 --- a/gfx/skia/skia/include/core/SkShader.h +++ b/gfx/skia/skia/include/core/SkShader.h @@ -5,7 +5,6 @@ * found in the LICENSE file. */ - #ifndef SkShader_DEFINED #define SkShader_DEFINED @@ -20,7 +19,7 @@ class SkPath; class SkPicture; class SkXfermode; class GrContext; -class GrEffect; +class GrFragmentProcessor; /** \class SkShader * @@ -34,8 +33,6 @@ class GrEffect; */ class SK_API SkShader : public SkFlattenable { public: - SK_DECLARE_INST_COUNT(SkShader) - SkShader(const SkMatrix* localMatrix = NULL); virtual ~SkShader(); @@ -47,14 +44,6 @@ public: */ const SkMatrix& getLocalMatrix() const { return fLocalMatrix; } - /** - * Returns true if the local matrix is not an identity matrix. - * - * FIXME: This can be incorrect for a Shader with its own local matrix - * that is also wrapped via CreateLocalMatrixShader. - */ - bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); } - enum TileMode { /** replicate the edge color if the shader draws outside of its * original bounds @@ -73,8 +62,10 @@ public: /** only draw within the original domain, return 0 everywhere else */ kDecal_TileMode, #endif + }; - kTileModeCount + enum { + kTileModeCount = kMirror_TileMode + 1 }; // override these in your subclass @@ -120,14 +111,11 @@ public: * ContextRec acts as a parameter bundle for creating Contexts. */ struct ContextRec { - ContextRec() : fDevice(NULL), fPaint(NULL), fMatrix(NULL), fLocalMatrix(NULL) {} - ContextRec(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix) - : fDevice(&device) - , fPaint(&paint) + ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM) + : fPaint(&paint) , fMatrix(&matrix) - , fLocalMatrix(NULL) {} + , fLocalMatrix(localM) {} - const SkBitmap* fDevice; // the bitmap we are drawing into const SkPaint* fPaint; // the current paint associated with the draw const SkMatrix* fMatrix; // the current matrix in the canvas const SkMatrix* fLocalMatrix; // optional local matrix @@ -185,6 +173,9 @@ public: return SkShader::CanCallShadeSpan16(this->getFlags()); } + // Notification from blitter::blitMask in case we need to see the non-alpha channels + virtual void set3DMask(const SkMask*) {} + protected: // Reference to shader, so we don't have to dupe information. const SkShader& fShader; @@ -232,68 +223,17 @@ public: } /** - Gives method bitmap should be read to implement a shader. - Also determines number and interpretation of "extra" parameters returned - by asABitmap + * Returns true if this shader is just a bitmap, and if not null, returns the bitmap, + * localMatrix, and tilemodes. If this is not a bitmap, returns false and ignores the + * out-parameters. */ - enum BitmapType { - kNone_BitmapType, //onIsABitmap(outTexture, outMatrix, xy); + } - kLast_BitmapType = kLinear_BitmapType - }; - /** Optional methods for shaders that can pretend to be a bitmap/texture - to play along with opengl. Default just returns kNone_BitmapType and - ignores the out parameters. - - @param outTexture if non-NULL will be the bitmap representing the shader - after return. - @param outMatrix if non-NULL will be the matrix to apply to vertices - to access the bitmap after return. - @param xy if non-NULL will be the tile modes that should be - used to access the bitmap after return. - @param twoPointRadialParams Two extra return values needed for two point - radial bitmaps. The first is the x-offset of - the second point and the second is the radius - about the first point. - */ - virtual BitmapType asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, - TileMode xy[2]) const; + bool isABitmap() const { + return this->isABitmap(nullptr, nullptr, nullptr); + } /** * If the shader subclass can be represented as a gradient, asAGradient @@ -317,7 +257,7 @@ public: * fPoint[0] and fPoint[1] are the end-points of the gradient * Radial: * fPoint[0] and fRadius[0] are the center and radius - * Radial2: + * Conical: * fPoint[0] and fRadius[0] are the center and radius of the 1st circle * fPoint[1] and fRadius[1] are the center and radius of the 2nd circle * Sweep: @@ -329,7 +269,6 @@ public: kColor_GradientType, kLinear_GradientType, kRadial_GradientType, - kRadial2_GradientType, kSweep_GradientType, kConical_GradientType, kLast_GradientType = kConical_GradientType @@ -363,35 +302,43 @@ public: const SkXfermode* fMode; }; - virtual bool asACompose(ComposeRec* rec) const { return false; } + virtual bool asACompose(ComposeRec*) const { return false; } /** - * Returns true if the shader subclass succeeds in creating an effect or if none is required. - * False is returned if it fails or if there is not an implementation of this method in the - * shader subclass. + * Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is + * returned if there is no GPU implementation. * - * On success an implementation of this method must inspect the SkPaint and set paintColor to - * the color the effect expects as its input color. If the SkShader wishes to emit a solid - * color then it should set paintColor to that color and not create an effect. Note that - * GrColor is always premul. The common patterns are to convert paint's SkColor to GrColor or - * to extract paint's alpha and replicate it to all channels in paintColor. Upon failure - * paintColor should not be modified. It is not recommended to specialize the effect to - * the paint's color as then many GPU shaders may be generated. + * The GPU device does not call SkShader::createContext(), instead we pass the view matrix, + * local matrix, and filter quality directly. * - * The GrContext may be used by the effect to create textures. The GPU device does not - * call createContext. Instead we pass the SkPaint here in case the shader needs paint info. + * The GrContext may be used by the to create textures that are required by the returned + * processor. + * + * The returned GrFragmentProcessor should expect an unpremultiplied input color and + * produce a premultiplied output. */ - virtual bool asNewEffect(GrContext* context, const SkPaint& paint, - const SkMatrix* localMatrixOrNull, GrColor* paintColor, - GrEffect** effect) const; + virtual const GrFragmentProcessor* asFragmentProcessor(GrContext*, + const SkMatrix& viewMatrix, + const SkMatrix* localMatrix, + SkFilterQuality) const; + + /** + * If the shader can represent its "average" luminance in a single color, return true and + * if color is not NULL, return that color. If it cannot, return false and ignore the color + * parameter. + * + * Note: if this returns true, the returned color will always be opaque, as only the RGB + * components are used to compute luminance. + */ + bool asLuminanceColor(SkColor*) const; #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK /** * If the shader is a custom shader which has data the caller might want, call this function * to get that data. */ - virtual bool asACustomShader(void** customData) const { return false; } + virtual bool asACustomShader(void** /* customData */) const { return false; } #endif ////////////////////////////////////////////////////////////////////////// @@ -402,6 +349,12 @@ public: */ static SkShader* CreateEmptyShader(); + /** + * Call this to create a new shader that just draws the specified color. This should always + * draw the same as a paint with this color (and no shader). + */ + static SkShader* CreateColorShader(SkColor); + /** Call this to create a new shader that will draw with the specified bitmap. * * If the bitmap cannot be used (e.g. has no pixels, or its dimensions @@ -420,18 +373,26 @@ public: TileMode tmx, TileMode tmy, const SkMatrix* localMatrix = NULL); + // NOTE: You can create an SkImage Shader with SkImage::newShader(). + /** Call this to create a new shader that will draw with the specified picture. * * @param src The picture to use inside the shader (if not NULL, its ref count * is incremented). The SkPicture must not be changed after * successfully creating a picture shader. - * FIXME: src cannot be const due to SkCanvas::drawPicture * @param tmx The tiling mode to use when sampling the bitmap in the x-direction. * @param tmy The tiling mode to use when sampling the bitmap in the y-direction. + * @param tile The tile rectangle in picture coordinates: this represents the subset + * (or superset) of the picture used when building a tile. It is not + * affected by localMatrix and does not imply scaling (only translation + * and cropping). If null, the tile rect is considered equal to the picture + * bounds. * @return Returns a new shader object. Note: this function never returns null. */ - static SkShader* CreatePictureShader(SkPicture* src, TileMode tmx, TileMode tmy, - const SkMatrix* localMatrix = NULL); + static SkShader* CreatePictureShader(const SkPicture* src, + TileMode tmx, TileMode tmy, + const SkMatrix* localMatrix, + const SkRect* tile); /** * Return a shader that will apply the specified localMatrix to the proxy shader. @@ -454,8 +415,7 @@ public: SK_DEFINE_FLATTENABLE_TYPE(SkShader) protected: - SkShader(SkReadBuffer& ); - virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; + void flatten(SkWriteBuffer&) const override; bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const; @@ -465,6 +425,14 @@ protected: */ virtual Context* onCreateContext(const ContextRec&, void* storage) const; + virtual bool onAsLuminanceColor(SkColor*) const { + return false; + } + + virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const { + return false; + } + private: // This is essentially const, but not officially so it can be modified in // constructors. @@ -472,6 +440,7 @@ private: // So the SkLocalMatrixShader can whack fLocalMatrix in its SkReadBuffer constructor. friend class SkLocalMatrixShader; + friend class SkBitmapProcShader; // for computeTotalInverse() typedef SkFlattenable INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkStream.h b/gfx/skia/skia/include/core/SkStream.h index 516b036a55e6..2279f9ff10ec 100644 --- a/gfx/skia/skia/include/core/SkStream.h +++ b/gfx/skia/skia/include/core/SkStream.h @@ -36,17 +36,17 @@ class SkStreamMemory; * no more data (at EOF or hit an error). The caller should *not* call again * in hopes of fulfilling more of the request. */ -class SK_API SkStream : public SkRefCnt { //TODO: remove SkRefCnt +class SK_API SkStream : public SkNoncopyable { public: + virtual ~SkStream() {} + /** * Attempts to open the specified file, and return a stream to it (using - * mmap if available). On success, the caller must call unref() on the - * returned object. On failure, returns NULL. + * mmap if available). On success, the caller is responsible for deleting. + * On failure, returns NULL. */ static SkStreamAsset* NewFromFile(const char path[]); - SK_DECLARE_INST_COUNT(SkStream) - /** Reads or skips size number of bytes. * If buffer == NULL, skip size bytes, return how many were skipped. * If buffer != NULL, copy size bytes into buffer, return how many were copied. @@ -63,6 +63,20 @@ public: return this->read(NULL, size); } + /** + * Attempt to peek at size bytes. + * If this stream supports peeking, and it can peek size bytes, copy size + * bytes into buffer, and return true. + * If the stream does not support peeking, or cannot peek size bytes, + * return false and leave buffer unchanged. + * The stream is guaranteed to be in the same visible state after this + * call, regardless of success or failure. + * @param buffer Must not be NULL. Destination to copy bytes. + * @param size Number of bytes to copy. + * @return Whether the peek was performed. + */ + virtual bool peek(void* /* buffer */, size_t /* size */) const { return false; } + /** Returns true when all the bytes in the stream have been read. * This may return true early (when there are no more bytes to be read) * or late (after the first unsuccessful read). @@ -81,12 +95,6 @@ public: SkScalar readScalar(); size_t readPackedUInt(); - /** - * Reconstitute an SkData object that was written to the stream - * using SkWStream::writeData(). - */ - SkData* readData(); - //SkStreamRewindable /** Rewinds to the beginning of the stream. Returns true if the stream is known * to be at the beginning after this call returns. @@ -108,13 +116,13 @@ public: * If an attempt is made to seek past the end of the stream, the position will be set * to the end of the stream. */ - virtual bool seek(size_t position) { return false; } + virtual bool seek(size_t /*position*/) { return false; } /** Seeks to an relative offset in the stream. If this cannot be done, returns false. * If an attempt is made to move to a position outside the stream, the position will be set * to the closest point within the stream (beginning or end). */ - virtual bool move(long offset) { return false; } + virtual bool move(long /*offset*/) { return false; } /** Duplicates this stream. If this cannot be done, returns NULL. * The returned stream will be positioned the same as this stream. @@ -131,53 +139,48 @@ public: /** Returns the starting address for the data. If this cannot be done, returns NULL. */ //TODO: replace with virtual const SkData* getData() virtual const void* getMemoryBase() { return NULL; } - -private: - typedef SkRefCnt INHERITED; }; /** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */ class SK_API SkStreamRewindable : public SkStream { public: - virtual bool rewind() SK_OVERRIDE = 0; - virtual SkStreamRewindable* duplicate() const SK_OVERRIDE = 0; + bool rewind() override = 0; + SkStreamRewindable* duplicate() const override = 0; }; /** SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required. */ class SK_API SkStreamSeekable : public SkStreamRewindable { public: - virtual SkStreamSeekable* duplicate() const SK_OVERRIDE = 0; + SkStreamSeekable* duplicate() const override = 0; - virtual bool hasPosition() const SK_OVERRIDE { return true; } - virtual size_t getPosition() const SK_OVERRIDE = 0; - virtual bool seek(size_t position) SK_OVERRIDE = 0; - virtual bool move(long offset) SK_OVERRIDE = 0; - virtual SkStreamSeekable* fork() const SK_OVERRIDE = 0; + bool hasPosition() const override { return true; } + size_t getPosition() const override = 0; + bool seek(size_t position) override = 0; + bool move(long offset) override = 0; + SkStreamSeekable* fork() const override = 0; }; /** SkStreamAsset is a SkStreamSeekable for which getLength is required. */ class SK_API SkStreamAsset : public SkStreamSeekable { public: - virtual SkStreamAsset* duplicate() const SK_OVERRIDE = 0; - virtual SkStreamAsset* fork() const SK_OVERRIDE = 0; + SkStreamAsset* duplicate() const override = 0; + SkStreamAsset* fork() const override = 0; - virtual bool hasLength() const SK_OVERRIDE { return true; } - virtual size_t getLength() const SK_OVERRIDE = 0; + bool hasLength() const override { return true; } + size_t getLength() const override = 0; }; /** SkStreamMemory is a SkStreamAsset for which getMemoryBase is required. */ class SK_API SkStreamMemory : public SkStreamAsset { public: - virtual SkStreamMemory* duplicate() const SK_OVERRIDE = 0; - virtual SkStreamMemory* fork() const SK_OVERRIDE = 0; + SkStreamMemory* duplicate() const override = 0; + SkStreamMemory* fork() const override = 0; - virtual const void* getMemoryBase() SK_OVERRIDE = 0; + const void* getMemoryBase() override = 0; }; class SK_API SkWStream : SkNoncopyable { public: - SK_DECLARE_INST_COUNT_ROOT(SkWStream) - virtual ~SkWStream(); /** Called to write bytes to a SkWStream. Returns true on success @@ -209,16 +212,6 @@ public: bool writeStream(SkStream* input, size_t length); - /** - * Append an SkData object to the stream, such that it can be read - * out of the stream using SkStream::readData(). - * - * Note that the encoding method used to write the SkData object - * to the stream may change over time. This method DOES NOT - * just write the raw content of the SkData object to the stream. - */ - bool writeData(const SkData*); - /** * This returns the number of bytes in the stream required to store * 'value'. @@ -231,13 +224,9 @@ public: #include "SkString.h" #include -struct SkFILE; - /** A stream that wraps a C FILE* file stream. */ class SK_API SkFILEStream : public SkStreamAsset { public: - SK_DECLARE_INST_COUNT(SkFILEStream) - /** Initialize the stream by calling sk_fopen on the specified path. * This internal stream will be closed in the destructor. */ @@ -264,23 +253,23 @@ public: */ void setPath(const char path[]); - virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; - virtual bool isAtEnd() const SK_OVERRIDE; + size_t read(void* buffer, size_t size) override; + bool isAtEnd() const override; - virtual bool rewind() SK_OVERRIDE; - virtual SkStreamAsset* duplicate() const SK_OVERRIDE; + bool rewind() override; + SkStreamAsset* duplicate() const override; - virtual size_t getPosition() const SK_OVERRIDE; - virtual bool seek(size_t position) SK_OVERRIDE; - virtual bool move(long offset) SK_OVERRIDE; - virtual SkStreamAsset* fork() const SK_OVERRIDE; + size_t getPosition() const override; + bool seek(size_t position) override; + bool move(long offset) override; + SkStreamAsset* fork() const override; - virtual size_t getLength() const SK_OVERRIDE; + size_t getLength() const override; - virtual const void* getMemoryBase() SK_OVERRIDE; + const void* getMemoryBase() override; private: - SkFILE* fFILE; + FILE* fFILE; SkString fName; Ownership fOwnership; // fData is lazilly initialized when needed. @@ -291,8 +280,6 @@ private: class SK_API SkMemoryStream : public SkStreamMemory { public: - SK_DECLARE_INST_COUNT(SkMemoryStream) - SkMemoryStream(); /** We allocate (and free) the memory. Write to it via getMemoryBase() */ @@ -334,22 +321,23 @@ public: void skipToAlign4(); const void* getAtPos(); - size_t peek() const { return fOffset; } - virtual size_t read(void* buffer, size_t size) SK_OVERRIDE; - virtual bool isAtEnd() const SK_OVERRIDE; + size_t read(void* buffer, size_t size) override; + bool isAtEnd() const override; - virtual bool rewind() SK_OVERRIDE; - virtual SkMemoryStream* duplicate() const SK_OVERRIDE; + bool peek(void* buffer, size_t size) const override; - virtual size_t getPosition() const SK_OVERRIDE; - virtual bool seek(size_t position) SK_OVERRIDE; - virtual bool move(long offset) SK_OVERRIDE; - virtual SkMemoryStream* fork() const SK_OVERRIDE; + bool rewind() override; + SkMemoryStream* duplicate() const override; - virtual size_t getLength() const SK_OVERRIDE; + size_t getPosition() const override; + bool seek(size_t position) override; + bool move(long offset) override; + SkMemoryStream* fork() const override; - virtual const void* getMemoryBase() SK_OVERRIDE; + size_t getLength() const override; + + const void* getMemoryBase() override; private: SkData* fData; @@ -362,8 +350,6 @@ private: class SK_API SkFILEWStream : public SkWStream { public: - SK_DECLARE_INST_COUNT(SkFILEWStream) - SkFILEWStream(const char path[]); virtual ~SkFILEWStream(); @@ -371,23 +357,21 @@ public: */ bool isValid() const { return fFILE != NULL; } - virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - virtual void flush() SK_OVERRIDE; - virtual size_t bytesWritten() const SK_OVERRIDE; + bool write(const void* buffer, size_t size) override; + void flush() override; + size_t bytesWritten() const override; private: - SkFILE* fFILE; + FILE* fFILE; typedef SkWStream INHERITED; }; class SkMemoryWStream : public SkWStream { public: - SK_DECLARE_INST_COUNT(SkMemoryWStream) - SkMemoryWStream(void* buffer, size_t size); - virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; } + bool write(const void* buffer, size_t size) override; + size_t bytesWritten() const override { return fBytesWritten; } private: char* fBuffer; @@ -399,13 +383,11 @@ private: class SK_API SkDynamicMemoryWStream : public SkWStream { public: - SK_DECLARE_INST_COUNT(SkDynamicMemoryWStream) - SkDynamicMemoryWStream(); virtual ~SkDynamicMemoryWStream(); - virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; } + bool write(const void* buffer, size_t size) override; + size_t bytesWritten() const override { return fBytesWritten; } // random access write // modifies stream and returns true if offset + size is less than or equal to getOffset() bool write(const void* buffer, size_t offset, size_t size); @@ -414,6 +396,7 @@ public: // copy what has been written to the stream into dst void copyTo(void* dst) const; + void writeToStream(SkWStream* dst) const; /** * Return a copy of the data written so far. This call is responsible for @@ -447,12 +430,11 @@ private: class SK_API SkDebugWStream : public SkWStream { public: SkDebugWStream() : fBytesWritten(0) {} - SK_DECLARE_INST_COUNT(SkDebugWStream) // overrides - virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - virtual void newline() SK_OVERRIDE; - virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; } + bool write(const void* buffer, size_t size) override; + void newline() override; + size_t bytesWritten() const override { return fBytesWritten; } private: size_t fBytesWritten; diff --git a/gfx/skia/skia/include/core/SkString.h b/gfx/skia/skia/include/core/SkString.h index bc06cb0aba63..9229d808a63d 100644 --- a/gfx/skia/skia/include/core/SkString.h +++ b/gfx/skia/skia/include/core/SkString.h @@ -39,6 +39,12 @@ static int SkStrFind(const char string[], const char substring[]) { return SkToS32(first - &string[0]); } +static int SkStrFindLastOf(const char string[], const char subchar) { + const char* last = strrchr(string, subchar); + if (NULL == last) return -1; + return SkToS32(last - &string[0]); +} + static bool SkStrContains(const char string[], const char substring[]) { SkASSERT(string); SkASSERT(substring); @@ -58,7 +64,23 @@ static inline char *SkStrDup(const char string[]) { return ret; } - +/* + * The SkStrAppend... methods will write into the provided buffer, assuming it is large enough. + * Each method has an associated const (e.g. SkStrAppendU32_MaxSize) which will be the largest + * value needed for that method's buffer. + * + * char storage[SkStrAppendU32_MaxSize]; + * SkStrAppendU32(storage, value); + * + * Note : none of the SkStrAppend... methods write a terminating 0 to their buffers. Instead, + * the methods return the ptr to the end of the written part of the buffer. This can be used + * to compute the length, and/or know where to write a 0 if that is desired. + * + * char storage[SkStrAppendU32_MaxSize + 1]; + * char* stop = SkStrAppendU32(storage, value); + * size_t len = stop - storage; + * *stop = 0; // valid, since storage was 1 byte larger than the max. + */ #define SkStrAppendU32_MaxSize 10 char* SkStrAppendU32(char buffer[], uint32_t); @@ -136,6 +158,9 @@ public: int find(const char substring[]) const { return SkStrFind(fRec->data(), substring); } + int findLastOf(const char subchar) const { + return SkStrFindLastOf(fRec->data(), subchar); + } friend bool operator==(const SkString& a, const SkString& b) { return a.equals(b); @@ -153,6 +178,7 @@ public: char& operator[](size_t n) { return this->writable_str()[n]; } void reset(); + /** Destructive resize, does not preserve contents. */ void resize(size_t len) { this->set(NULL, len); } void set(const SkString& src) { *this = src; } void set(const char text[]); @@ -195,6 +221,7 @@ public: void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3); void appendVAList(const char format[], va_list); void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3); + void prependVAList(const char format[], va_list); void remove(size_t offset, size_t length); @@ -221,7 +248,6 @@ private: Rec* fRec; #ifdef SK_DEBUG - const char* fStr; void validate() const; #else void validate() const {} diff --git a/gfx/skia/skia/include/core/SkStrokeRec.h b/gfx/skia/skia/include/core/SkStrokeRec.h index 0c5892f62584..32e54405632f 100644 --- a/gfx/skia/skia/include/core/SkStrokeRec.h +++ b/gfx/skia/skia/include/core/SkStrokeRec.h @@ -12,6 +12,7 @@ class SkPath; +SK_BEGIN_REQUIRE_DENSE class SkStrokeRec { public: enum InitStyle { @@ -19,10 +20,8 @@ public: kFill_InitStyle }; SkStrokeRec(InitStyle style); - - SkStrokeRec(const SkStrokeRec&); - SkStrokeRec(const SkPaint&, SkPaint::Style); - explicit SkStrokeRec(const SkPaint&); + SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1); + explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1); enum Style { kHairline_Style, @@ -37,8 +36,8 @@ public: Style getStyle() const; SkScalar getWidth() const { return fWidth; } SkScalar getMiter() const { return fMiterLimit; } - SkPaint::Cap getCap() const { return fCap; } - SkPaint::Join getJoin() const { return fJoin; } + SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; } + SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; } bool isHairlineStyle() const { return kHairline_Style == this->getStyle(); @@ -64,6 +63,11 @@ public: fMiterLimit = miterLimit; } + void setResScale(SkScalar rs) { + SkASSERT(rs > 0 && SkScalarIsFinite(rs)); + fResScale = rs; + } + /** * Returns true if this specifes any thick stroking, i.e. applyToPath() * will return true. @@ -85,23 +89,43 @@ public: */ bool applyToPath(SkPath* dst, const SkPath& src) const; - bool operator==(const SkStrokeRec& other) const { - return fWidth == other.fWidth && - fMiterLimit == other.fMiterLimit && - fCap == other.fCap && - fJoin == other.fJoin && - fStrokeAndFill == other.fStrokeAndFill; + /** + * Apply these stroke parameters to a paint. + */ + void applyToPaint(SkPaint* paint) const; + + /** + * Compare if two SkStrokeRecs have an equal effect on a path. + * Equal SkStrokeRecs produce equal paths. Equality of produced + * paths does not take the ResScale parameter into account. + */ + bool hasEqualEffect(const SkStrokeRec& other) const { + if (!this->needToApply()) { + return this->getStyle() == other.getStyle(); + } + return fWidth == other.fWidth && + fMiterLimit == other.fMiterLimit && + fCap == other.fCap && + fJoin == other.fJoin && + fStrokeAndFill == other.fStrokeAndFill; } private: - void init(const SkPaint& paint, SkPaint::Style style); - + void init(const SkPaint&, SkPaint::Style, SkScalar resScale); + SkScalar fResScale; SkScalar fWidth; SkScalar fMiterLimit; - SkPaint::Cap fCap; - SkPaint::Join fJoin; - bool fStrokeAndFill; + // The following three members are packed together into a single u32. + // This is to avoid unnecessary padding and ensure binary equality for + // hashing (because the padded areas might contain garbage values). + // + // fCap and fJoin are larger than needed to avoid having to initialize + // any pad values + uint32_t fCap : 16; // SkPaint::Cap + uint32_t fJoin : 15; // SkPaint::Join + uint32_t fStrokeAndFill : 1; // bool }; +SK_END_REQUIRE_DENSE #endif diff --git a/gfx/skia/skia/include/core/SkSurface.h b/gfx/skia/skia/include/core/SkSurface.h index cb5133ae003e..57527ed33afa 100644 --- a/gfx/skia/skia/include/core/SkSurface.h +++ b/gfx/skia/skia/include/core/SkSurface.h @@ -10,6 +10,7 @@ #include "SkRefCnt.h" #include "SkImage.h" +#include "SkSurfaceProps.h" class SkCanvas; class SkPaint; @@ -23,10 +24,23 @@ class GrRenderTarget; * * To draw into a canvas, first create the appropriate type of Surface, and * then request the canvas from the surface. + * + * SkSurface always has non-zero dimensions. If there is a request for a new surface, and either + * of the requested dimensions are zero, then NULL will be returned. */ class SK_API SkSurface : public SkRefCnt { public: - SK_DECLARE_INST_COUNT(SkSurface) + /** + * Indicates whether a new surface or image should count against a cache budget. Currently this + * is only used by the GPU backend (sw-raster surfaces and images are never counted against the + * resource cache budget.) + */ + enum Budgeted { + /** The surface or image does not count against the cache budget. */ + kNo_Budgeted, + /** The surface or image counts against the cache budget. */ + kYes_Budgeted + }; /** * Create a new surface, using the specified pixels/rowbytes as its @@ -35,7 +49,8 @@ public: * If the requested surface cannot be created, or the request is not a * supported configuration, NULL will be returned. */ - static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes); + static SkSurface* NewRasterDirect(const SkImageInfo&, void* pixels, size_t rowBytes, + const SkSurfaceProps* = NULL); /** * The same as NewRasterDirect, but also accepts a call-back routine, which is invoked @@ -43,7 +58,7 @@ public: */ static SkSurface* NewRasterDirectReleaseProc(const SkImageInfo&, void* pixels, size_t rowBytes, void (*releaseProc)(void* pixels, void* context), - void* context); + void* context, const SkSurfaceProps* = NULL); /** * Return a new surface, with the memory for the pixels automatically @@ -52,70 +67,59 @@ public: * If the requested surface cannot be created, or the request is not a * supported configuration, NULL will be returned. */ - static SkSurface* NewRaster(const SkImageInfo&); + static SkSurface* NewRaster(const SkImageInfo&, const SkSurfaceProps* = NULL); /** * Helper version of NewRaster. It creates a SkImageInfo with the * specified width and height, and populates the rest of info to match * pixels in SkPMColor format. */ - static SkSurface* NewRasterPMColor(int width, int height) { - return NewRaster(SkImageInfo::MakeN32Premul(width, height)); + static SkSurface* NewRasterN32Premul(int width, int height, const SkSurfaceProps* props = NULL) { + return NewRaster(SkImageInfo::MakeN32Premul(width, height), props); } - /** - * Text rendering modes that can be passed to NewRenderTarget* - */ - enum TextRenderMode { - /** - * This will use the standard text rendering method - */ - kStandard_TextRenderMode, - /** - * This will use signed distance fields for text rendering when possible - */ - kDistanceField_TextRenderMode, - }; - - enum RenderTargetFlags { - kNone_RenderTargetFlag = 0x0, - /* - * By default a RenderTarget-based surface will be cleared on creation. - * Pass in this flag to prevent the clear from happening. - */ - kDontClear_RenderTargetFlag = 0x01, - }; - /** * Return a new surface using the specified render target. */ - static SkSurface* NewRenderTargetDirect(GrRenderTarget*, - TextRenderMode trm = kStandard_TextRenderMode, - RenderTargetFlags flags = kNone_RenderTargetFlag); + static SkSurface* NewRenderTargetDirect(GrRenderTarget*, const SkSurfaceProps*); + + static SkSurface* NewRenderTargetDirect(GrRenderTarget* target) { + return NewRenderTargetDirect(target, NULL); + } + + /** + * Used to wrap a pre-existing backend 3D API texture as a SkSurface. The kRenderTarget flag + * must be set on GrBackendTextureDesc for this to succeed. Skia will not assume ownership + * of the texture and the client must ensure the texture is valid for the lifetime of the + * SkSurface. + */ + static SkSurface* NewFromBackendTexture(GrContext*, const GrBackendTextureDesc&, + const SkSurfaceProps*); + // Legacy alias + static SkSurface* NewWrappedRenderTarget(GrContext* ctx, const GrBackendTextureDesc& desc, + const SkSurfaceProps* props) { + return NewFromBackendTexture(ctx, desc, props); + } + + + /** + * Used to wrap a pre-existing 3D API rendering target as a SkSurface. Skia will not assume + * ownership of the render target and the client must ensure the render target is valid for the + * lifetime of the SkSurface. + */ + static SkSurface* NewFromBackendRenderTarget(GrContext*, const GrBackendRenderTargetDesc&, + const SkSurfaceProps*); /** * Return a new surface whose contents will be drawn to an offscreen * render target, allocated by the surface. */ - static SkSurface* NewRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0, - TextRenderMode trm = kStandard_TextRenderMode, - RenderTargetFlags flags = kNone_RenderTargetFlag); + static SkSurface* NewRenderTarget(GrContext*, Budgeted, const SkImageInfo&, int sampleCount, + const SkSurfaceProps* = NULL); - /** - * Return a new surface whose contents will be drawn to an offscreen - * render target, allocated by the surface from the scratch texture pool - * managed by the GrContext. The scratch texture pool serves the purpose - * of retaining textures after they are no longer in use in order to - * re-use them later without having to re-allocate. Scratch textures - * should be used in cases where high turnover is expected. This allows, - * for example, the copy on write to recycle a texture from a recently - * released SkImage snapshot of the surface. - * Note: Scratch textures count against the GrContext's cached resource - * budget. - */ - static SkSurface* NewScratchRenderTarget(GrContext*, const SkImageInfo&, int sampleCount = 0, - TextRenderMode trm = kStandard_TextRenderMode, - RenderTargetFlags flags = kNone_RenderTargetFlag); + static SkSurface* NewRenderTarget(GrContext* gr, Budgeted b, const SkImageInfo& info) { + return NewRenderTarget(gr, b, info, 0, NULL); + } int width() const { return fWidth; } int height() const { return fHeight; } @@ -150,9 +154,45 @@ public: /** * Call this if the contents are about to change. This will (lazily) force a new * value to be returned from generationID() when it is called next. + * + * CAN WE DEPRECATE THIS? */ void notifyContentWillChange(ContentChangeMode mode); + enum BackendHandleAccess { + kFlushRead_BackendHandleAccess, //!< caller may read from the backend object + kFlushWrite_BackendHandleAccess, //!< caller may write to the backend object + kDiscardWrite_BackendHandleAccess, //!< caller must over-write the entire backend object + }; + + /* + * These are legacy aliases which will be removed soon + */ + static const BackendHandleAccess kFlushRead_TextureHandleAccess = + kFlushRead_BackendHandleAccess; + static const BackendHandleAccess kFlushWrite_TextureHandleAccess = + kFlushWrite_BackendHandleAccess; + static const BackendHandleAccess kDiscardWrite_TextureHandleAccess = + kDiscardWrite_BackendHandleAccess; + + + /** + * Retrieves the backend API handle of the texture used by this surface, or 0 if the surface + * is not backed by a GPU texture. + * + * The returned texture-handle is only valid until the next draw-call into the surface, + * or the surface is deleted. + */ + GrBackendObject getTextureHandle(BackendHandleAccess); + + /** + * Retrieves the backend API handle of the RenderTarget backing this surface. Callers must + * ensure this function returns 'true' or else the GrBackendObject will be invalid + * + * In OpenGL this will return the FramebufferObject ID. + */ + bool getRenderTargetHandle(GrBackendObject*, BackendHandleAccess); + /** * Return a canvas that will draw into this surface. This will always * return the same canvas for a given surface, and is manged/owned by the @@ -179,12 +219,14 @@ public: /** * Returns an image of the current state of the surface pixels up to this * point. Subsequent changes to the surface (by drawing into its canvas) - * will not be reflected in this image. + * will not be reflected in this image. If a copy must be made the Budgeted + * parameter controls whether it counts against the resource budget + * (currently for the gpu backend only). */ - SkImage* newImageSnapshot(); + SkImage* newImageSnapshot(Budgeted = kYes_Budgeted); /** - * Thought the caller could get a snapshot image explicitly, and draw that, + * Though the caller could get a snapshot image explicitly, and draw that, * it seems that directly drawing a surface into another canvas might be * a common pattern, and that we could possibly be more efficient, since * we'd know that the "snapshot" need only live until we've handed it off @@ -204,9 +246,32 @@ public: */ const void* peekPixels(SkImageInfo* info, size_t* rowBytes); + /** + * Copy the pixels from the surface into the specified buffer (pixels + rowBytes), + * converting them into the requested format (dstInfo). The surface pixels are read + * starting at the specified (srcX,srcY) location. + * + * The specified ImageInfo and (srcX,srcY) offset specifies a source rectangle + * + * srcR.setXYWH(srcX, srcY, dstInfo.width(), dstInfo.height()); + * + * srcR is intersected with the bounds of the base-layer. If this intersection is not empty, + * then we have two sets of pixels (of equal size). Replace the dst pixels with the + * corresponding src pixels, performing any colortype/alphatype transformations needed + * (in the case where the src and dst have different colortypes or alphatypes). + * + * This call can fail, returning false, for several reasons: + * - If srcR does not intersect the surface bounds. + * - If the requested colortype/alphatype cannot be converted from the surface's types. + */ + bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + int srcX, int srcY); + + const SkSurfaceProps& props() const { return fProps; } + protected: - SkSurface(int width, int height); - SkSurface(const SkImageInfo&); + SkSurface(int width, int height, const SkSurfaceProps*); + SkSurface(const SkImageInfo&, const SkSurfaceProps*); // called by subclass if their contents have changed void dirtyGenerationID() { @@ -214,9 +279,10 @@ protected: } private: - const int fWidth; - const int fHeight; - uint32_t fGenerationID; + const SkSurfaceProps fProps; + const int fWidth; + const int fHeight; + uint32_t fGenerationID; typedef SkRefCnt INHERITED; }; diff --git a/gfx/skia/skia/include/core/SkSurfaceProps.h b/gfx/skia/skia/include/core/SkSurfaceProps.h new file mode 100644 index 000000000000..735561f1dc91 --- /dev/null +++ b/gfx/skia/skia/include/core/SkSurfaceProps.h @@ -0,0 +1,86 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkSurfaceProps_DEFINED +#define SkSurfaceProps_DEFINED + +#include "SkTypes.h" + +/** + * Description of how the LCD strips are arranged for each pixel. If this is unknown, or the + * pixels are meant to be "portable" and/or transformed before showing (e.g. rotated, scaled) + * then use kUnknown_SkPixelGeometry. + */ +enum SkPixelGeometry { + kUnknown_SkPixelGeometry, + kRGB_H_SkPixelGeometry, + kBGR_H_SkPixelGeometry, + kRGB_V_SkPixelGeometry, + kBGR_V_SkPixelGeometry, +}; + +// Returns true iff geo is a known geometry and is RGB. +static inline bool SkPixelGeometryIsRGB(SkPixelGeometry geo) { + return kRGB_H_SkPixelGeometry == geo || kRGB_V_SkPixelGeometry == geo; +} + +// Returns true iff geo is a known geometry and is BGR. +static inline bool SkPixelGeometryIsBGR(SkPixelGeometry geo) { + return kBGR_H_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo; +} + +// Returns true iff geo is a known geometry and is horizontal. +static inline bool SkPixelGeometryIsH(SkPixelGeometry geo) { + return kRGB_H_SkPixelGeometry == geo || kBGR_H_SkPixelGeometry == geo; +} + +// Returns true iff geo is a known geometry and is vertical. +static inline bool SkPixelGeometryIsV(SkPixelGeometry geo) { + return kRGB_V_SkPixelGeometry == geo || kBGR_V_SkPixelGeometry == geo; +} + +/** + * Describes properties and constraints of a given SkSurface. The rendering engine can parse these + * during drawing, and can sometimes optimize its performance (e.g. disabling an expensive + * feature). + */ +class SK_API SkSurfaceProps { +public: + enum Flags { + kDisallowAntiAlias_Flag = 1 << 0, + kDisallowDither_Flag = 1 << 1, + kUseDeviceIndependentFonts_Flag = 1 << 2, + }; + /** Deprecated alias used by Chromium. Will be removed. */ + static const Flags kUseDistanceFieldFonts_Flag = kUseDeviceIndependentFonts_Flag; + + SkSurfaceProps(uint32_t flags, SkPixelGeometry); + + enum InitType { + kLegacyFontHost_InitType + }; + SkSurfaceProps(InitType); + SkSurfaceProps(uint32_t flags, InitType); + SkSurfaceProps(const SkSurfaceProps& other); + + uint32_t flags() const { return fFlags; } + SkPixelGeometry pixelGeometry() const { return fPixelGeometry; } + + bool isDisallowAA() const { return SkToBool(fFlags & kDisallowAntiAlias_Flag); } + bool isDisallowDither() const { return SkToBool(fFlags & kDisallowDither_Flag); } + bool isUseDeviceIndependentFonts() const { + return SkToBool(fFlags & kUseDeviceIndependentFonts_Flag); + } + +private: + SkSurfaceProps(); + + uint32_t fFlags; + SkPixelGeometry fPixelGeometry; +}; + +#endif diff --git a/gfx/skia/skia/include/core/SkTArray.h b/gfx/skia/skia/include/core/SkTArray.h index 6c76c78094bf..401f7084d6e5 100644 --- a/gfx/skia/skia/include/core/SkTArray.h +++ b/gfx/skia/skia/include/core/SkTArray.h @@ -8,9 +8,10 @@ #ifndef SkTArray_DEFINED #define SkTArray_DEFINED -#include +#include "../private/SkTemplates.h" #include "SkTypes.h" -#include "SkTemplates.h" + +#include template class SkTArray; @@ -31,18 +32,18 @@ inline void copyAndDelete(SkTArray* self, char* newMemArray) { template inline void copy(SkTArray* self, int dst, int src) { - SkNEW_PLACEMENT_ARGS(&self->fItemArray[dst], T, (self->fItemArray[src])); + new (&self->fItemArray[dst]) T(self->fItemArray[src]); } template inline void copy(SkTArray* self, const T* array) { for (int i = 0; i < self->fCount; ++i) { - SkNEW_PLACEMENT_ARGS(self->fItemArray + i, T, (array[i])); + new (self->fItemArray + i) T(array[i]); } } template inline void copyAndDelete(SkTArray* self, char* newMemArray) { for (int i = 0; i < self->fCount; ++i) { - SkNEW_PLACEMENT_ARGS(newMemArray + sizeof(T) * i, T, (self->fItemArray[i])); + new (newMemArray + sizeof(T) * i) T(self->fItemArray[i]); self->fItemArray[i].~T(); } } @@ -107,7 +108,7 @@ public: return *this; } - virtual ~SkTArray() { + ~SkTArray() { for (int i = 0; i < fCount; ++i) { fItemArray[i].~T(); } @@ -134,7 +135,7 @@ public: this->checkRealloc(n); fCount = n; for (int i = 0; i < fCount; ++i) { - SkNEW_PLACEMENT(fItemArray + i, T); + new (fItemArray + i) T; } } @@ -179,7 +180,7 @@ public: */ T& push_back() { T* newT = reinterpret_cast(this->push_back_raw(1)); - SkNEW_PLACEMENT(newT, T); + new (newT) T; return *newT; } @@ -188,10 +189,18 @@ public: */ T& push_back(const T& t) { T* newT = reinterpret_cast(this->push_back_raw(1)); - SkNEW_PLACEMENT_ARGS(newT, T, (t)); + new (newT) T(t); return *newT; } + /** + * Construct a new T at the back of this array. + */ + template T& emplace_back(Args&&... args) { + T* newT = reinterpret_cast(this->push_back_raw(1)); + return *new (newT) T(skstd::forward(args)...); + } + /** * Allocates n more default-initialized T values, and returns the address of * the start of that new range. Note: this address is only valid until the @@ -201,7 +210,7 @@ public: SkASSERT(n >= 0); T* newTs = reinterpret_cast(this->push_back_raw(n)); for (int i = 0; i < n; ++i) { - SkNEW_PLACEMENT(newTs + i, T); + new (newTs + i) T; } return newTs; } @@ -214,7 +223,7 @@ public: SkASSERT(n >= 0); T* newTs = reinterpret_cast(this->push_back_raw(n)); for (int i = 0; i < n; ++i) { - SkNEW_PLACEMENT_ARGS(newTs[i], T, (t)); + new (newTs[i]) T(t); } return newTs; } @@ -227,7 +236,7 @@ public: SkASSERT(n >= 0); this->checkRealloc(n); for (int i = 0; i < n; ++i) { - SkNEW_PLACEMENT_ARGS(fItemArray + fCount + i, T, (t[i])); + new (fItemArray + fCount + i) T(t[i]); } fCount += n; return fItemArray + fCount - n; @@ -270,6 +279,26 @@ public: } } + /** Swaps the contents of this array with that array. Does a pointer swap if possible, + otherwise copies the T values. */ + void swap(SkTArray* that) { + if (this == that) { + return; + } + if (this->fPreAllocMemArray != this->fItemArray && + that->fPreAllocMemArray != that->fItemArray) { + // If neither is using a preallocated array then just swap. + SkTSwap(fItemArray, that->fItemArray); + SkTSwap(fCount, that->fCount); + SkTSwap(fAllocCount, that->fAllocCount); + } else { + // This could be more optimal... + SkTArray copy(*that); + *that = *this; + *this = copy; + } + } + T* begin() { return fItemArray; } @@ -280,7 +309,7 @@ public: return fItemArray ? fItemArray + fCount : NULL; } const T* end() const { - return fItemArray ? fItemArray + fCount : NULL;; + return fItemArray ? fItemArray + fCount : NULL; } /** @@ -375,7 +404,7 @@ protected: } void init(const T* array, int count, - void* preAllocStorage, int preAllocOrReserveCount) { + void* preAllocStorage, int preAllocOrReserveCount) { SkASSERT(count >= 0); SkASSERT(preAllocOrReserveCount >= 0); fCount = count; @@ -384,7 +413,7 @@ protected: gMIN_ALLOC_COUNT; fPreAllocMemArray = preAllocStorage; if (fReserveCount >= fCount && - NULL != preAllocStorage) { + preAllocStorage) { fAllocCount = fReserveCount; fMemArray = preAllocStorage; } else { @@ -427,7 +456,7 @@ private: fAllocCount = newAllocCount; char* newMemArray; - if (fAllocCount == fReserveCount && NULL != fPreAllocMemArray) { + if (fAllocCount == fReserveCount && fPreAllocMemArray) { newMemArray = (char*) fPreAllocMemArray; } else { newMemArray = (char*) sk_malloc_throw(fAllocCount*sizeof(T)); @@ -452,10 +481,10 @@ private: template friend void SkTArrayExt::copy(SkTArray* that, const X*); template friend void SkTArrayExt::copyAndDelete(SkTArray* that, char*); - int fReserveCount; - int fCount; - int fAllocCount; - void* fPreAllocMemArray; + int fReserveCount; + int fCount; + int fAllocCount; + void* fPreAllocMemArray; union { T* fItemArray; void* fMemArray; @@ -464,7 +493,7 @@ private: // Use the below macro (SkNEW_APPEND_TO_TARRAY) rather than calling this directly template -void* operator new(size_t, SkTArray* array, int atIndex) { +void* operator new(size_t, SkTArray* array, int SkDEBUGCODE(atIndex)) { // Currently, we only support adding to the end of the array. When the array class itself // supports random insertion then this should be updated. // SkASSERT(atIndex >= 0 && atIndex <= array->count()); @@ -476,7 +505,7 @@ void* operator new(size_t, SkTArray* array, int atIndex) { // to match the op new silences warnings about missing op delete when a constructor throws an // exception. template -void operator delete(void*, SkTArray* array, int atIndex) { +void operator delete(void*, SkTArray* /*array*/, int /*atIndex*/) { SK_CRASH(); } diff --git a/gfx/skia/skia/include/core/SkTDArray.h b/gfx/skia/skia/include/core/SkTDArray.h index 4c90460b947f..26c6c7f8956b 100644 --- a/gfx/skia/skia/include/core/SkTDArray.h +++ b/gfx/skia/skia/include/core/SkTDArray.h @@ -17,23 +17,14 @@ public: SkTDArray() { fReserve = fCount = 0; fArray = NULL; -#ifdef SK_DEBUG - fData = NULL; -#endif } SkTDArray(const T src[], int count) { SkASSERT(src || count == 0); fReserve = fCount = 0; fArray = NULL; -#ifdef SK_DEBUG - fData = NULL; -#endif if (count) { fArray = (T*)sk_malloc_throw(count * sizeof(T)); -#ifdef SK_DEBUG - fData = (ArrayT*)fArray; -#endif memcpy(fArray, src, sizeof(T) * count); fReserve = fCount = count; } @@ -41,9 +32,6 @@ public: SkTDArray(const SkTDArray& src) { fReserve = fCount = 0; fArray = NULL; -#ifdef SK_DEBUG - fData = NULL; -#endif SkTDArray tmp(src.fArray, src.fCount); this->swap(tmp); } @@ -75,9 +63,6 @@ public: void swap(SkTDArray& other) { SkTSwap(fArray, other.fArray); -#ifdef SK_DEBUG - SkTSwap(fData, other.fData); -#endif SkTSwap(fReserve, other.fReserve); SkTSwap(fCount, other.fCount); } @@ -89,7 +74,6 @@ public: T* array = fArray; fArray = NULL; fReserve = fCount = 0; - SkDEBUGCODE(fData = NULL;) return array; } @@ -137,9 +121,6 @@ public: if (fArray) { sk_free(fArray); fArray = NULL; -#ifdef SK_DEBUG - fData = NULL; -#endif fReserve = fCount = 0; } else { SkASSERT(fReserve == 0 && fCount == 0); @@ -155,7 +136,7 @@ public: * Sets the number of elements in the array. * If the array does not have space for count elements, it will increase * the storage allocated to some amount greater than that required. - * It will never shrink the shrink the storage. + * It will never shrink the storage. */ void setCount(int count) { SkASSERT(count >= 0); @@ -237,7 +218,7 @@ public: for (; iter < stop; iter++) { if (*iter == elem) { - return (int) (iter - fArray); + return SkToInt(iter - fArray); } } return -1; @@ -282,18 +263,18 @@ public: } // routines to treat the array like a stack - T* push() { return this->append(); } - void push(const T& elem) { *this->append() = elem; } - const T& top() const { return (*this)[fCount - 1]; } - T& top() { return (*this)[fCount - 1]; } - void pop(T* elem) { if (elem) *elem = (*this)[fCount - 1]; --fCount; } - void pop() { --fCount; } + T* push() { return this->append(); } + void push(const T& elem) { *this->append() = elem; } + const T& top() const { return (*this)[fCount - 1]; } + T& top() { return (*this)[fCount - 1]; } + void pop(T* elem) { SkASSERT(fCount > 0); if (elem) *elem = (*this)[fCount - 1]; --fCount; } + void pop() { SkASSERT(fCount > 0); --fCount; } void deleteAll() { T* iter = fArray; T* stop = fArray + fCount; while (iter < stop) { - SkDELETE (*iter); + delete *iter; iter += 1; } this->reset(); @@ -343,18 +324,15 @@ public: SkASSERT((fReserve == 0 && fArray == NULL) || (fReserve > 0 && fArray != NULL)); SkASSERT(fCount <= fReserve); - SkASSERT(fData == (ArrayT*)fArray); } #endif + void shrinkToFit() { + fReserve = fCount; + fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T)); + } + private: -#ifdef SK_DEBUG - enum { - kDebugArraySize = 16 - }; - typedef T ArrayT[kDebugArraySize]; - ArrayT* fData; -#endif T* fArray; int fReserve; int fCount; @@ -380,9 +358,6 @@ private: fReserve = count + 4; fReserve += fReserve / 4; fArray = (T*)sk_realloc_throw(fArray, fReserve * sizeof(T)); -#ifdef SK_DEBUG - fData = (ArrayT*)fArray; -#endif } }; diff --git a/gfx/skia/skia/include/core/SkTInternalLList.h b/gfx/skia/skia/include/core/SkTInternalLList.h index 1c82a71cda67..1aa1a1220988 100644 --- a/gfx/skia/skia/include/core/SkTInternalLList.h +++ b/gfx/skia/skia/include/core/SkTInternalLList.h @@ -46,18 +46,18 @@ public: } void remove(T* entry) { - SkASSERT(NULL != fHead && NULL != fTail); + SkASSERT(fHead && fTail); SkASSERT(this->isInList(entry)); T* prev = entry->fPrev; T* next = entry->fNext; - if (NULL != prev) { + if (prev) { prev->fNext = next; } else { fHead = next; } - if (NULL != next) { + if (next) { next->fPrev = prev; } else { fTail = prev; @@ -77,7 +77,7 @@ public: entry->fPrev = NULL; entry->fNext = fHead; - if (NULL != fHead) { + if (fHead) { fHead->fPrev = entry; } fHead = entry; @@ -96,7 +96,7 @@ public: entry->fPrev = fTail; entry->fNext = NULL; - if (NULL != fTail) { + if (fTail) { fTail->fNext = entry; } fTail = entry; @@ -115,7 +115,7 @@ public: * at the tail. */ void addBefore(T* newEntry, T* existingEntry) { - SkASSERT(NULL != newEntry); + SkASSERT(newEntry); if (NULL == existingEntry) { this->addToTail(newEntry); @@ -144,7 +144,7 @@ public: * at the head. */ void addAfter(T* newEntry, T* existingEntry) { - SkASSERT(NULL != newEntry); + SkASSERT(newEntry); if (NULL == existingEntry) { this->addToHead(newEntry); @@ -227,7 +227,7 @@ public: void validate() const { SkASSERT(!fHead == !fTail); Iter iter; - for (T* item = iter.init(*this, Iter::kHead_IterStart); NULL != item; item = iter.next()) { + for (T* item = iter.init(*this, Iter::kHead_IterStart); item; item = iter.next()) { SkASSERT(this->isInList(item)); if (NULL == item->fPrev) { SkASSERT(fHead == item); @@ -255,7 +255,7 @@ public: */ int countEntries() const { int count = 0; - for (T* entry = fHead; NULL != entry; entry = entry->fNext) { + for (T* entry = fHead; entry; entry = entry->fNext) { ++count; } return count; diff --git a/gfx/skia/skia/include/core/SkTLazy.h b/gfx/skia/skia/include/core/SkTLazy.h index a291e22a1376..60d816147f75 100644 --- a/gfx/skia/skia/include/core/SkTLazy.h +++ b/gfx/skia/skia/include/core/SkTLazy.h @@ -1,4 +1,3 @@ - /* * Copyright 2011 Google Inc. * @@ -6,17 +5,13 @@ * found in the LICENSE file. */ - - #ifndef SkTLazy_DEFINED #define SkTLazy_DEFINED +#include "../private/SkTemplates.h" #include "SkTypes.h" #include -template class SkTLazy; -template void* operator new(size_t, SkTLazy* lazy); - /** * Efficient way to defer allocating/initializing a class until it is needed * (if ever). @@ -27,13 +22,13 @@ public: explicit SkTLazy(const T* src) : fPtr(NULL) { if (src) { - fPtr = new (fStorage) T(*src); + fPtr = new (fStorage.get()) T(*src); } } SkTLazy(const SkTLazy& src) : fPtr(NULL) { if (src.isValid()) { - fPtr = new (fStorage) T(*src->get()); + fPtr = new (fStorage.get()) T(*src->get()); } else { fPtr = NULL; } @@ -46,16 +41,16 @@ public: } /** - * Return a pointer to a default-initialized instance of the class. If a - * previous instance had been initialized (either from init() or set()) it - * will first be destroyed, so that a freshly initialized instance is - * always returned. + * Return a pointer to an instance of the class initialized with 'args'. + * If a previous instance had been initialized (either from init() or + * set()) it will first be destroyed, so that a freshly initialized + * instance is always returned. */ - T* init() { + template T* init(Args&&... args) { if (this->isValid()) { fPtr->~T(); } - fPtr = new (SkTCast(fStorage)) T; + fPtr = new (SkTCast(fStorage.get())) T(skstd::forward(args)...); return fPtr; } @@ -69,7 +64,7 @@ public: if (this->isValid()) { *fPtr = src; } else { - fPtr = new (SkTCast(fStorage)) T(src); + fPtr = new (SkTCast(fStorage.get())) T(src); } return fPtr; } @@ -88,7 +83,7 @@ public: * Returns true if a valid object has been initialized in the SkTLazy, * false otherwise. */ - bool isValid() const { return NULL != fPtr; } + bool isValid() const { return SkToBool(fPtr); } /** * Returns the object. This version should only be called when the caller @@ -103,27 +98,10 @@ public: T* getMaybeNull() const { return fPtr; } private: - friend void* operator new(size_t, SkTLazy* lazy); - - T* fPtr; // NULL or fStorage - char fStorage[sizeof(T)]; + T* fPtr; // NULL or fStorage + SkAlignedSTStorage<1, T> fStorage; }; -// Use the below macro (SkNEW_IN_TLAZY) rather than calling this directly -template void* operator new(size_t, SkTLazy* lazy) { - SkASSERT(!lazy->isValid()); - lazy->fPtr = reinterpret_cast(lazy->fStorage); - return lazy->fPtr; -} - -// Skia doesn't use C++ exceptions but it may be compiled with them enabled. Having an op delete -// to match the op new silences warnings about missing op delete when a constructor throws an -// exception. -template void operator delete(void*, SkTLazy*) { SK_CRASH(); } - -// Use this to construct a T inside an SkTLazy using a non-default constructor. -#define SkNEW_IN_TLAZY(tlazy_ptr, type_name, args) (new (tlazy_ptr) type_name args) - /** * A helper built on top of SkTLazy to do copy-on-first-write. The object is initialized * with a const pointer but provides a non-const pointer accessor. The first time the @@ -166,7 +144,7 @@ public: * Returns a writable T*. The first time this is called the initial object is cloned. */ T* writable() { - SkASSERT(NULL != fObj); + SkASSERT(fObj); if (!fLazy.isValid()) { fLazy.set(*fObj); fObj = fLazy.get(); diff --git a/gfx/skia/skia/include/core/SkTSearch.h b/gfx/skia/skia/include/core/SkTSearch.h index a4e4994ef378..549bcfd7c844 100644 --- a/gfx/skia/skia/include/core/SkTSearch.h +++ b/gfx/skia/skia/include/core/SkTSearch.h @@ -49,7 +49,7 @@ int SkTSearch(const T base[], int count, const K& key, size_t elemSize, LESS& le int hi = count - 1; while (lo < hi) { - int mid = (hi + lo) >> 1; + int mid = lo + ((hi - lo) >> 1); const T* elem = (const T*)((const char*)base + mid * elemSize); if (less(*elem, key)) diff --git a/gfx/skia/skia/include/core/SkTextBlob.h b/gfx/skia/skia/include/core/SkTextBlob.h new file mode 100644 index 000000000000..b0ab8929e60f --- /dev/null +++ b/gfx/skia/skia/include/core/SkTextBlob.h @@ -0,0 +1,184 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkTextBlob_DEFINED +#define SkTextBlob_DEFINED + +#include "SkPaint.h" +#include "SkRefCnt.h" +#include "SkTArray.h" +#include "SkTDArray.h" + +class SkReadBuffer; +class SkWriteBuffer; + +/** \class SkTextBlob + + SkTextBlob combines multiple text runs into an immutable, ref-counted structure. +*/ +class SK_API SkTextBlob : public SkRefCnt { +public: + /** + * Returns a conservative blob bounding box. + */ + const SkRect& bounds() const { return fBounds; } + + /** + * Return a non-zero, unique value representing the text blob. + */ + uint32_t uniqueID() const { return fUniqueID; } + + /** + * Serialize to a buffer. + */ + void flatten(SkWriteBuffer&) const; + + /** + * Recreate an SkTextBlob that was serialized into a buffer. + * + * @param SkReadBuffer Serialized blob data. + * @return A new SkTextBlob representing the serialized data, or NULL if the buffer is + * invalid. + */ + static const SkTextBlob* CreateFromBuffer(SkReadBuffer&); + + enum GlyphPositioning { + kDefault_Positioning = 0, // Default glyph advances -- zero scalars per glyph. + kHorizontal_Positioning = 1, // Horizontal positioning -- one scalar per glyph. + kFull_Positioning = 2 // Point positioning -- two scalars per glyph. + }; + +private: + class RunRecord; + + SkTextBlob(int runCount, const SkRect& bounds); + + virtual ~SkTextBlob(); + + // Memory for objects of this class is created with sk_malloc rather than operator new and must + // be freed with sk_free. + void operator delete(void* p) { sk_free(p); } + void* operator new(size_t) { + SkFAIL("All blobs are created by placement new."); + return sk_malloc_throw(0); + } + void* operator new(size_t, void* p) { return p; } + + static unsigned ScalarsPerGlyph(GlyphPositioning pos); + + friend class SkTextBlobBuilder; + friend class SkTextBlobRunIterator; + + const int fRunCount; + const SkRect fBounds; + const uint32_t fUniqueID; + + SkDEBUGCODE(size_t fStorageSize;) + + // The actual payload resides in externally-managed storage, following the object. + // (see the .cpp for more details) + + typedef SkRefCnt INHERITED; +}; + +/** \class SkTextBlobBuilder + + Helper class for constructing SkTextBlobs. + */ +class SK_API SkTextBlobBuilder { +public: + SkTextBlobBuilder(); + + ~SkTextBlobBuilder(); + + /** + * Returns an immutable SkTextBlob for the current runs/glyphs. The builder is reset and + * can be reused. + */ + const SkTextBlob* build(); + + /** + * Glyph and position buffers associated with a run. + * + * A run is a sequence of glyphs sharing the same font metrics and positioning mode. + */ + struct RunBuffer { + uint16_t* glyphs; + SkScalar* pos; + }; + + /** + * Allocates a new default-positioned run and returns its writable glyph buffer + * for direct manipulation. + * + * @param font The font to be used for this run. + * @param count Number of glyphs. + * @param x,y Position within the blob. + * @param bounds Optional run bounding box. If known in advance (!= NULL), it will + * be used when computing the blob bounds, to avoid re-measuring. + * + * @return A writable glyph buffer, valid until the next allocRun() or + * build() call. The buffer is guaranteed to hold @count@ glyphs. + */ + const RunBuffer& allocRun(const SkPaint& font, int count, SkScalar x, SkScalar y, + const SkRect* bounds = NULL); + + /** + * Allocates a new horizontally-positioned run and returns its writable glyph and position + * buffers for direct manipulation. + * + * @param font The font to be used for this run. + * @param count Number of glyphs. + * @param y Vertical offset within the blob. + * @param bounds Optional run bounding box. If known in advance (!= NULL), it will + * be used when computing the blob bounds, to avoid re-measuring. + * + * @return Writable glyph and position buffers, valid until the next allocRun() + * or build() call. The buffers are guaranteed to hold @count@ elements. + */ + const RunBuffer& allocRunPosH(const SkPaint& font, int count, SkScalar y, + const SkRect* bounds = NULL); + + /** + * Allocates a new fully-positioned run and returns its writable glyph and position + * buffers for direct manipulation. + * + * @param font The font to be used for this run. + * @param count Number of glyphs. + * @param bounds Optional run bounding box. If known in advance (!= NULL), it will + * be used when computing the blob bounds, to avoid re-measuring. + * + * @return Writable glyph and position buffers, valid until the next allocRun() + * or build() call. The glyph buffer and position buffer are + * guaranteed to hold @count@ and 2 * @count@ elements, respectively. + */ + const RunBuffer& allocRunPos(const SkPaint& font, int count, const SkRect* bounds = NULL); + +private: + void reserve(size_t size); + void allocInternal(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, + int count, SkPoint offset, const SkRect* bounds); + bool mergeRun(const SkPaint& font, SkTextBlob::GlyphPositioning positioning, + int count, SkPoint offset); + void updateDeferredBounds(); + + static SkRect ConservativeRunBounds(const SkTextBlob::RunRecord&); + static SkRect TightRunBounds(const SkTextBlob::RunRecord&); + + SkAutoTMalloc fStorage; + size_t fStorageSize; + size_t fStorageUsed; + + SkRect fBounds; + int fRunCount; + bool fDeferredBounds; + size_t fLastRun; // index into fStorage + + RunBuffer fCurrentRunBuffer; +}; + +#endif // SkTextBlob_DEFINED diff --git a/gfx/skia/skia/include/core/SkThread.h b/gfx/skia/skia/include/core/SkThread.h deleted file mode 100644 index bcbc43754f69..000000000000 --- a/gfx/skia/skia/include/core/SkThread.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkThread_DEFINED -#define SkThread_DEFINED - -#include "SkTypes.h" - -// SK_ATOMICS_PLATFORM_H must provide inline implementations for the following declarations. - -/** Atomically adds one to the int referenced by addr and returns the previous value. - * No additional memory barrier is required; this must act as a compiler barrier. - */ -static int32_t sk_atomic_inc(int32_t* addr); -static int64_t sk_atomic_inc(int64_t* addr); - -/** Atomically adds inc to the int referenced by addr and returns the previous value. - * No additional memory barrier is required; this must act as a compiler barrier. - */ -static int32_t sk_atomic_add(int32_t* addr, int32_t inc); - -/** Atomically subtracts one from the int referenced by addr and returns the previous value. - * This must act as a release (SL/S) memory barrier and as a compiler barrier. - */ -static int32_t sk_atomic_dec(int32_t* addr); - -/** Atomic compare and set. - * If *addr == before, set *addr to after and return true, otherwise return false. - * This must act as a release (SL/S) memory barrier and as a compiler barrier. - */ -static bool sk_atomic_cas(int32_t* addr, int32_t before, int32_t after); - -/** If sk_atomic_dec does not act as an acquire (L/SL) barrier, - * this must act as an acquire (L/SL) memory barrier and as a compiler barrier. - */ -static void sk_membar_acquire__after_atomic_dec(); - -/** If sk_atomic_conditional_inc does not act as an acquire (L/SL) barrier, - * this must act as an acquire (L/SL) memory barrier and as a compiler barrier. - */ -static void sk_membar_acquire__after_atomic_conditional_inc(); - -#include SK_ATOMICS_PLATFORM_H - -/** Atomically adds one to the int referenced by addr iff the referenced int was not 0 - * and returns the previous value. - * No additional memory barrier is required; this must act as a compiler barrier. - */ -template static inline INT_TYPE sk_atomic_conditional_inc(INT_TYPE* addr) { - INT_TYPE prev; - do { - prev = *addr; - if (0 == prev) { - break; - } - } while (!sk_atomic_cas(addr, prev, prev+1)); - return prev; -} - -// SK_BARRIERS_PLATFORM_H must provide implementations for the following declarations: - -/** Prevent the compiler from reordering across this barrier. */ -static void sk_compiler_barrier(); - -/** Read T*, with at least an acquire barrier. - * - * Only needs to be implemented for T which can be atomically read. - */ -template T sk_acquire_load(T*); - -/** Write T*, with at least a release barrier. - * - * Only needs to be implemented for T which can be atomically written. - */ -template void sk_release_store(T*, T); - -#include SK_BARRIERS_PLATFORM_H - -/** SK_MUTEX_PLATFORM_H must provide the following (or equivalent) declarations. - -class SkBaseMutex { -public: - void acquire(); // Block until this thread owns the mutex. - void release(); // Assuming this thread owns the mutex, release it. - void assertHeld(); // If SK_DEBUG, assert this thread owns the mutex. -}; - -class SkMutex : SkBaseMutex { -public: - SkMutex(); - ~SkMutex(); -}; - -#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = ... -*/ - -#include SK_MUTEX_PLATFORM_H - - -class SkAutoMutexAcquire : SkNoncopyable { -public: - explicit SkAutoMutexAcquire(SkBaseMutex& mutex) : fMutex(&mutex) { - SkASSERT(fMutex != NULL); - mutex.acquire(); - } - - explicit SkAutoMutexAcquire(SkBaseMutex* mutex) : fMutex(mutex) { - if (mutex) { - mutex->acquire(); - } - } - - /** If the mutex has not been released, release it now. */ - ~SkAutoMutexAcquire() { - if (fMutex) { - fMutex->release(); - } - } - - /** If the mutex has not been released, release it now. */ - void release() { - if (fMutex) { - fMutex->release(); - fMutex = NULL; - } - } - - /** Assert that we're holding the mutex. */ - void assertHeld() { - SkASSERT(fMutex); - fMutex->assertHeld(); - } - -private: - SkBaseMutex* fMutex; -}; -#define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire) - -#endif diff --git a/gfx/skia/skia/include/core/SkTime.h b/gfx/skia/skia/include/core/SkTime.h index 51616d41c741..2cfe3efcb45c 100644 --- a/gfx/skia/skia/include/core/SkTime.h +++ b/gfx/skia/skia/include/core/SkTime.h @@ -12,12 +12,16 @@ #include "SkTypes.h" +class SkString; + /** \class SkTime Platform-implemented utilities to return time of day, and millisecond counter. */ class SkTime { public: struct DateTime { + int16_t fTimeZoneMinutes; // The number of minutes that GetDateTime() + // is ahead of or behind UTC. uint16_t fYear; //!< e.g. 2005 uint8_t fMonth; //!< 1..12 uint8_t fDayOfWeek; //!< 0..6, 0==Sunday @@ -25,10 +29,13 @@ public: uint8_t fHour; //!< 0..23 uint8_t fMinute; //!< 0..59 uint8_t fSecond; //!< 0..59 + + void toISO8601(SkString* dst) const; }; static void GetDateTime(DateTime*); - static SkMSec GetMSecs(); + static SkMSec GetMSecs() { return (SkMSec)(GetNSecs() * 1e-6); } + static double GetNSecs(); }; #if defined(SK_DEBUG) && defined(SK_BUILD_FOR_WIN32) diff --git a/gfx/skia/skia/include/core/SkTraceMemoryDump.h b/gfx/skia/skia/include/core/SkTraceMemoryDump.h new file mode 100644 index 000000000000..8383190ccccc --- /dev/null +++ b/gfx/skia/skia/include/core/SkTraceMemoryDump.h @@ -0,0 +1,80 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkTraceMemoryDump_DEFINED +#define SkTraceMemoryDump_DEFINED + +#include "SkTypes.h" + +class SkDiscardableMemory; + +/** + * Interface for memory tracing. + * This interface is meant to be passed as argument to the memory dump methods of Skia objects. + * The implementation of this interface is provided by the embedder. + */ +class SK_API SkTraceMemoryDump { +public: + /** + * Enum to specify the level of the requested details for the dump from the Skia objects. + */ + enum LevelOfDetail { + // Dump only the minimal details to get the total memory usage (Usually just the totals). + kLight_LevelOfDetail, + + // Dump the detailed breakdown of the objects in the caches. + kObjectsBreakdowns_LevelOfDetail + }; + + /** + * Appends a new memory dump (i.e. a row) to the trace memory infrastructure. + * If dumpName does not exist yet, a new one is created. Otherwise, a new column is appended to + * the previously created dump. + * Arguments: + * dumpName: an absolute, slash-separated, name for the item being dumped + * e.g., "skia/CacheX/EntryY". + * valueName: a string indicating the name of the column. + * e.g., "size", "active_size", "number_of_objects". + * This string is supposed to be long lived and is NOT copied. + * units: a string indicating the units for the value. + * e.g., "bytes", "objects". + * This string is supposed to be long lived and is NOT copied. + * value: the actual value being dumped. + */ + virtual void dumpNumericValue(const char* dumpName, + const char* valueName, + const char* units, + uint64_t value) = 0; + + /** + * Sets the memory backing for an existing dump. + * backingType and backingObjectId are used by the embedder to associate the memory dumped via + * dumpNumericValue with the corresponding dump that backs the memory. + */ + virtual void setMemoryBacking(const char* dumpName, + const char* backingType, + const char* backingObjectId) = 0; + + /** + * Specialization for memory backed by discardable memory. + */ + virtual void setDiscardableMemoryBacking( + const char* dumpName, + const SkDiscardableMemory& discardableMemoryObject) = 0; + + /** + * Returns the type of details requested in the dump. The granularity of the dump is supposed to + * match the LevelOfDetail argument. The level of detail must not affect the total size + * reported, but only granularity of the child entries. + */ + virtual LevelOfDetail getRequestedDetails() const = 0; + +protected: + virtual ~SkTraceMemoryDump() { } +}; + +#endif diff --git a/gfx/skia/skia/include/core/SkTypeface.h b/gfx/skia/skia/include/core/SkTypeface.h index 0b1c1f24ac73..0b1ca6a4bdaf 100644 --- a/gfx/skia/skia/include/core/SkTypeface.h +++ b/gfx/skia/skia/include/core/SkTypeface.h @@ -10,14 +10,19 @@ #ifndef SkTypeface_DEFINED #define SkTypeface_DEFINED -#include "SkAdvancedTypefaceMetrics.h" -#include "SkWeakRefCnt.h" +#include "../private/SkOncePtr.h" +#include "../private/SkWeakRefCnt.h" +#include "SkFontStyle.h" +#include "SkRect.h" +#include "SkString.h" class SkDescriptor; +class SkFontData; class SkFontDescriptor; class SkScalerContext; struct SkScalerContextRec; class SkStream; +class SkStreamAsset; class SkAdvancedTypefaceMetrics; class SkWStream; @@ -36,8 +41,6 @@ typedef uint32_t SkFontTableTag; */ class SK_API SkTypeface : public SkWeakRefCnt { public: - SK_DECLARE_INST_COUNT(SkTypeface) - /** Style specifies the intrinsic style attributes of a given typeface */ enum Style { @@ -49,17 +52,25 @@ public: kBoldItalic = 0x03 }; - /** Returns the typeface's intrinsic style attributes - */ - Style style() const { return fStyle; } + /** Returns the typeface's intrinsic style attributes. */ + SkFontStyle fontStyle() const { + return fStyle; + } - /** Returns true if getStyle() has the kBold bit set. - */ - bool isBold() const { return (fStyle & kBold) != 0; } + /** Returns the typeface's intrinsic style attributes. + * @deprecated use fontStyle() instead. + */ + Style style() const { + return static_cast