From 47a2d486297314c46022277b747b27a44cc11491 Mon Sep 17 00:00:00 2001 From: Andrew Halberstadt Date: Thu, 20 Mar 2014 15:25:43 -0400 Subject: [PATCH 001/101] Bug 981030 - Create platform specific mozharness files for storing test harness options, r=aki --- .../config/mozharness/android_arm_config.py | 37 ++++++++ .../config/mozharness/android_panda_config.py | 86 +++++++++++++++++++ .../config/mozharness/android_x86_config.py | 37 ++++++++ .../config/mozharness/b2g_desktop_config.py | 18 ++++ .../config/mozharness/b2g_emulator_config.py | 48 +++++++++++ testing/config/mozharness/linux_config.py | 34 ++++++++ testing/config/mozharness/mac_config.py | 34 ++++++++ testing/config/mozharness/windows_config.py | 34 ++++++++ testing/config/mozharness_config.py | 28 ------ 9 files changed, 328 insertions(+), 28 deletions(-) create mode 100644 testing/config/mozharness/android_arm_config.py create mode 100644 testing/config/mozharness/android_panda_config.py create mode 100644 testing/config/mozharness/android_x86_config.py create mode 100644 testing/config/mozharness/b2g_desktop_config.py create mode 100644 testing/config/mozharness/b2g_emulator_config.py create mode 100644 testing/config/mozharness/linux_config.py create mode 100644 testing/config/mozharness/mac_config.py create mode 100644 testing/config/mozharness/windows_config.py delete mode 100644 testing/config/mozharness_config.py diff --git a/testing/config/mozharness/android_arm_config.py b/testing/config/mozharness/android_arm_config.py new file mode 100644 index 000000000000..06ec34aa6995 --- /dev/null +++ b/testing/config/mozharness/android_arm_config.py @@ -0,0 +1,37 @@ +# 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/. + +config = { + "suite_definitions": { + "mochitest": { + "run_filename": "runtestsremote.py", + "options": ["--autorun", "--close-when-done", "--dm_trans=sut", + "--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s", + "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s", + "--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s" + ], + }, + "reftest": { + "run_filename": "remotereftest.py", + "options": [ "--app=%(app)s", "--ignore-window-size", + "--bootstrap", "--enable-privilege", + "--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s", + "--utility-path=%(utility_path)s", "--deviceIP=%(device_ip)s", + "--devicePort=%(device_port)s", "--http-port=%(http_port)s", + "--ssl-port=%(ssl_port)s", "--httpd-path", "reftest/components", + "--symbols-path=%(symbols_path)s", + ], + }, + "xpcshell": { + "run_filename": "remotexpcshelltests.py", + "options": ["--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s", + "--xre-path=%(xre_path)s", "--testing-modules-dir=%(modules_dir)s", + "--apk=%(installer_path)s", "--no-logfiles", + "--symbols-path=%(symbols_path)s", + ], + }, + }, # end suite_definitions +} diff --git a/testing/config/mozharness/android_panda_config.py b/testing/config/mozharness/android_panda_config.py new file mode 100644 index 000000000000..2bafcc732b87 --- /dev/null +++ b/testing/config/mozharness/android_panda_config.py @@ -0,0 +1,86 @@ +# 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/. + +config = { + "mochitest_options": [ + "--deviceIP=%(device_ip)s", + "--xre-path=../hostutils/xre", + "--utility-path=../hostutils/bin", "--certificate-path=certs", + "--app=%(app_name)s", "--console-level=INFO", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--run-only-tests=android.json", "--symbols-path=%(symbols_path)s" + ], + "reftest_options": [ + "--deviceIP=%(device_ip)s", + "--xre-path=../hostutils/xre", + "--utility-path=../hostutils/bin", + "--app=%(app_name)s", + "--ignore-window-size", "--bootstrap", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--symbols-path=%(symbols_path)s", + "reftest/tests/layout/reftests/reftest.list" + ], + "crashtest_options": [ + "--deviceIP=%(device_ip)s", + "--xre-path=../hostutils/xre", + "--utility-path=../hostutils/bin", + "--app=%(app_name)s", + "--enable-privilege", "--ignore-window-size", "--bootstrap", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--symbols-path=%(symbols_path)s", + "reftest/tests/testing/crashtest/crashtests.list" + ], + "jsreftest_options": [ + "--deviceIP=%(device_ip)s", + "--xre-path=../hostutils/xre", + "--utility-path=../hostutils/bin", + "--app=%(app_name)s", + "--enable-privilege", "--ignore-window-size", "--bootstrap", + "--extra-profile-file=jsreftest/tests/user.js", "jsreftest/tests/jstests.list", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--symbols-path=%(symbols_path)s" + ], + "robocop_options": [ + "--deviceIP=%(device_ip)s", + "--xre-path=../hostutils/xre", + "--utility-path=../hostutils/bin", + "--certificate-path=certs", + "--app=%(app_name)s", "--console-level=INFO", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--symbols-path=%(symbols_path)s", + "--robocop=mochitest/robocop.ini" + ], + "xpcshell_options": [ + "--deviceIP=%(device_ip)s", + "--xre-path=../hostutils/xre", + "--manifest=xpcshell/tests/xpcshell_android.ini", + "--build-info-json=xpcshell/mozinfo.json", + "--testing-modules-dir=modules", + "--local-lib-dir=../fennec", + "--apk=../%(apk_name)s", + "--no-logfiles", + "--symbols-path=%(symbols_path)s" + ], + "jittest_options": [ + "bin/js", + "--remote", + "-j", "1", + "--deviceTransport=sut", + "--deviceIP=%(device_ip)s", + "--localLib=../tests/bin", + "--no-slow", + "--no-progress", + "--tinderbox", + "--tbpl" + ], + "cppunittest_options": [ + "--symbols-path=%(symbols_path)s", + "--xre-path=tests/bin", + "--dm_trans=SUT", + "--deviceIP=%(device_ip)s", + "--localBinDir=../tests/bin", + "--apk=%(apk_path)s", + "--skip-manifest=../tests/cppunittests/android_cppunittest_manifest.txt" + ], +} diff --git a/testing/config/mozharness/android_x86_config.py b/testing/config/mozharness/android_x86_config.py new file mode 100644 index 000000000000..06ec34aa6995 --- /dev/null +++ b/testing/config/mozharness/android_x86_config.py @@ -0,0 +1,37 @@ +# 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/. + +config = { + "suite_definitions": { + "mochitest": { + "run_filename": "runtestsremote.py", + "options": ["--autorun", "--close-when-done", "--dm_trans=sut", + "--console-level=INFO", "--app=%(app)s", "--remote-webserver=%(remote_webserver)s", + "--xre-path=%(xre_path)s", "--utility-path=%(utility_path)s", + "--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s", + "--http-port=%(http_port)s", "--ssl-port=%(ssl_port)s", + "--certificate-path=%(certs_path)s", "--symbols-path=%(symbols_path)s" + ], + }, + "reftest": { + "run_filename": "remotereftest.py", + "options": [ "--app=%(app)s", "--ignore-window-size", + "--bootstrap", "--enable-privilege", + "--remote-webserver=%(remote_webserver)s", "--xre-path=%(xre_path)s", + "--utility-path=%(utility_path)s", "--deviceIP=%(device_ip)s", + "--devicePort=%(device_port)s", "--http-port=%(http_port)s", + "--ssl-port=%(ssl_port)s", "--httpd-path", "reftest/components", + "--symbols-path=%(symbols_path)s", + ], + }, + "xpcshell": { + "run_filename": "remotexpcshelltests.py", + "options": ["--deviceIP=%(device_ip)s", "--devicePort=%(device_port)s", + "--xre-path=%(xre_path)s", "--testing-modules-dir=%(modules_dir)s", + "--apk=%(installer_path)s", "--no-logfiles", + "--symbols-path=%(symbols_path)s", + ], + }, + }, # end suite_definitions +} diff --git a/testing/config/mozharness/b2g_desktop_config.py b/testing/config/mozharness/b2g_desktop_config.py new file mode 100644 index 000000000000..772566c266c3 --- /dev/null +++ b/testing/config/mozharness/b2g_desktop_config.py @@ -0,0 +1,18 @@ +# 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/. + +config = { + "mochitest_options": [ + "--console-level=INFO", "%(test_manifest)s", + "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s", + "--profile=%(gaia_profile)s", "--app=%(application)s", "--desktop", + "--utility-path=%(utility_path)s", "--certificate-path=%(cert_path)s", + "--symbols-path=%(symbols_path)s", + ], + + "reftest_options": [ + "--desktop", "--profile=%(gaia_profile)s", "--appname=%(application)s", + "--symbols-path=%(symbols_path)s", "%(test_manifest)s", + ] +} diff --git a/testing/config/mozharness/b2g_emulator_config.py b/testing/config/mozharness/b2g_emulator_config.py new file mode 100644 index 000000000000..d20c5f8512da --- /dev/null +++ b/testing/config/mozharness/b2g_emulator_config.py @@ -0,0 +1,48 @@ +# 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/. + +config = { + "jsreftest_options": [ + "--adbpath=%(adbpath)s", "--b2gpath=%(b2gpath)s", "--emulator=%(emulator)s", + "--emulator-res=800x1000", "--logcat-dir=%(logcat_dir)s", + "--remote-webserver=%(remote_webserver)s", "--ignore-window-size", + "--xre-path=%(xre_path)s", "--symbols-path=%(symbols_path)s", "--busybox=%(busybox)s", + "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s", + "--extra-profile-file=jsreftest/tests/user.js", + "%(test_manifest)s", + ], + + "mochitest_options": [ + "--adbpath=%(adbpath)s", "--b2gpath=%(b2gpath)s", "--console-level=INFO", + "--emulator=%(emulator)s", "--logcat-dir=%(logcat_dir)s", + "--remote-webserver=%(remote_webserver)s", "%(test_manifest)s", + "--xre-path=%(xre_path)s", "--symbols-path=%(symbols_path)s", "--busybox=%(busybox)s", + "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s", + ], + + "reftest_options": [ + "--adbpath=%(adbpath)s", "--b2gpath=%(b2gpath)s", "--emulator=%(emulator)s", + "--emulator-res=800x1000", "--logcat-dir=%(logcat_dir)s", + "--remote-webserver=%(remote_webserver)s", "--ignore-window-size", + "--xre-path=%(xre_path)s", "--symbols-path=%(symbols_path)s", "--busybox=%(busybox)s", + "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s", + "%(test_manifest)s", + ], + + "crashtest_options": [ + "--adbpath=%(adbpath)s", "--b2gpath=%(b2gpath)s", "--emulator=%(emulator)s", + "--emulator-res=800x1000", "--logcat-dir=%(logcat_dir)s", + "--remote-webserver=%(remote_webserver)s", "--ignore-window-size", + "--xre-path=%(xre_path)s", "--symbols-path=%(symbols_path)s", "--busybox=%(busybox)s", + "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s", + "%(test_manifest)s", + ], + + "xpcshell_options": [ + "--adbpath=%(adbpath)s", "--b2gpath=%(b2gpath)s", "--emulator=%(emulator)s", + "--logcat-dir=%(logcat_dir)s", "--manifest=%(test_manifest)s", "--use-device-libs", + "--testing-modules-dir=%(modules_dir)s", "--symbols-path=%(symbols_path)s", + "--busybox=%(busybox)s", "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s", + ], +} diff --git a/testing/config/mozharness/linux_config.py b/testing/config/mozharness/linux_config.py new file mode 100644 index 000000000000..bba4f61385e8 --- /dev/null +++ b/testing/config/mozharness/linux_config.py @@ -0,0 +1,34 @@ +# 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/. + +config = { + "reftest_options": [ + "--appname=%(binary_path)s", "--utility-path=tests/bin", + "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s" + ], + "mochitest_options": [ + "--appname=%(binary_path)s", "--utility-path=tests/bin", + "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s", + "--certificate-path=tests/certs", "--autorun", "--close-when-done", + "--console-level=INFO", "--setpref=webgl.force-enabled=true" + ], + "xpcshell_options": [ + "--symbols-path=%(symbols_path)s", + "--test-plugin-path=%(test_plugin_path)s" + ], + "cppunittest_options": [ + "--symbols-path=%(symbols_path)s", + "--xre-path=%(abs_app_dir)s" + ], + "jittest_options": [ + "tests/bin/js", + "--no-slow", + "--no-progress", + "--tinderbox", + "--tbpl" + ], + "mozbase_options": [ + "-b", "%(binary_path)s" + ], +} diff --git a/testing/config/mozharness/mac_config.py b/testing/config/mozharness/mac_config.py new file mode 100644 index 000000000000..73fa299d4a02 --- /dev/null +++ b/testing/config/mozharness/mac_config.py @@ -0,0 +1,34 @@ +# 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/. + +config = { + "reftest_options": [ + "--appname=%(binary_path)s", "--utility-path=tests/bin", + "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s" + ], + "mochitest_options": [ + "--appname=%(binary_path)s", "--utility-path=tests/bin", + "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s", + "--certificate-path=tests/certs", "--autorun", "--close-when-done", + "--console-level=INFO" + ], + "xpcshell_options": [ + "--symbols-path=%(symbols_path)s", + "--test-plugin-path=%(test_plugin_path)s" + ], + "cppunittest_options": [ + "--symbols-path=%(symbols_path)s", + "--xre-path=%(abs_app_dir)s" + ], + "jittest_options": [ + "tests/bin/js", + "--no-slow", + "--no-progress", + "--tinderbox", + "--tbpl" + ], + "mozbase_options": [ + "-b", "%(binary_path)s" + ], +} diff --git a/testing/config/mozharness/windows_config.py b/testing/config/mozharness/windows_config.py new file mode 100644 index 000000000000..73fa299d4a02 --- /dev/null +++ b/testing/config/mozharness/windows_config.py @@ -0,0 +1,34 @@ +# 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/. + +config = { + "reftest_options": [ + "--appname=%(binary_path)s", "--utility-path=tests/bin", + "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s" + ], + "mochitest_options": [ + "--appname=%(binary_path)s", "--utility-path=tests/bin", + "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s", + "--certificate-path=tests/certs", "--autorun", "--close-when-done", + "--console-level=INFO" + ], + "xpcshell_options": [ + "--symbols-path=%(symbols_path)s", + "--test-plugin-path=%(test_plugin_path)s" + ], + "cppunittest_options": [ + "--symbols-path=%(symbols_path)s", + "--xre-path=%(abs_app_dir)s" + ], + "jittest_options": [ + "tests/bin/js", + "--no-slow", + "--no-progress", + "--tinderbox", + "--tbpl" + ], + "mozbase_options": [ + "-b", "%(binary_path)s" + ], +} diff --git a/testing/config/mozharness_config.py b/testing/config/mozharness_config.py deleted file mode 100644 index 1f8e36aa78cd..000000000000 --- a/testing/config/mozharness_config.py +++ /dev/null @@ -1,28 +0,0 @@ -# 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/. - -"""The config defined in this module is read by mozharness, which is a -tool used to run many of the tests reporting to TBPL. This file is -primarily useful for pushing custom test harness configurations to try. - -For example you can define a custom mochitest configuration by adding: - "mochitest_options": [ - "--appname=%(binary_path)s", "--utility-path=tests/bin", - "--extra-profile-file=tests/bin/plugins", "--symbols-path=%(symbols_path)s", - "--certificate-path=tests/certs", "--autorun", "--close-when-done", - "--console-level=INFO", "--setpref=webgl.force-enabled=true" - ], - -Be warned that these values will be picked up by all platforms and changing them -may result in unexpected behaviour. For example, the above will break B2G -mochitests. - -You must also provide the complete command line to avoid errors. The official -configuration files containing the default values live in: - https://hg.mozilla.org/build/mozharness/configs -""" - -config = { - # Add custom mozharness config options here -} From 337e06fd002cf5168771e64b7cf0b82083d2cc4a Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:21:03 +1200 Subject: [PATCH 002/101] Bug 917755. Part 1: Add nsLayoutUtils::TransformCSSPoints and nsLayoutUtils::GetFirstNonAnonymousFrame. r=matspal --- layout/base/nsLayoutUtils.cpp | 97 +++++++++++++++++++++++++++++++++++ layout/base/nsLayoutUtils.h | 71 +++++++++++++++++-------- 2 files changed, 146 insertions(+), 22 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 29c40af562f9..173eaae5c2c9 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1893,6 +1893,66 @@ nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncesto return ctm; } +static nsIFrame* +FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2) +{ + nsAutoTArray ancestors1; + nsAutoTArray ancestors2; + nsIFrame* commonAncestor = nullptr; + if (aFrame1->PresContext() == aFrame2->PresContext()) { + commonAncestor = aFrame1->PresContext()->PresShell()->GetRootFrame(); + } + for (nsIFrame* f = aFrame1; f != commonAncestor; + f = nsLayoutUtils::GetCrossDocParentFrame(f)) { + ancestors1.AppendElement(f); + } + for (nsIFrame* f = aFrame2; f != commonAncestor; + f = nsLayoutUtils::GetCrossDocParentFrame(f)) { + ancestors2.AppendElement(f); + } + uint32_t minLengths = std::min(ancestors1.Length(), ancestors2.Length()); + for (uint32_t i = 1; i <= minLengths; ++i) { + if (ancestors1[ancestors1.Length() - i] == ancestors2[ancestors2.Length() - i]) { + commonAncestor = ancestors1[ancestors1.Length() - i]; + } else { + break; + } + } + return commonAncestor; +} + +nsLayoutUtils::TransformResult +nsLayoutUtils::TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame, + uint32_t aPointCount, CSSPoint* aPoints) +{ + nsIFrame* nearestCommonAncestor = FindNearestCommonAncestorFrame(aFromFrame, aToFrame); + if (!nearestCommonAncestor) { + return NO_COMMON_ANCESTOR; + } + gfx3DMatrix downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor); + if (downToDest.IsSingular()) { + return NONINVERTIBLE_TRANSFORM; + } + downToDest.Invert(); + gfx3DMatrix upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor); + CSSToLayoutDeviceScale devPixelsPerCSSPixelFromFrame( + double(nsPresContext::AppUnitsPerCSSPixel())/ + aFromFrame->PresContext()->AppUnitsPerDevPixel()); + CSSToLayoutDeviceScale devPixelsPerCSSPixelToFrame( + double(nsPresContext::AppUnitsPerCSSPixel())/ + aToFrame->PresContext()->AppUnitsPerDevPixel()); + for (uint32_t i = 0; i < aPointCount; ++i) { + LayoutDevicePoint devPixels = aPoints[i] * devPixelsPerCSSPixelFromFrame; + gfxPoint toDevPixels = downToDest.ProjectPoint( + upToAncestor.ProjectPoint(gfxPoint(devPixels.x, devPixels.y))); + // Divide here so that when the devPixelsPerCSSPixels are the same, we get the correct + // answer instead of some inaccuracy multiplying a number by its reciprocal. + aPoints[i] = LayoutDevicePoint(toDevPixels.x, toDevPixels.y) / + devPixelsPerCSSPixelToFrame; + } + return TRANSFORM_SUCCEEDED; +} + bool nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame, gfx3DMatrix* aTransform) @@ -2586,6 +2646,43 @@ nsLayoutUtils::GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback) } } +nsIFrame* +nsLayoutUtils::GetFirstNonAnonymousFrame(nsIFrame* aFrame) +{ + while (aFrame) { + nsIAtom* pseudoType = aFrame->StyleContext()->GetPseudo(); + + if (pseudoType == nsCSSAnonBoxes::tableOuter) { + nsIFrame* f = GetFirstNonAnonymousFrame(aFrame->GetFirstPrincipalChild()); + if (f) { + return f; + } + nsIFrame* kid = aFrame->GetFirstChild(nsIFrame::kCaptionList); + if (kid) { + f = GetFirstNonAnonymousFrame(kid); + if (f) { + return f; + } + } + } else if (pseudoType == nsCSSAnonBoxes::mozAnonymousBlock || + pseudoType == nsCSSAnonBoxes::mozAnonymousPositionedBlock || + pseudoType == nsCSSAnonBoxes::mozMathMLAnonymousBlock || + pseudoType == nsCSSAnonBoxes::mozXULAnonymousBlock) { + for (nsIFrame* kid = aFrame->GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) { + nsIFrame* f = GetFirstNonAnonymousFrame(kid); + if (f) { + return f; + } + } + } else { + return aFrame; + } + + aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame); + } + return nullptr; +} + struct BoxToRect : public nsLayoutUtils::BoxCallback { nsIFrame* mRelativeTo; nsLayoutUtils::RectCallback* mCallback; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index a5eeeacec8c5..e61449e5539c 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -6,6 +6,29 @@ #ifndef nsLayoutUtils_h__ #define nsLayoutUtils_h__ +#include "mozilla/MemoryReporting.h" +#include "nsChangeHint.h" +#include "nsAutoPtr.h" +#include "nsFrameList.h" +#include "nsThreadUtils.h" +#include "nsIPrincipal.h" +#include "GraphicsFilter.h" +#include "nsCSSPseudoElements.h" +#include "FrameMetrics.h" +#include "gfx3DMatrix.h" +#include "nsIWidget.h" +#include "nsCSSProperty.h" +#include "nsStyleCoord.h" +#include "nsStyleConsts.h" +#include "nsGkAtoms.h" +#include "nsRuleNode.h" +#include "imgIContainer.h" +#include "mozilla/gfx/2D.h" +#include "Units.h" + +#include +#include + class nsIFormControlFrame; class nsPresContext; class nsIContent; @@ -30,32 +53,11 @@ class gfxContext; class nsPIDOMWindow; class imgIRequest; class nsIDocument; +class gfxPoint; struct nsStyleFont; struct nsStyleImageOrientation; struct nsOverflowAreas; -#include "mozilla/MemoryReporting.h" -#include "nsChangeHint.h" -#include "nsAutoPtr.h" -#include "nsFrameList.h" -#include "nsThreadUtils.h" -#include "nsIPrincipal.h" -#include "GraphicsFilter.h" -#include "nsCSSPseudoElements.h" -#include "FrameMetrics.h" -#include "gfx3DMatrix.h" -#include "nsIWidget.h" -#include "nsCSSProperty.h" -#include "nsStyleCoord.h" -#include "nsStyleConsts.h" -#include "nsGkAtoms.h" -#include "nsRuleNode.h" -#include "imgIContainer.h" -#include "mozilla/gfx/2D.h" - -#include -#include - namespace mozilla { class SVGImageContext; struct IntrinsicSize; @@ -107,6 +109,7 @@ class nsLayoutUtils public: typedef mozilla::layers::FrameMetrics FrameMetrics; typedef FrameMetrics::ViewID ViewID; + typedef mozilla::CSSPoint CSSPoint; /** * Finds previously assigned ViewID for the given content element, if any. @@ -683,6 +686,24 @@ public: */ static gfx3DMatrix GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor); + /** + * Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into + * account all relevant transformations on the frames up to (but excluding) + * their nearest common ancestor. + * If we encounter a transform that we need to invert but which is + * non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have + * no common ancestor, we return NO_COMMON_ANCESTOR. + * If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed + * in-place, otherwise they are untouched. + */ + enum TransformResult { + TRANSFORM_SUCCEEDED, + NO_COMMON_ANCESTOR, + NONINVERTIBLE_TRANSFORM + }; + static TransformResult TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame, + uint32_t aPointCount, CSSPoint* aPoints); + /** * Return true if a "layer transform" could be computed for aFrame, * and optionally return the computed transform. The returned @@ -877,6 +898,12 @@ public: */ static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback); + /** + * Find the first frame descendant of aFrame (including aFrame) which is + * not an anonymous frame that getBoxQuads/getClientRects should ignore. + */ + static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame); + class RectCallback { public: virtual void AddRect(const nsRect& aRect) = 0; From af322377544f0d35650587c038945f58e7e2965e Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:37 +0800 Subject: [PATCH 003/101] Bug 917755. Part 1.5: Make nsImageLoadingContent more robust in unified builds. r=matspal --- content/base/src/nsImageLoadingContent.cpp | 2 +- content/base/src/nsImageLoadingContent.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/content/base/src/nsImageLoadingContent.cpp b/content/base/src/nsImageLoadingContent.cpp index 64c7b0c8afd4..9548bc94e903 100644 --- a/content/base/src/nsImageLoadingContent.cpp +++ b/content/base/src/nsImageLoadingContent.cpp @@ -47,7 +47,7 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/ScriptSettings.h" -#if defined(XP_WIN) +#ifdef LoadImage // Undefine LoadImage to prevent naming conflict with Windows. #undef LoadImage #endif diff --git a/content/base/src/nsImageLoadingContent.h b/content/base/src/nsImageLoadingContent.h index 328124a757e6..7d5c5f3422fa 100644 --- a/content/base/src/nsImageLoadingContent.h +++ b/content/base/src/nsImageLoadingContent.h @@ -31,6 +31,11 @@ class nsPresContext; class nsIContent; class imgRequestProxy; +#ifdef LoadImage +// Undefine LoadImage to prevent naming conflict with Windows. +#undef LoadImage +#endif + class nsImageLoadingContent : public nsIImageLoadingContent, public imgIOnloadBlocker { From df8181c63ec201bc8747775d3573b8cf54199aa6 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:37 +0800 Subject: [PATCH 004/101] Bug 917755. Part 2: Implement DOMPoint. r=jst DOMPointReadOnly is not currently used by anything but it's in the spec so we might as well support it. It would be useful for adding "topLeft"-style APIs to DOMRect. --- content/base/src/DOMPoint.cpp | 43 ++++++++++ content/base/src/DOMPoint.h | 78 +++++++++++++++++++ content/base/src/moz.build | 2 + dom/bindings/Bindings.conf | 5 ++ .../mochitest/general/test_interfaces.html | 4 + dom/webidl/DOMPoint.webidl | 37 +++++++++ dom/webidl/moz.build | 1 + modules/libpref/src/init/all.js | 3 + 8 files changed, 173 insertions(+) create mode 100644 content/base/src/DOMPoint.cpp create mode 100644 content/base/src/DOMPoint.h create mode 100644 dom/webidl/DOMPoint.webidl diff --git a/content/base/src/DOMPoint.cpp b/content/base/src/DOMPoint.cpp new file mode 100644 index 000000000000..5414455683fa --- /dev/null +++ b/content/base/src/DOMPoint.cpp @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/DOMPoint.h" + +#include "mozilla/dom/DOMPointBinding.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "nsAutoPtr.h" + +using namespace mozilla; +using namespace mozilla::dom; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMPoint, mParent) + +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPoint, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPoint, Release) + +already_AddRefed +DOMPoint::Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams, + ErrorResult& aRV) +{ + nsRefPtr obj = + new DOMPoint(aGlobal.GetAsSupports(), aParams.mX, aParams.mY, + aParams.mZ, aParams.mW); + return obj.forget(); +} + +already_AddRefed +DOMPoint::Constructor(const GlobalObject& aGlobal, double aX, double aY, + double aZ, double aW, ErrorResult& aRV) +{ + nsRefPtr obj = + new DOMPoint(aGlobal.GetAsSupports(), aX, aY, aZ, aW); + return obj.forget(); +} + +JSObject* +DOMPoint::WrapObject(JSContext* aCx, JS::Handle aScope) +{ + return DOMPointBinding::Wrap(aCx, aScope, this); +} diff --git a/content/base/src/DOMPoint.h b/content/base/src/DOMPoint.h new file mode 100644 index 000000000000..6e69f7aae73a --- /dev/null +++ b/content/base/src/DOMPoint.h @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_DOMPOINT_H_ +#define MOZILLA_DOMPOINT_H_ + +#include "nsWrapperCache.h" +#include "nsISupports.h" +#include "nsCycleCollectionParticipant.h" +#include "mozilla/Attributes.h" +#include "mozilla/ErrorResult.h" +#include "nsCOMPtr.h" +#include "mozilla/dom/BindingDeclarations.h" + +namespace mozilla { +namespace dom { + +class GlobalObject; +class DOMPointInit; + +class DOMPointReadOnly : public nsWrapperCache +{ +public: + DOMPointReadOnly(nsISupports* aParent, double aX, double aY, + double aZ, double aW) + : mParent(aParent) + , mX(aX) + , mY(aY) + , mZ(aZ) + , mW(aW) + { + SetIsDOMBinding(); + } + + double X() const { return mX; } + double Y() const { return mY; } + double Z() const { return mZ; } + double W() const { return mW; } + +protected: + nsCOMPtr mParent; + double mX, mY, mZ, mW; +}; + +class DOMPoint MOZ_FINAL : public DOMPointReadOnly +{ +public: + DOMPoint(nsISupports* aParent, double aX = 0.0, double aY = 0.0, + double aZ = 0.0, double aW = 1.0) + : DOMPointReadOnly(aParent, aX, aY, aZ, aW) + {} + + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPoint) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPoint) + + static already_AddRefed + Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams, + ErrorResult& aRV); + static already_AddRefed + Constructor(const GlobalObject& aGlobal, double aX, double aY, + double aZ, double aW, ErrorResult& aRV); + + nsISupports* GetParentObject() const { return mParent; } + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aScope) MOZ_OVERRIDE; + + void SetX(double aX) { mX = aX; } + void SetY(double aY) { mY = aY; } + void SetZ(double aZ) { mZ = aZ; } + void SetW(double aW) { mW = aW; } +}; + +} +} + +#endif /*MOZILLA_DOMPOINT_H_*/ diff --git a/content/base/src/moz.build b/content/base/src/moz.build index c7bb37fd8517..bda6ff921fc3 100644 --- a/content/base/src/moz.build +++ b/content/base/src/moz.build @@ -60,6 +60,7 @@ EXPORTS.mozilla.dom += [ 'DocumentType.h', 'DOMImplementation.h', 'DOMParser.h', + 'DOMPoint.h', 'DOMRect.h', 'DOMStringList.h', 'EventSource.h', @@ -79,6 +80,7 @@ UNIFIED_SOURCES += [ 'DocumentType.cpp', 'DOMImplementation.cpp', 'DOMParser.cpp', + 'DOMPoint.cpp', 'DOMRect.cpp', 'DOMStringList.cpp', 'Element.cpp', diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index e6209f63f03a..561d234b163c 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -225,6 +225,11 @@ DOMInterfaces = { 'resultNotAddRefed': [ 'item' ] }, +'DOMPointReadOnly': { + 'headerFile': 'mozilla/dom/DOMPoint.h', + 'concrete': False, +}, + 'Console': { 'implicitJSContext': [ 'trace', 'time', 'timeEnd' ], }, diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 146665b4b69b..52b5711aa3fa 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -305,6 +305,10 @@ var interfaceNamesInGlobalScope = "DOMMMIError", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMParser", +// IMPORTANT: Do not change this list without review from a DOM peer! + "DOMPoint", +// IMPORTANT: Do not change this list without review from a DOM peer! + "DOMPointReadOnly", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMRect", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/DOMPoint.webidl b/dom/webidl/DOMPoint.webidl new file mode 100644 index 000000000000..d092d900f51e --- /dev/null +++ b/dom/webidl/DOMPoint.webidl @@ -0,0 +1,37 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/fxtf/geometry/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +[Pref="layout.css.DOMPoint.enabled"] +interface DOMPointReadOnly { + readonly attribute unrestricted double x; + readonly attribute unrestricted double y; + readonly attribute unrestricted double z; + readonly attribute unrestricted double w; +}; + +[Pref="layout.css.DOMPoint.enabled", + Constructor(optional DOMPointInit point), + Constructor(unrestricted double x, unrestricted double y, + optional unrestricted double z = 0, optional unrestricted double w = 1)] +interface DOMPoint : DOMPointReadOnly { + inherit attribute unrestricted double x; + inherit attribute unrestricted double y; + inherit attribute unrestricted double z; + inherit attribute unrestricted double w; +}; + +dictionary DOMPointInit { + unrestricted double x = 0; + unrestricted double y = 0; + unrestricted double z = 0; + unrestricted double w = 1; +}; \ No newline at end of file diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index ae24ef7f42cd..03f9418eee82 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -83,6 +83,7 @@ WEBIDL_FILES = [ 'DOMImplementation.webidl', 'DOMMMIError.webidl', 'DOMParser.webidl', + 'DOMPoint.webidl', 'DOMRect.webidl', 'DOMRectList.webidl', 'DOMRequest.webidl', diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index f4178a06c40e..e66ea049fa45 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1810,6 +1810,9 @@ pref("layout.css.sticky.enabled", true); // Is support for CSS "will-change" enabled? pref("layout.css.will-change.enabled", false); +// Is support for DOMPoint enabled? +pref("layout.css.DOMPoint.enabled", true); + // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From 13590066d30989bdd060ae73a60ebb720f2b8db8 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:21:03 +1200 Subject: [PATCH 005/101] Bug 917755. Part 3: Implement DOMRect per spec. r=jst --- content/base/src/DOMRect.cpp | 43 +++++- content/base/src/DOMRect.h | 139 ++++++++++++------ dom/bindings/Bindings.conf | 24 +-- .../mochitest/general/test_interfaces.html | 2 + dom/webidl/DOMRect.webidl | 36 +++-- dom/webidl/LegacyQueryInterface.webidl | 2 - 6 files changed, 176 insertions(+), 70 deletions(-) diff --git a/content/base/src/DOMRect.cpp b/content/base/src/DOMRect.cpp index 6223c158d850..f0d5a8f7120f 100644 --- a/content/base/src/DOMRect.cpp +++ b/content/base/src/DOMRect.cpp @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "DOMRect.h" +#include "mozilla/dom/DOMRect.h" #include "nsPresContext.h" #include "mozilla/dom/DOMRectListBinding.h" @@ -12,20 +12,30 @@ using namespace mozilla; using namespace mozilla::dom; -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMRect, mParent) -NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRect) -NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRect) -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRect) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMRectReadOnly, mParent) +NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectReadOnly) +NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectReadOnly) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRectReadOnly) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsIDOMClientRect) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END +JSObject* +DOMRectReadOnly::WrapObject(JSContext* aCx, JS::Handle aScope) +{ + MOZ_ASSERT(mParent); + return DOMRectReadOnlyBinding::Wrap(aCx, aScope, this); +} + +// ----------------------------------------------------------------------------- + +NS_IMPL_ISUPPORTS_INHERITED1(DOMRect, DOMRectReadOnly, nsIDOMClientRect) + #define FORWARD_GETTER(_name) \ NS_IMETHODIMP \ DOMRect::Get ## _name(float* aResult) \ { \ - *aResult = _name(); \ + *aResult = float(_name()); \ return NS_OK; \ } @@ -43,6 +53,23 @@ DOMRect::WrapObject(JSContext* aCx, JS::Handle aScope) return DOMRectBinding::Wrap(aCx, aScope, this); } +already_AddRefed +DOMRect::Constructor(const GlobalObject& aGlobal, ErrorResult& aRV) +{ + nsRefPtr obj = + new DOMRect(aGlobal.GetAsSupports(), 0.0, 0.0, 0.0, 0.0); + return obj.forget(); +} + +already_AddRefed +DOMRect::Constructor(const GlobalObject& aGlobal, double aX, double aY, + double aWidth, double aHeight, ErrorResult& aRV) +{ + nsRefPtr obj = + new DOMRect(aGlobal.GetAsSupports(), aX, aY, aWidth, aHeight); + return obj.forget(); +} + // ----------------------------------------------------------------------------- NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(DOMRectList, mParent, mArray) @@ -57,7 +84,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectList) NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectList) -NS_IMETHODIMP +NS_IMETHODIMP DOMRectList::GetLength(uint32_t* aLength) { *aLength = Length(); diff --git a/content/base/src/DOMRect.h b/content/base/src/DOMRect.h index ae3db528683c..bdef9ce37c2b 100644 --- a/content/base/src/DOMRect.h +++ b/content/base/src/DOMRect.h @@ -14,33 +14,29 @@ #include "nsWrapperCache.h" #include "nsCycleCollectionParticipant.h" #include "mozilla/Attributes.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/ErrorResult.h" +#include struct nsRect; namespace mozilla { namespace dom { -class DOMRect MOZ_FINAL : public nsIDOMClientRect - , public nsWrapperCache +class DOMRectReadOnly : public nsISupports + , public nsWrapperCache { public: - DOMRect(nsISupports* aParent) - : mParent(aParent), mX(0.0), mY(0.0), mWidth(0.0), mHeight(0.0) + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRectReadOnly) + + virtual ~DOMRectReadOnly() {} + + DOMRectReadOnly(nsISupports* aParent) + : mParent(aParent) { SetIsDOMBinding(); } - virtual ~DOMRect() {} - - void SetRect(float aX, float aY, float aWidth, float aHeight) { - mX = aX; mY = aY; mWidth = aWidth; mHeight = aHeight; - } - void SetLayoutRect(const nsRect& aLayoutRect); - - - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRect) - NS_DECL_NSIDOMCLIENTRECT - nsISupports* GetParentObject() const { @@ -50,40 +46,103 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aScope) MOZ_OVERRIDE; + virtual double X() const = 0; + virtual double Y() const = 0; + virtual double Width() const = 0; + virtual double Height() const = 0; - float Left() const + double Left() const { - return mX; + double x = X(), w = Width(); + return std::min(x, x + w); } - - float Top() const + double Top() const { - return mY; + double y = Y(), h = Height(); + return std::min(y, y + h); } - - float Right() const + double Right() const { - return mX + mWidth; + double x = X(), w = Width(); + return std::max(x, x + w); } - - float Bottom() const + double Bottom() const { - return mY + mHeight; - } - - float Width() const - { - return mWidth; - } - - float Height() const - { - return mHeight; + double y = Y(), h = Height(); + return std::max(y, y + h); } protected: nsCOMPtr mParent; - float mX, mY, mWidth, mHeight; +}; + +class DOMRect MOZ_FINAL : public DOMRectReadOnly + , public nsIDOMClientRect +{ +public: + DOMRect(nsISupports* aParent, double aX = 0, double aY = 0, + double aWidth = 0, double aHeight = 0) + : DOMRectReadOnly(aParent) + , mX(aX) + , mY(aY) + , mWidth(aWidth) + , mHeight(aHeight) + { + } + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIDOMCLIENTRECT + + static already_AddRefed + Constructor(const GlobalObject& aGlobal, ErrorResult& aRV); + static already_AddRefed + Constructor(const GlobalObject& aGlobal, double aX, double aY, + double aWidth, double aHeight, ErrorResult& aRV); + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aScope) MOZ_OVERRIDE; + + void SetRect(float aX, float aY, float aWidth, float aHeight) { + mX = aX; mY = aY; mWidth = aWidth; mHeight = aHeight; + } + void SetLayoutRect(const nsRect& aLayoutRect); + + virtual double X() const MOZ_OVERRIDE + { + return mX; + } + virtual double Y() const MOZ_OVERRIDE + { + return mY; + } + virtual double Width() const MOZ_OVERRIDE + { + return mWidth; + } + virtual double Height() const MOZ_OVERRIDE + { + return mHeight; + } + + void SetX(double aX) + { + mX = aX; + } + void SetY(double aY) + { + mY = aY; + } + void SetWidth(double aWidth) + { + mWidth = aWidth; + } + void SetHeight(double aHeight) + { + mHeight = aHeight; + } + +protected: + double mX, mY, mWidth, mHeight; }; class DOMRectList MOZ_FINAL : public nsIDOMClientRectList, @@ -145,9 +204,7 @@ public: } protected: - virtual ~DOMRectList() {} - - nsTArray< nsRefPtr > mArray; + nsTArray > mArray; nsCOMPtr mParent; }; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 561d234b163c..63bd7b9ec2da 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -220,16 +220,6 @@ DOMInterfaces = { 'nativeType': 'mozilla::dom::workers::ChromeWorkerPrivate', }, -'DOMRectList': { - 'headerFile': 'mozilla/dom/DOMRect.h', - 'resultNotAddRefed': [ 'item' ] -}, - -'DOMPointReadOnly': { - 'headerFile': 'mozilla/dom/DOMPoint.h', - 'concrete': False, -}, - 'Console': { 'implicitJSContext': [ 'trace', 'time', 'timeEnd' ], }, @@ -338,6 +328,20 @@ DOMInterfaces = { }, }, +'DOMPointReadOnly': { + 'headerFile': 'mozilla/dom/DOMPoint.h', + 'concrete': False, +}, + +'DOMRectList': { + 'headerFile': 'mozilla/dom/DOMRect.h', + 'resultNotAddRefed': [ 'item' ] +}, + +'DOMRectReadOnly': { + 'headerFile': 'mozilla/dom/DOMRect.h', +}, + 'DOMSettableTokenList': { 'nativeType': 'nsDOMSettableTokenList', }, diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 52b5711aa3fa..0cf08f3cfeb5 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -313,6 +313,8 @@ var interfaceNamesInGlobalScope = "DOMRect", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMRectList", +// IMPORTANT: Do not change this list without review from a DOM peer! + "DOMRectReadOnly", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMRequest", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/DOMRect.webidl b/dom/webidl/DOMRect.webidl index 73adf4a4bedf..1e817106cdb9 100644 --- a/dom/webidl/DOMRect.webidl +++ b/dom/webidl/DOMRect.webidl @@ -1,14 +1,32 @@ /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/fxtf/geometry/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ -interface DOMRect -{ - readonly attribute float left; - readonly attribute float top; - readonly attribute float right; - readonly attribute float bottom; - readonly attribute float width; - readonly attribute float height; +[Constructor, + Constructor(unrestricted double x, unrestricted double y, + unrestricted double width, unrestricted double height)] +interface DOMRect : DOMRectReadOnly { + inherit attribute unrestricted double x; + inherit attribute unrestricted double y; + inherit attribute unrestricted double width; + inherit attribute unrestricted double height; }; + +interface DOMRectReadOnly { + readonly attribute unrestricted double x; + readonly attribute unrestricted double y; + readonly attribute unrestricted double width; + readonly attribute unrestricted double height; + readonly attribute unrestricted double top; + readonly attribute unrestricted double right; + readonly attribute unrestricted double bottom; + readonly attribute unrestricted double left; +}; \ No newline at end of file diff --git a/dom/webidl/LegacyQueryInterface.webidl b/dom/webidl/LegacyQueryInterface.webidl index fbe00d2c9f8b..20d70c5d6f33 100644 --- a/dom/webidl/LegacyQueryInterface.webidl +++ b/dom/webidl/LegacyQueryInterface.webidl @@ -24,8 +24,6 @@ CSSStyleDeclaration implements LegacyQueryInterface; CSSValueList implements LegacyQueryInterface; DOMImplementation implements LegacyQueryInterface; DOMParser implements LegacyQueryInterface; -DOMRect implements LegacyQueryInterface; -DOMRectList implements LegacyQueryInterface; DOMStringMap implements LegacyQueryInterface; DOMTokenList implements LegacyQueryInterface; Document implements LegacyQueryInterface; From 9d59ab279c30c4053d349f2f4a1de294d0296d35 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:21:04 +1200 Subject: [PATCH 006/101] Bug 917755. Part 4: Add DOMQuad implementation. r=jst --- content/base/src/DOMQuad.cpp | 159 ++++++++++++++++++ content/base/src/DOMQuad.h | 70 ++++++++ content/base/src/moz.build | 2 + dom/bindings/Bindings.conf | 4 + .../mochitest/general/test_interfaces.html | 2 + dom/webidl/DOMQuad.webidl | 23 +++ dom/webidl/moz.build | 1 + modules/libpref/src/init/all.js | 3 + 8 files changed, 264 insertions(+) create mode 100644 content/base/src/DOMQuad.cpp create mode 100644 content/base/src/DOMQuad.h create mode 100644 dom/webidl/DOMQuad.webidl diff --git a/content/base/src/DOMQuad.cpp b/content/base/src/DOMQuad.cpp new file mode 100644 index 000000000000..1445a531f06d --- /dev/null +++ b/content/base/src/DOMQuad.cpp @@ -0,0 +1,159 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/DOMQuad.h" + +#include "mozilla/dom/DOMQuadBinding.h" +#include "mozilla/dom/DOMPoint.h" +#include "mozilla/dom/DOMRect.h" +#include + +using namespace mozilla; +using namespace mozilla::dom; +using namespace mozilla::gfx; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_6(DOMQuad, mParent, mBounds, mPoints[0], + mPoints[1], mPoints[2], mPoints[3]) + +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMQuad, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMQuad, Release) + +DOMQuad::DOMQuad(nsISupports* aParent, CSSPoint aPoints[4]) + : mParent(aParent) +{ + SetIsDOMBinding(); + for (uint32_t i = 0; i < 4; ++i) { + mPoints[i] = new DOMPoint(aParent, aPoints[i].x, aPoints[i].y); + } +} + +DOMQuad::DOMQuad(nsISupports* aParent) + : mParent(aParent) +{ + SetIsDOMBinding(); +} + +DOMQuad::~DOMQuad() +{ +} + +JSObject* +DOMQuad::WrapObject(JSContext* aCx, JS::Handle aScope) +{ + return DOMQuadBinding::Wrap(aCx, aScope, this); +} + +already_AddRefed +DOMQuad::Constructor(const GlobalObject& aGlobal, + const DOMPointInit& aP1, + const DOMPointInit& aP2, + const DOMPointInit& aP3, + const DOMPointInit& aP4, + ErrorResult& aRV) +{ + nsRefPtr obj = new DOMQuad(aGlobal.GetAsSupports()); + obj->mPoints[0] = DOMPoint::Constructor(aGlobal, aP1, aRV); + obj->mPoints[1] = DOMPoint::Constructor(aGlobal, aP2, aRV); + obj->mPoints[2] = DOMPoint::Constructor(aGlobal, aP3, aRV); + obj->mPoints[3] = DOMPoint::Constructor(aGlobal, aP4, aRV); + return obj.forget(); +} + +already_AddRefed +DOMQuad::Constructor(const GlobalObject& aGlobal, const DOMRectReadOnly& aRect, + ErrorResult& aRV) +{ + CSSPoint points[4]; + Float x = aRect.X(), y = aRect.Y(), w = aRect.Width(), h = aRect.Height(); + points[0] = CSSPoint(x, y); + points[1] = CSSPoint(x + w, y); + points[2] = CSSPoint(x + w, y + h); + points[3] = CSSPoint(x, y + h); + nsRefPtr obj = new DOMQuad(aGlobal.GetAsSupports(), points); + return obj.forget(); +} + +class DOMQuad::QuadBounds MOZ_FINAL : public DOMRectReadOnly +{ +public: + QuadBounds(DOMQuad* aQuad) + : DOMRectReadOnly(aQuad->GetParentObject()) + , mQuad(aQuad) + {} + + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(QuadBounds, DOMRectReadOnly) + NS_DECL_ISUPPORTS_INHERITED + + virtual double X() const + { + double x1, x2; + GetHorizontalMinMax(&x1, &x2); + return x1; + } + virtual double Y() const + { + double y1, y2; + GetVerticalMinMax(&y1, &y2); + return y1; + } + virtual double Width() const + { + double x1, x2; + GetHorizontalMinMax(&x1, &x2); + return x2 - x1; + } + virtual double Height() const + { + double y1, y2; + GetVerticalMinMax(&y1, &y2); + return y2 - y1; + } + + void GetHorizontalMinMax(double* aX1, double* aX2) const + { + double x1, x2; + x1 = x2 = mQuad->Point(0)->X(); + for (uint32_t i = 1; i < 4; ++i) { + double x = mQuad->Point(i)->X(); + x1 = std::min(x1, x); + x2 = std::max(x2, x); + } + *aX1 = x1; + *aX2 = x2; + } + + void GetVerticalMinMax(double* aY1, double* aY2) const + { + double y1, y2; + y1 = y2 = mQuad->Point(0)->Y(); + for (uint32_t i = 1; i < 4; ++i) { + double y = mQuad->Point(i)->Y(); + y1 = std::min(y1, y); + y2 = std::max(y2, y); + } + *aY1 = y1; + *aY2 = y2; + } + +protected: + nsRefPtr mQuad; +}; + +NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DOMQuad::QuadBounds, DOMRectReadOnly, mQuad) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMQuad::QuadBounds) +NS_INTERFACE_MAP_END_INHERITING(DOMRectReadOnly) + +NS_IMPL_ADDREF_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly) +NS_IMPL_RELEASE_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly) + +DOMRectReadOnly* +DOMQuad::Bounds() const +{ + if (!mBounds) { + mBounds = new QuadBounds(const_cast(this)); + } + return mBounds; +} diff --git a/content/base/src/DOMQuad.h b/content/base/src/DOMQuad.h new file mode 100644 index 000000000000..0806b246f3dd --- /dev/null +++ b/content/base/src/DOMQuad.h @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_DOMQUAD_H_ +#define MOZILLA_DOMQUAD_H_ + +#include "nsWrapperCache.h" +#include "nsISupports.h" +#include "nsCycleCollectionParticipant.h" +#include "mozilla/Attributes.h" +#include "nsCOMPtr.h" +#include "nsAutoPtr.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/ErrorResult.h" +#include "Units.h" + +namespace mozilla { +namespace dom { + +class DOMRectReadOnly; +class DOMPoint; +struct DOMPointInit; + +class DOMQuad MOZ_FINAL : public nsWrapperCache +{ +public: + DOMQuad(nsISupports* aParent, CSSPoint aPoints[4]); + DOMQuad(nsISupports* aParent); + ~DOMQuad(); + + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMQuad) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMQuad) + + nsISupports* GetParentObject() const { return mParent; } + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aScope) MOZ_OVERRIDE; + + static already_AddRefed + Constructor(const GlobalObject& aGlobal, + const DOMPointInit& aP1, + const DOMPointInit& aP2, + const DOMPointInit& aP3, + const DOMPointInit& aP4, + ErrorResult& aRV); + static already_AddRefed + Constructor(const GlobalObject& aGlobal, const DOMRectReadOnly& aRect, + ErrorResult& aRV); + + DOMRectReadOnly* Bounds() const; + DOMPoint* P1() const { return mPoints[0]; } + DOMPoint* P2() const { return mPoints[1]; } + DOMPoint* P3() const { return mPoints[2]; } + DOMPoint* P4() const { return mPoints[3]; } + + DOMPoint* Point(uint32_t aIndex) { return mPoints[aIndex]; } + +protected: + class QuadBounds; + + nsCOMPtr mParent; + nsRefPtr mPoints[4]; + mutable nsRefPtr mBounds; // allocated lazily +}; + +} +} + +#endif /*MOZILLA_DOMRECT_H_*/ diff --git a/content/base/src/moz.build b/content/base/src/moz.build index bda6ff921fc3..82304b5f8ed0 100644 --- a/content/base/src/moz.build +++ b/content/base/src/moz.build @@ -61,6 +61,7 @@ EXPORTS.mozilla.dom += [ 'DOMImplementation.h', 'DOMParser.h', 'DOMPoint.h', + 'DOMQuad.h', 'DOMRect.h', 'DOMStringList.h', 'EventSource.h', @@ -81,6 +82,7 @@ UNIFIED_SOURCES += [ 'DOMImplementation.cpp', 'DOMParser.cpp', 'DOMPoint.cpp', + 'DOMQuad.cpp', 'DOMRect.cpp', 'DOMStringList.cpp', 'Element.cpp', diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 63bd7b9ec2da..e3afdcb20e14 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -342,6 +342,10 @@ DOMInterfaces = { 'headerFile': 'mozilla/dom/DOMRect.h', }, +'DOMQuad': { + 'resultNotAddRefed': [ 'bounds', 'p0', 'p1', 'p2', 'p3' ] +}, + 'DOMSettableTokenList': { 'nativeType': 'nsDOMSettableTokenList', }, diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 0cf08f3cfeb5..c5ce599114c7 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -309,6 +309,8 @@ var interfaceNamesInGlobalScope = "DOMPoint", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMPointReadOnly", +// IMPORTANT: Do not change this list without review from a DOM peer! + "DOMQuad", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMRect", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/DOMQuad.webidl b/dom/webidl/DOMQuad.webidl new file mode 100644 index 000000000000..b933987d5979 --- /dev/null +++ b/dom/webidl/DOMQuad.webidl @@ -0,0 +1,23 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/fxtf/geometry/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +[Pref="layout.css.DOMQuad.enabled", + Constructor(optional DOMPointInit p1, optional DOMPointInit p2, + optional DOMPointInit p3, optional DOMPointInit p4), + Constructor(DOMRectReadOnly rect)] +interface DOMQuad { + [SameObject] readonly attribute DOMPoint p1; + [SameObject] readonly attribute DOMPoint p2; + [SameObject] readonly attribute DOMPoint p3; + [SameObject] readonly attribute DOMPoint p4; + [SameObject] readonly attribute DOMRectReadOnly bounds; +}; \ No newline at end of file diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 03f9418eee82..a4dfc1a0d299 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -84,6 +84,7 @@ WEBIDL_FILES = [ 'DOMMMIError.webidl', 'DOMParser.webidl', 'DOMPoint.webidl', + 'DOMQuad.webidl', 'DOMRect.webidl', 'DOMRectList.webidl', 'DOMRequest.webidl', diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index e66ea049fa45..04513a3efa11 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1813,6 +1813,9 @@ pref("layout.css.will-change.enabled", false); // Is support for DOMPoint enabled? pref("layout.css.DOMPoint.enabled", true); +// Is support for DOMQuad enabled? +pref("layout.css.DOMQuad.enabled", true); + // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From 06a94c462c911b633b0c8e714ced677658a886c1 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:38 +0800 Subject: [PATCH 007/101] Bug 917755. Part 5: Implement GeometryUtils GetBoxQuads. r=matspal --- layout/base/GeometryUtils.cpp | 238 ++++++++++++++++++++++++++++++++++ layout/base/GeometryUtils.h | 41 ++++++ layout/base/moz.build | 2 + 3 files changed, 281 insertions(+) create mode 100644 layout/base/GeometryUtils.cpp create mode 100644 layout/base/GeometryUtils.h diff --git a/layout/base/GeometryUtils.cpp b/layout/base/GeometryUtils.cpp new file mode 100644 index 000000000000..8f3b9f70a8ec --- /dev/null +++ b/layout/base/GeometryUtils.cpp @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "GeometryUtils.h" + +#include "mozilla/dom/GeometryUtilsBinding.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/Text.h" +#include "mozilla/dom/DOMQuad.h" +#include "nsIFrame.h" +#include "nsGenericDOMDataNode.h" +#include "nsCSSFrameConstructor.h" +#include "nsLayoutUtils.h" +#include "nsSVGUtils.h" + +using namespace mozilla; +using namespace mozilla::dom; + +namespace mozilla { + +typedef OwningTextOrElementOrDocument GeometryNode; + +enum GeometryNodeType { + GEOMETRY_NODE_ELEMENT, + GEOMETRY_NODE_TEXT, + GEOMETRY_NODE_DOCUMENT +}; + +static nsIFrame* +GetFrameForNode(nsINode* aNode, GeometryNodeType aType) +{ + nsIDocument* doc = aNode->OwnerDoc(); + doc->FlushPendingNotifications(Flush_Layout); + switch (aType) { + case GEOMETRY_NODE_ELEMENT: + return aNode->AsContent()->GetPrimaryFrame(); + case GEOMETRY_NODE_TEXT: { + nsIPresShell* presShell = doc->GetShell(); + if (presShell) { + return presShell->FrameConstructor()->EnsureFrameForTextNode( + static_cast(aNode)); + } + return nullptr; + } + case GEOMETRY_NODE_DOCUMENT: { + nsIPresShell* presShell = doc->GetShell(); + return presShell ? presShell->GetRootFrame() : nullptr; + } + default: + MOZ_ASSERT(false, "Unknown GeometryNodeType"); + return nullptr; + } +} + +static nsIFrame* +GetFrameForGeometryNode(const Optional& aGeometryNode, + nsINode* aDefaultNode) +{ + if (!aGeometryNode.WasPassed()) { + return GetFrameForNode(aDefaultNode->OwnerDoc(), GEOMETRY_NODE_DOCUMENT); + } + + const GeometryNode& value = aGeometryNode.Value(); + if (value.IsElement()) { + return GetFrameForNode(value.GetAsElement(), GEOMETRY_NODE_ELEMENT); + } + if (value.IsDocument()) { + return GetFrameForNode(value.GetAsDocument(), GEOMETRY_NODE_DOCUMENT); + } + return GetFrameForNode(value.GetAsText(), GEOMETRY_NODE_TEXT); +} + +static nsIFrame* +GetFrameForNode(nsINode* aNode) +{ + if (aNode->IsElement()) { + return GetFrameForNode(aNode, GEOMETRY_NODE_ELEMENT); + } + if (aNode == aNode->OwnerDoc()) { + return GetFrameForNode(aNode, GEOMETRY_NODE_DOCUMENT); + } + NS_ASSERTION(aNode->IsNodeOfType(nsINode::eTEXT), "Unknown node type"); + return GetFrameForNode(aNode, GEOMETRY_NODE_TEXT); +} + +static nsIFrame* +GetFirstNonAnonymousFrameForGeometryNode(const Optional& aNode, + nsINode* aDefaultNode) +{ + nsIFrame* f = GetFrameForGeometryNode(aNode, aDefaultNode); + if (f) { + f = nsLayoutUtils::GetFirstNonAnonymousFrame(f); + } + return f; +} + +/** + * This can modify aFrame to point to a different frame. This is needed to + * handle SVG, where SVG elements can only compute a rect that's valid with + * respect to the "outer SVG" frame. + */ +static nsRect +GetBoxRectForFrame(nsIFrame** aFrame, CSSBoxType aType) +{ + nsRect r; + nsIFrame* f = nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(*aFrame, &r); + if (f) { + // For SVG, the BoxType is ignored. + *aFrame = f; + return r; + } + + f = *aFrame; + switch (aType) { + case CSSBoxType::Content: r = f->GetContentRectRelativeToSelf(); break; + case CSSBoxType::Padding: r = f->GetPaddingRectRelativeToSelf(); break; + case CSSBoxType::Border: r = nsRect(nsPoint(0, 0), f->GetSize()); break; + case CSSBoxType::Margin: { + r = nsRect(nsPoint(0, 0), f->GetSize()); + r.Inflate(f->GetUsedMargin()); + break; + } + default: MOZ_ASSERT(false, "unknown box type"); return r; + } + + return r; +} + +class AccumulateQuadCallback : public nsLayoutUtils::BoxCallback { +public: + AccumulateQuadCallback(nsISupports* aParentObject, + nsTArray >& aResult, + nsIFrame* aRelativeToFrame, + const nsPoint& aRelativeToBoxTopLeft, + CSSBoxType aBoxType) + : mParentObject(aParentObject) + , mResult(aResult) + , mRelativeToFrame(aRelativeToFrame) + , mRelativeToBoxTopLeft(aRelativeToBoxTopLeft) + , mBoxType(aBoxType) + { + } + + virtual void AddBox(nsIFrame* aFrame) MOZ_OVERRIDE + { + nsIFrame* f = aFrame; + nsRect box = GetBoxRectForFrame(&f, mBoxType); + nsPoint appUnits[4] = + { box.TopLeft(), box.TopRight(), box.BottomRight(), box.BottomLeft() }; + CSSPoint points[4]; + for (uint32_t i = 0; i < 4; ++i) { + points[i] = CSSPoint(nsPresContext::AppUnitsToFloatCSSPixels(appUnits[i].x), + nsPresContext::AppUnitsToFloatCSSPixels(appUnits[i].y)); + } + nsLayoutUtils::TransformResult rv = + nsLayoutUtils::TransformPoints(f, mRelativeToFrame, 4, points); + if (rv == nsLayoutUtils::TRANSFORM_SUCCEEDED) { + CSSPoint delta(nsPresContext::AppUnitsToFloatCSSPixels(mRelativeToBoxTopLeft.x), + nsPresContext::AppUnitsToFloatCSSPixels(mRelativeToBoxTopLeft.y)); + for (uint32_t i = 0; i < 4; ++i) { + points[i] -= delta; + } + } else { + PodArrayZero(points); + } + mResult.AppendElement(new DOMQuad(mParentObject, points)); + } + + nsISupports* mParentObject; + nsTArray >& mResult; + nsIFrame* mRelativeToFrame; + nsPoint mRelativeToBoxTopLeft; + CSSBoxType mBoxType; +}; + +static nsPresContext* +FindTopLevelPresContext(nsPresContext* aPC) +{ + bool isChrome = aPC->IsChrome(); + nsPresContext* pc = aPC; + for (;;) { + nsPresContext* parent = pc->GetParentPresContext(); + if (!parent || parent->IsChrome() != isChrome) { + return pc; + } + pc = parent; + } +} + +static bool +CheckFramesInSameTopLevelBrowsingContext(nsIFrame* aFrame1, nsIFrame* aFrame2) +{ + nsPresContext* pc1 = aFrame1->PresContext(); + nsPresContext* pc2 = aFrame2->PresContext(); + if (pc1 == pc2) { + return true; + } + if (nsContentUtils::IsCallerChrome()) { + return true; + } + if (FindTopLevelPresContext(pc1) == FindTopLevelPresContext(pc2)) { + return true; + } + return false; +} + +void GetBoxQuads(nsINode* aNode, + const dom::BoxQuadOptions& aOptions, + nsTArray >& aResult, + ErrorResult& aRv) +{ + nsIFrame* frame = GetFrameForNode(aNode); + if (!frame) { + // No boxes to return + return; + } + nsIDocument* ownerDoc = aNode->OwnerDoc(); + nsIFrame* relativeToFrame = + GetFirstNonAnonymousFrameForGeometryNode(aOptions.mRelativeTo, ownerDoc); + if (!relativeToFrame) { + aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR); + return; + } + if (!CheckFramesInSameTopLevelBrowsingContext(frame, relativeToFrame)) { + aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR); + return; + } + // GetBoxRectForFrame can modify relativeToFrame so call it first. + nsPoint relativeToTopLeft = + GetBoxRectForFrame(&relativeToFrame, CSSBoxType::Border).TopLeft(); + AccumulateQuadCallback callback(ownerDoc, aResult, relativeToFrame, + relativeToTopLeft, aOptions.mBox); + nsLayoutUtils::GetAllInFlowBoxes(frame, &callback); +} + +} diff --git a/layout/base/GeometryUtils.h b/layout/base/GeometryUtils.h new file mode 100644 index 000000000000..72592508fcbd --- /dev/null +++ b/layout/base/GeometryUtils.h @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GEOMETRYUTILS_H_ +#define MOZILLA_GEOMETRYUTILS_H_ + +#include "mozilla/ErrorResult.h" +#include "nsTArray.h" +#include "nsCOMPtr.h" + +/** + * This file defines utility functions for converting between layout + * coordinate systems. + */ + +class nsINode; +class nsIDocument; + +namespace mozilla { + +namespace dom { +struct BoxQuadOptions; +class DOMQuad; +class Element; +class Text; +} + +/** + * Computes quads for aNode using aOptions, according to GeometryUtils.getBoxQuads. + * May set an error in aRv. + */ +void GetBoxQuads(nsINode* aNode, + const dom::BoxQuadOptions& aOptions, + nsTArray >& aResult, + ErrorResult& aRv); + +} + +#endif /* MOZILLA_GEOMETRYUTILS_H_ */ diff --git a/layout/base/moz.build b/layout/base/moz.build index 5102ba082f25..5095f56661a2 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -60,6 +60,7 @@ EXPORTS += [ ] EXPORTS.mozilla += [ + 'GeometryUtils.h', 'PaintTracker.h', ] @@ -69,6 +70,7 @@ UNIFIED_SOURCES += [ 'DisplayListClipState.cpp', 'FrameLayerBuilder.cpp', 'FramePropertyTable.cpp', + 'GeometryUtils.cpp', 'MaskLayerImageCache.cpp', 'nsCaret.cpp', 'nsCounterManager.cpp', From 05e0309b2bb656f25aaa3c6849e3c1e182494265 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:38 +0800 Subject: [PATCH 008/101] Bug 917755. Part 5.5: Implement getBoxQuads DOM API. r=jst --- content/base/public/nsINode.h | 10 +++++++++ content/base/src/nsINode.cpp | 9 ++++++++ dom/webidl/GeometryUtils.webidl | 38 +++++++++++++++++++++++++++++++++ dom/webidl/moz.build | 1 + modules/libpref/src/init/all.js | 7 ++++++ 5 files changed, 65 insertions(+) create mode 100644 dom/webidl/GeometryUtils.webidl diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 300a95690056..3fe973fd99b5 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -66,6 +66,8 @@ inline bool IsSpaceCharacter(char aChar) { aChar == '\f'; } class Element; +struct BoxQuadOptions; +class DOMQuad; class EventHandlerNonNull; class OnErrorEventHandlerNonNull; template class Optional; @@ -279,6 +281,10 @@ private: class nsINode : public mozilla::dom::EventTarget { public: + typedef mozilla::dom::BoxQuadOptions BoxQuadOptions; + typedef mozilla::dom::DOMQuad DOMQuad; + typedef mozilla::ErrorResult ErrorResult; + NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID) // Among the sub-classes that inherit (directly or indirectly) from nsINode, @@ -1610,6 +1616,10 @@ public: mozilla::dom::Element* GetFirstElementChild() const; mozilla::dom::Element* GetLastElementChild() const; + void GetBoxQuads(const BoxQuadOptions& aOptions, + nsTArray >& aResult, + mozilla::ErrorResult& aRv); + protected: // Override this function to create a custom slots class. diff --git a/content/base/src/nsINode.cpp b/content/base/src/nsINode.cpp index d6b84d3979a2..953912d33043 100644 --- a/content/base/src/nsINode.cpp +++ b/content/base/src/nsINode.cpp @@ -103,6 +103,7 @@ #include #include "nsGlobalWindow.h" #include "nsDOMMutationObserver.h" +#include "GeometryUtils.h" using namespace mozilla; using namespace mozilla::dom; @@ -1140,6 +1141,14 @@ nsINode::PreHandleEvent(EventChainPreVisitor& aVisitor) return NS_ERROR_NOT_IMPLEMENTED; } +void +nsINode::GetBoxQuads(const BoxQuadOptions& aOptions, + nsTArray >& aResult, + mozilla::ErrorResult& aRv) +{ + mozilla::GetBoxQuads(this, aOptions, aResult, aRv); +} + nsresult nsINode::DispatchEvent(nsIDOMEvent *aEvent, bool* aRetVal) { diff --git a/dom/webidl/GeometryUtils.webidl b/dom/webidl/GeometryUtils.webidl new file mode 100644 index 000000000000..d34a614af224 --- /dev/null +++ b/dom/webidl/GeometryUtils.webidl @@ -0,0 +1,38 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/csswg/cssom-view/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +enum CSSBoxType { "margin", "border", "padding", "content" }; +dictionary BoxQuadOptions { + CSSBoxType box = "border"; + GeometryNode relativeTo; +}; + +dictionary ConvertCoordinateOptions { + CSSBoxType fromBox = "border"; + CSSBoxType toBox = "border"; +}; + +[NoInterfaceObject] +interface GeometryUtils { + [Throws, Pref="layout.css.getBoxQuads.enabled"] + sequence getBoxQuads(optional BoxQuadOptions options); +// DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional ConvertCoordinateOptions options); +// DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options); +// DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options); +}; + +Text implements GeometryUtils; +Element implements GeometryUtils; +// PseudoElement implements GeometryUtils; +Document implements GeometryUtils; + +typedef (Text or Element /* or PseudoElement */ or Document) GeometryNode; \ No newline at end of file diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index a4dfc1a0d299..f4934df66f2a 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -115,6 +115,7 @@ WEBIDL_FILES = [ 'Function.webidl', 'GainNode.webidl', 'Geolocation.webidl', + 'GeometryUtils.webidl', 'GetUserMediaRequest.webidl', 'History.webidl', 'HTMLAnchorElement.webidl', diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 04513a3efa11..b07b9f2e2b60 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1816,6 +1816,13 @@ pref("layout.css.DOMPoint.enabled", true); // Is support for DOMQuad enabled? pref("layout.css.DOMQuad.enabled", true); +// Is support for GeometryUtils.getBoxQuads enabled? +#ifdef RELEASE_BUILD +pref("layout.css.getBoxQuads.enabled", false); +#else +pref("layout.css.getBoxQuads.enabled", true); +#endif + // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From 7cf35d690c9ad3b68a9e676497954e017d099e3e Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:21:42 +1200 Subject: [PATCH 009/101] Bug 917755. Part 6: Add tests for getBoxQuads. r=matspal --- layout/base/tests/mochitest.ini | 1 + ...test_getBoxQuads_convertPointRectQuad.html | 525 ++++++++++++++++++ 2 files changed, 526 insertions(+) create mode 100644 layout/base/tests/test_getBoxQuads_convertPointRectQuad.html diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index 3cb3967cf3c6..f8e9af0ad75e 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -458,6 +458,7 @@ skip-if = toolkit == "win" skip-if = toolkit == "win" [test_flush_on_paint.html] skip-if = true || (toolkit == 'android') || (toolkit == "cocoa") # Bug 688128, bug 539356 +[test_getBoxQuads_convertPointRectQuad.html] [test_bug687297.html] skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 948948 support-files = diff --git a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html new file mode 100644 index 000000000000..5c41d6a588a6 --- /dev/null +++ b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html @@ -0,0 +1,525 @@ + + + + + + + + +

+ + +
+
+
+
+ +
+ + + +
+ + + + + + + + +
Cell
Caption
+ +
+
+
+
+ +
+ +
T +TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText
+ +
+ +
+ + + +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+ + + + +
+
+
+
+
+ + + + From f89a6a8e48b260e605827cc3688f403db60292a0 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:38 +0800 Subject: [PATCH 010/101] Bug 918189. Part 1: Implement GeometryUtils ConvertQuad/Rect/PointFromNode. r=mats --- layout/base/GeometryUtils.cpp | 141 ++++++++++++++++++++++++++++++++-- layout/base/GeometryUtils.h | 29 ++++++- 2 files changed, 163 insertions(+), 7 deletions(-) diff --git a/layout/base/GeometryUtils.cpp b/layout/base/GeometryUtils.cpp index 8f3b9f70a8ec..55c664a0bf9b 100644 --- a/layout/base/GeometryUtils.cpp +++ b/layout/base/GeometryUtils.cpp @@ -5,10 +5,13 @@ #include "GeometryUtils.h" +#include "mozilla/dom/DOMPointBinding.h" #include "mozilla/dom/GeometryUtilsBinding.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/Text.h" +#include "mozilla/dom/DOMPoint.h" #include "mozilla/dom/DOMQuad.h" +#include "mozilla/dom/DOMRect.h" #include "nsIFrame.h" #include "nsGenericDOMDataNode.h" #include "nsCSSFrameConstructor.h" @@ -20,8 +23,6 @@ using namespace mozilla::dom; namespace mozilla { -typedef OwningTextOrElementOrDocument GeometryNode; - enum GeometryNodeType { GEOMETRY_NODE_ELEMENT, GEOMETRY_NODE_TEXT, @@ -55,14 +56,14 @@ GetFrameForNode(nsINode* aNode, GeometryNodeType aType) } static nsIFrame* -GetFrameForGeometryNode(const Optional& aGeometryNode, +GetFrameForGeometryNode(const Optional& aGeometryNode, nsINode* aDefaultNode) { if (!aGeometryNode.WasPassed()) { return GetFrameForNode(aDefaultNode->OwnerDoc(), GEOMETRY_NODE_DOCUMENT); } - const GeometryNode& value = aGeometryNode.Value(); + const OwningGeometryNode& value = aGeometryNode.Value(); if (value.IsElement()) { return GetFrameForNode(value.GetAsElement(), GEOMETRY_NODE_ELEMENT); } @@ -72,6 +73,18 @@ GetFrameForGeometryNode(const Optional& aGeometryNode, return GetFrameForNode(value.GetAsText(), GEOMETRY_NODE_TEXT); } +static nsIFrame* +GetFrameForGeometryNode(const GeometryNode& aGeometryNode) +{ + if (aGeometryNode.IsElement()) { + return GetFrameForNode(&aGeometryNode.GetAsElement(), GEOMETRY_NODE_ELEMENT); + } + if (aGeometryNode.IsDocument()) { + return GetFrameForNode(&aGeometryNode.GetAsDocument(), GEOMETRY_NODE_DOCUMENT); + } + return GetFrameForNode(&aGeometryNode.GetAsText(), GEOMETRY_NODE_TEXT); +} + static nsIFrame* GetFrameForNode(nsINode* aNode) { @@ -86,7 +99,7 @@ GetFrameForNode(nsINode* aNode) } static nsIFrame* -GetFirstNonAnonymousFrameForGeometryNode(const Optional& aNode, +GetFirstNonAnonymousFrameForGeometryNode(const Optional& aNode, nsINode* aDefaultNode) { nsIFrame* f = GetFrameForGeometryNode(aNode, aDefaultNode); @@ -96,6 +109,26 @@ GetFirstNonAnonymousFrameForGeometryNode(const Optional& aNode, return f; } +static nsIFrame* +GetFirstNonAnonymousFrameForGeometryNode(const GeometryNode& aNode) +{ + nsIFrame* f = GetFrameForGeometryNode(aNode); + if (f) { + f = nsLayoutUtils::GetFirstNonAnonymousFrame(f); + } + return f; +} + +static nsIFrame* +GetFirstNonAnonymousFrameForNode(nsINode* aNode) +{ + nsIFrame* f = GetFrameForNode(aNode); + if (f) { + f = nsLayoutUtils::GetFirstNonAnonymousFrame(f); + } + return f; +} + /** * This can modify aFrame to point to a different frame. This is needed to * handle SVG, where SVG elements can only compute a rect that's valid with @@ -235,4 +268,102 @@ void GetBoxQuads(nsINode* aNode, nsLayoutUtils::GetAllInFlowBoxes(frame, &callback); } +static void +TransformPoints(nsINode* aTo, const GeometryNode& aFrom, + uint32_t aPointCount, CSSPoint* aPoints, + const ConvertCoordinateOptions& aOptions, ErrorResult& aRv) +{ + nsIFrame* fromFrame = GetFirstNonAnonymousFrameForGeometryNode(aFrom); + nsIFrame* toFrame = GetFirstNonAnonymousFrameForNode(aTo); + if (!fromFrame || !toFrame) { + aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR); + return; + } + if (!CheckFramesInSameTopLevelBrowsingContext(fromFrame, toFrame)) { + aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR); + return; + } + + nsPoint fromOffset = GetBoxRectForFrame(&fromFrame, aOptions.mFromBox).TopLeft(); + nsPoint toOffset = GetBoxRectForFrame(&toFrame, aOptions.mToBox).TopLeft(); + CSSPoint fromOffsetGfx(nsPresContext::AppUnitsToFloatCSSPixels(fromOffset.x), + nsPresContext::AppUnitsToFloatCSSPixels(fromOffset.y)); + for (uint32_t i = 0; i < aPointCount; ++i) { + aPoints[i] += fromOffsetGfx; + } + nsLayoutUtils::TransformResult rv = + nsLayoutUtils::TransformPoints(fromFrame, toFrame, aPointCount, aPoints); + if (rv == nsLayoutUtils::TRANSFORM_SUCCEEDED) { + CSSPoint toOffsetGfx(nsPresContext::AppUnitsToFloatCSSPixels(toOffset.x), + nsPresContext::AppUnitsToFloatCSSPixels(toOffset.y)); + for (uint32_t i = 0; i < aPointCount; ++i) { + aPoints[i] -= toOffsetGfx; + } + } else { + PodZero(aPoints, aPointCount); + } +} + +already_AddRefed +ConvertQuadFromNode(nsINode* aTo, dom::DOMQuad& aQuad, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + CSSPoint points[4]; + for (uint32_t i = 0; i < 4; ++i) { + DOMPoint* p = aQuad.Point(i); + if (p->W() != 1.0 || p->Z() != 0.0) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + points[i] = CSSPoint(p->X(), p->Y()); + } + TransformPoints(aTo, aFrom, 4, points, aOptions, aRv); + if (aRv.Failed()) { + return nullptr; + } + nsRefPtr result = new DOMQuad(aTo->GetParentObject(), points); + return result.forget(); +} + +already_AddRefed +ConvertRectFromNode(nsINode* aTo, dom::DOMRectReadOnly& aRect, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + CSSPoint points[4]; + double x = aRect.X(), y = aRect.Y(), w = aRect.Width(), h = aRect.Height(); + points[0] = CSSPoint(x, y); + points[1] = CSSPoint(x + w, y); + points[2] = CSSPoint(x + w, y + h); + points[3] = CSSPoint(x, y + h); + TransformPoints(aTo, aFrom, 4, points, aOptions, aRv); + if (aRv.Failed()) { + return nullptr; + } + nsRefPtr result = new DOMQuad(aTo->GetParentObject(), points); + return result.forget(); +} + +already_AddRefed +ConvertPointFromNode(nsINode* aTo, const dom::DOMPointInit& aPoint, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + if (aPoint.mW != 1.0 || aPoint.mZ != 0.0) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + CSSPoint point(aPoint.mX, aPoint.mY); + TransformPoints(aTo, aFrom, 1, &point, aOptions, aRv); + if (aRv.Failed()) { + return nullptr; + } + nsRefPtr result = new DOMPoint(aTo->GetParentObject(), point.x, point.y); + return result.forget(); +} + } diff --git a/layout/base/GeometryUtils.h b/layout/base/GeometryUtils.h index 72592508fcbd..0f327c03c1aa 100644 --- a/layout/base/GeometryUtils.h +++ b/layout/base/GeometryUtils.h @@ -22,11 +22,18 @@ namespace mozilla { namespace dom { struct BoxQuadOptions; +struct ConvertCoordinateOptions; class DOMQuad; -class Element; -class Text; +class DOMRectReadOnly; +class DOMPoint; +class DOMPointInit; +class OwningTextOrElementOrDocument; +class TextOrElementOrDocument; } +typedef dom::TextOrElementOrDocument GeometryNode; +typedef dom::OwningTextOrElementOrDocument OwningGeometryNode; + /** * Computes quads for aNode using aOptions, according to GeometryUtils.getBoxQuads. * May set an error in aRv. @@ -36,6 +43,24 @@ void GetBoxQuads(nsINode* aNode, nsTArray >& aResult, ErrorResult& aRv); +already_AddRefed +ConvertQuadFromNode(nsINode* aTo, dom::DOMQuad& aQuad, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + +already_AddRefed +ConvertRectFromNode(nsINode* aTo, dom::DOMRectReadOnly& aRect, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + +already_AddRefed +ConvertPointFromNode(nsINode* aTo, const dom::DOMPointInit& aPoint, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + } #endif /* MOZILLA_GEOMETRYUTILS_H_ */ From a619f60776a85ee301694d3a00e114ca7b537c09 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:39 +0800 Subject: [PATCH 011/101] Bug 918189. Part 1.5: Implement GeometryUtils.convertPointFromNode, convertRectFromNode, and convertQuadFromNode. r=jst --- content/base/public/nsINode.h | 25 ++++++++++++++++- content/base/src/nsINode.cpp | 27 +++++++++++++++++++ dom/webidl/GeometryUtils.webidl | 9 ++++--- editor/libeditor/html/nsHTMLEditRules.cpp | 4 +-- ...test_getBoxQuads_convertPointRectQuad.html | 3 ++- modules/libpref/src/init/all.js | 7 +++++ 6 files changed, 68 insertions(+), 7 deletions(-) diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 3fe973fd99b5..3ff35c84638f 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -65,12 +65,17 @@ inline bool IsSpaceCharacter(char aChar) { return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' || aChar == '\f'; } -class Element; struct BoxQuadOptions; +struct ConvertCoordinateOptions; +class DOMPoint; class DOMQuad; +class DOMRectReadOnly; +class Element; class EventHandlerNonNull; class OnErrorEventHandlerNonNull; template class Optional; +class TextOrElementOrDocument; +struct DOMPointInit; } // namespace dom } // namespace mozilla @@ -282,7 +287,12 @@ class nsINode : public mozilla::dom::EventTarget { public: typedef mozilla::dom::BoxQuadOptions BoxQuadOptions; + typedef mozilla::dom::ConvertCoordinateOptions ConvertCoordinateOptions; + typedef mozilla::dom::DOMPoint DOMPoint; + typedef mozilla::dom::DOMPointInit DOMPointInit; typedef mozilla::dom::DOMQuad DOMQuad; + typedef mozilla::dom::DOMRectReadOnly DOMRectReadOnly; + typedef mozilla::dom::TextOrElementOrDocument TextOrElementOrDocument; typedef mozilla::ErrorResult ErrorResult; NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID) @@ -1620,6 +1630,19 @@ public: nsTArray >& aResult, mozilla::ErrorResult& aRv); + already_AddRefed ConvertQuadFromNode(DOMQuad& aQuad, + const TextOrElementOrDocument& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + already_AddRefed ConvertRectFromNode(DOMRectReadOnly& aRect, + const TextOrElementOrDocument& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + already_AddRefed ConvertPointFromNode(const DOMPointInit& aPoint, + const TextOrElementOrDocument& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + protected: // Override this function to create a custom slots class. diff --git a/content/base/src/nsINode.cpp b/content/base/src/nsINode.cpp index 953912d33043..0a7558328119 100644 --- a/content/base/src/nsINode.cpp +++ b/content/base/src/nsINode.cpp @@ -1149,6 +1149,33 @@ nsINode::GetBoxQuads(const BoxQuadOptions& aOptions, mozilla::GetBoxQuads(this, aOptions, aResult, aRv); } +already_AddRefed +nsINode::ConvertQuadFromNode(DOMQuad& aQuad, + const GeometryNode& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + return mozilla::ConvertQuadFromNode(this, aQuad, aFrom, aOptions, aRv); +} + +already_AddRefed +nsINode::ConvertRectFromNode(DOMRectReadOnly& aRect, + const GeometryNode& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + return mozilla::ConvertRectFromNode(this, aRect, aFrom, aOptions, aRv); +} + +already_AddRefed +nsINode::ConvertPointFromNode(const DOMPointInit& aPoint, + const GeometryNode& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + return mozilla::ConvertPointFromNode(this, aPoint, aFrom, aOptions, aRv); +} + nsresult nsINode::DispatchEvent(nsIDOMEvent *aEvent, bool* aRetVal) { diff --git a/dom/webidl/GeometryUtils.webidl b/dom/webidl/GeometryUtils.webidl index d34a614af224..08023d4dfe2f 100644 --- a/dom/webidl/GeometryUtils.webidl +++ b/dom/webidl/GeometryUtils.webidl @@ -25,9 +25,12 @@ dictionary ConvertCoordinateOptions { interface GeometryUtils { [Throws, Pref="layout.css.getBoxQuads.enabled"] sequence getBoxQuads(optional BoxQuadOptions options); -// DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional ConvertCoordinateOptions options); -// DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options); -// DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options); + [Throws, Pref="layout.css.convertFromNode.enabled"] + DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional ConvertCoordinateOptions options); + [Throws, Pref="layout.css.convertFromNode.enabled"] + DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options); + [Throws, Pref="layout.css.convertFromNode.enabled"] + DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options); }; Text implements GeometryUtils; diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp index 2013780f5dd9..58e86f9b1b0a 100644 --- a/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/editor/libeditor/html/nsHTMLEditRules.cpp @@ -2932,7 +2932,7 @@ nsHTMLEditRules::MoveBlock(nsIDOMNode *aLeftBlock, nsIDOMNode *aRightBlock, int3 nsCOMArray arrayOfNodes; nsCOMPtr isupports; // GetNodesFromPoint is the workhorse that figures out what we wnat to move. - nsresult res = GetNodesFromPoint(DOMPoint(aRightBlock,aRightOffset), + nsresult res = GetNodesFromPoint(::DOMPoint(aRightBlock,aRightOffset), EditAction::makeList, arrayOfNodes, true); NS_ENSURE_SUCCESS(res, res); int32_t listCount = arrayOfNodes.Count(); @@ -6459,7 +6459,7 @@ nsHTMLEditRules::GetHighestInlineParent(nsIDOMNode* aNode) // of nodes from a point that will be operated on. // nsresult -nsHTMLEditRules::GetNodesFromPoint(DOMPoint point, +nsHTMLEditRules::GetNodesFromPoint(::DOMPoint point, EditAction operation, nsCOMArray &arrayOfNodes, bool dontTouchContent) diff --git a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html index 5c41d6a588a6..f35c8a46a5d7 100644 --- a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html +++ b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html @@ -216,7 +216,8 @@ window.scrollTo(0,0); function startTest() { SpecialPowers.pushPrefEnv({"set": [["layout.css.DOMPoint.enabled", true], ["layout.css.DOMQuad.enabled", true], - ["layout.css.getBoxQuads.enabled", true]]}, runTest); + ["layout.css.getBoxQuads.enabled", true], + ["layout.css.convertFromNode.enabled", true]]}, runTest); } function runTest() { diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index b07b9f2e2b60..fa46052e590a 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1823,6 +1823,13 @@ pref("layout.css.getBoxQuads.enabled", false); pref("layout.css.getBoxQuads.enabled", true); #endif +// Is support for GeometryUtils.getBoxQuads enabled? +#ifdef RELEASE_BUILD +pref("layout.css.convertFromNode.enabled", false); +#else +pref("layout.css.convertFromNode.enabled", true); +#endif + // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From 1d985c4849ef6f261095329a219d95f6f2b4da81 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:22:11 +1200 Subject: [PATCH 012/101] Bug 918189. Part 2: Add tests for convertPoint/Rect/QuadFromNode. r=mats --- layout/base/tests/mochitest.ini | 1 + ...test_getBoxQuads_convertPointRectQuad.html | 240 ++++++++++++++---- 2 files changed, 194 insertions(+), 47 deletions(-) diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index f8e9af0ad75e..69caff9de6fd 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -459,6 +459,7 @@ skip-if = toolkit == "win" [test_flush_on_paint.html] skip-if = true || (toolkit == 'android') || (toolkit == "cocoa") # Bug 688128, bug 539356 [test_getBoxQuads_convertPointRectQuad.html] +skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 948948 [test_bug687297.html] skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 948948 support-files = diff --git a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html index f35c8a46a5d7..0d7e104652d3 100644 --- a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html +++ b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html @@ -12,6 +12,13 @@ var f1d; var text; var suppressedText; +var suppressedText2; +var comment; +var fragment; +var openedWindow; +var zeroPoint = new DOMPoint(0,0); +var zeroRect = new DOMRect(0,0,0,0); +var zeroQuad = new DOMQuad(zeroRect); var notInDocument = document.createElement('div'); function isEval(expr, b) { @@ -38,6 +45,105 @@ function makeQuadsExpr(fromStr, options) { return fromStr + ".getBoxQuads({" + getBoxQuadsOptionParts.join(',') + "})"; } +function makePointExpr(fromStr, options, x, y) { + var convertPointOptionParts = []; + if ('box' in options) { + convertPointOptionParts.push("fromBox:'" + options.box + "'"); + } + if ('toBox' in options) { + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); + } + return ('toStr' in options ? options.toStr : "document") + + ".convertPointFromNode(new DOMPoint(" + x + "," + y + ")," + fromStr + ",{" + + convertPointOptionParts.join(",") + "})"; +} + +function checkConvertPoints(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { + var selfQuads = eval(fromStr).getBoxQuads( + {box:options.box == "" ? "border" : options.box, + relativeTo:eval(fromStr)}); + var boxWidth = selfQuads[0].bounds.width; + var boxHeight = selfQuads[0].bounds.height; + + var convertTopLeftPointExpr = makePointExpr(fromStr, options, 0, 0); + var topLeft = eval(convertTopLeftPointExpr); + isApprox(topLeft.x, x1, convertTopLeftPointExpr + ".x", options); + isApprox(topLeft.y, y1, convertTopLeftPointExpr + ".y", options); + + var convertTopRightPointExpr = makePointExpr(fromStr, options, boxWidth, 0); + var topRight = eval(convertTopRightPointExpr); + isApprox(topRight.x, x2, convertTopRightPointExpr + ".x", options); + isApprox(topRight.y, y2, convertTopRightPointExpr + ".y", options); + + var convertBottomRightPointExpr = makePointExpr(fromStr, options, boxWidth, boxHeight); + var bottomRight = eval(convertBottomRightPointExpr); + isApprox(bottomRight.x, x3, convertBottomRightPointExpr + ".x", options); + isApprox(bottomRight.y, y3, convertBottomRightPointExpr + ".y", options); + + var convertBottomLeftPointExpr = makePointExpr(fromStr, options, 0, boxHeight); + var bottomLeft = eval(convertBottomLeftPointExpr); + isApprox(bottomLeft.x, x4, convertBottomLeftPointExpr + ".x", options); + isApprox(bottomLeft.y, y4, convertBottomLeftPointExpr + ".y", options); +} + +function checkConvertRect(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { + var selfQuads = eval(fromStr).getBoxQuads( + {box:options.box == "" ? "border" : options.box, + relativeTo:eval(fromStr)}); + var boxWidth = selfQuads[0].bounds.width; + var boxHeight = selfQuads[0].bounds.height; + + var convertPointOptionParts = []; + if ('box' in options) { + convertPointOptionParts.push("fromBox:'" + options.box + "'"); + } + if ('toBox' in options) { + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); + } + + var convertRectExpr = ('toStr' in options ? options.toStr : "document") + + ".convertRectFromNode(new DOMRect(0,0," + boxWidth + "," + boxHeight + ")," + + fromStr + ",{" + convertPointOptionParts.join(",") + "})"; + var quad = eval(convertRectExpr); + isApprox(quad.p1.x, x1, convertRectExpr + ".p1.x", options); + isApprox(quad.p1.y, y1, convertRectExpr + ".p1.y", options); + isApprox(quad.p2.x, x2, convertRectExpr + ".p2.x", options); + isApprox(quad.p2.y, y2, convertRectExpr + ".p2.y", options); + isApprox(quad.p3.x, x3, convertRectExpr + ".p3.x", options); + isApprox(quad.p3.y, y3, convertRectExpr + ".p3.y", options); + isApprox(quad.p4.x, x4, convertRectExpr + ".p4.x", options); + isApprox(quad.p4.y, y4, convertRectExpr + ".p4.y", options); +} + +function checkConvertQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { + var selfQuads = eval(fromStr).getBoxQuads( + {box:options.box == "" ? "border" : options.box, + relativeTo:eval(fromStr)}); + var boxWidth = selfQuads[0].bounds.width; + var boxHeight = selfQuads[0].bounds.height; + + var convertPointOptionParts = []; + if ('box' in options) { + convertPointOptionParts.push("fromBox:'" + options.box + "'"); + } + if ('toBox' in options) { + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); + } + + var convertQuadExpr = ('toStr' in options ? options.toStr : "document") + + ".convertQuadFromNode(new DOMQuad(new DOMRect(0,0," + boxWidth + "," + boxHeight + "))," + + fromStr + ",{" + convertPointOptionParts.join(",") + "})"; + var quad = eval(convertQuadExpr); + isApprox(quad.p1.x, x1, convertQuadExpr + ".p1.x", options); + isApprox(quad.p1.y, y1, convertQuadExpr + ".p1.y", options); + isApprox(quad.p2.x, x2, convertQuadExpr + ".p2.x", options); + isApprox(quad.p2.y, y2, convertQuadExpr + ".p2.y", options); + isApprox(quad.p3.x, x3, convertQuadExpr + ".p3.x", options); + isApprox(quad.p3.y, y3, convertQuadExpr + ".p3.y", options); + isApprox(quad.p4.x, x4, convertQuadExpr + ".p4.x", options); + isApprox(quad.p4.y, y4, convertQuadExpr + ".p4.y", options); +} + function checkQuadIsRect(fromStr, options, x, y, w, h) { var quadsExpr = makeQuadsExpr(fromStr, options); var quads = eval(quadsExpr); @@ -56,6 +162,10 @@ function checkQuadIsRect(fromStr, options, x, y, w, h) { isApprox(q.bounds.top, y, quadsExpr + " checking quad.bounds.top", options); isApprox(q.bounds.width, w, quadsExpr + " checking quad.bounds.width", options); isApprox(q.bounds.height, h, quadsExpr + " checking quad.bounds.height", options); + + checkConvertPoints(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); + checkConvertRect(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); + checkConvertQuad(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); } function checkQuadIsQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { @@ -76,6 +186,33 @@ function checkQuadIsQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { isApprox(q.bounds.top, Math.min(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.top", options); isApprox(q.bounds.right, Math.max(x1,x2,x3,x4), quadsExpr + " checking quad.bounds.right", options); isApprox(q.bounds.bottom, Math.max(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.bottom", options); + + checkConvertPoints(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); + checkConvertRect(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); + checkConvertQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); +} + +function checkException(expr, name) { + try { + eval(expr); + ok(false, "Exception should have been thrown for " + expr); + } catch (ex) { + is(ex.name, name, "Checking exception type for " + expr); + } +} + +function checkNotFound(fromStr, toStr, x1, y1, x2, y2) { + var convertPointExpr = toStr + ".convertPointFromNode(new DOMPoint(" + x1 + + "," + y1 + ")," + fromStr + ")"; + checkException(convertPointExpr, "NotFoundError"); + + var convertRectExpr = toStr + ".convertRectFromNode(new DOMRect(" + x1 + + "," + y1 + "," + x2 + "," + y2 + ")," + fromStr + ")"; + checkException(convertRectExpr, "NotFoundError"); + + var convertQuadExpr = toStr + ".convertQuadFromNode(new DOMQuad(new DOMRect(" + x1 + + "," + y1 + "," + x2 + "," + y2 + "))," + fromStr + ")"; + checkException(convertQuadExpr, "NotFoundError"); } -
-
-
-
- -
- - - -
- - - - - - - - -
Cell
Caption
- -
-
-
-
- -
- -
T -TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText
- -
- -
- - - -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
-
- -
-
-
-
-
- -
-
-
-
-
- -
- - - - -
-
-
-
-
- - - - diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index b07b9f2e2b60..f4178a06c40e 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1810,19 +1810,6 @@ pref("layout.css.sticky.enabled", true); // Is support for CSS "will-change" enabled? pref("layout.css.will-change.enabled", false); -// Is support for DOMPoint enabled? -pref("layout.css.DOMPoint.enabled", true); - -// Is support for DOMQuad enabled? -pref("layout.css.DOMQuad.enabled", true); - -// Is support for GeometryUtils.getBoxQuads enabled? -#ifdef RELEASE_BUILD -pref("layout.css.getBoxQuads.enabled", false); -#else -pref("layout.css.getBoxQuads.enabled", true); -#endif - // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From 3c5f3ef4aae7de569115a7fb50865e2d37501a4b Mon Sep 17 00:00:00 2001 From: George Wright Date: Mon, 17 Mar 2014 07:34:32 -0400 Subject: [PATCH 016/101] [PATCH 1/6] Bug 985217 - Update Skia to r13827 r=upstream --- gfx/skia/README_MOZILLA | 2 +- gfx/skia/generate_mozbuild.py | 2 +- gfx/skia/moz.build | 15 +- gfx/skia/trunk/include/core/Sk64.h | 230 ----- gfx/skia/trunk/include/core/SkAnnotation.h | 13 +- gfx/skia/trunk/include/core/SkBitmap.h | 65 +- gfx/skia/trunk/include/core/SkBitmapDevice.h | 39 +- gfx/skia/trunk/include/core/SkCanvas.h | 422 ++++++-- gfx/skia/trunk/include/core/SkClipStack.h | 100 +- gfx/skia/trunk/include/core/SkColorFilter.h | 2 +- gfx/skia/trunk/include/core/SkColorShader.h | 2 +- gfx/skia/trunk/include/core/SkComposeShader.h | 2 +- gfx/skia/trunk/include/core/SkDevice.h | 117 ++- gfx/skia/trunk/include/core/SkDrawLooper.h | 59 +- gfx/skia/trunk/include/core/SkEmptyShader.h | 2 +- gfx/skia/trunk/include/core/SkGeometry.h | 9 + gfx/skia/trunk/include/core/SkImageFilter.h | 60 +- .../trunk/include/core/SkImageFilterUtils.h | 38 - gfx/skia/trunk/include/core/SkImageInfo.h | 7 + gfx/skia/trunk/include/core/SkMaskFilter.h | 13 +- gfx/skia/trunk/include/core/SkMatrix.h | 2 +- gfx/skia/trunk/include/core/SkPaint.h | 100 +- gfx/skia/trunk/include/core/SkPathEffect.h | 27 +- gfx/skia/trunk/include/core/SkPicture.h | 88 +- gfx/skia/trunk/include/core/SkPreConfig.h | 32 +- gfx/skia/trunk/include/core/SkRRect.h | 31 +- gfx/skia/trunk/include/core/SkRasterizer.h | 3 +- gfx/skia/trunk/include/core/SkReadBuffer.h | 4 +- gfx/skia/trunk/include/core/SkScalarCompare.h | 38 - gfx/skia/trunk/include/core/SkShader.h | 7 +- gfx/skia/trunk/include/core/SkStream.h | 18 +- gfx/skia/trunk/include/core/SkSurface.h | 17 +- gfx/skia/trunk/include/core/SkTDArray.h | 40 +- gfx/skia/trunk/include/core/SkTLazy.h | 10 + gfx/skia/trunk/include/core/SkTemplates.h | 11 + .../trunk/include/core/SkThread_platform.h | 194 ---- gfx/skia/trunk/include/core/SkTypes.h | 29 +- gfx/skia/trunk/include/core/SkWriter32.h | 39 +- gfx/skia/trunk/include/core/SkXfermode.h | 20 +- .../trunk/include/device/xps/SkXPSDevice.h | 8 +- .../trunk/include/effects/Sk1DPathEffect.h | 10 +- .../trunk/include/effects/Sk2DPathEffect.h | 29 +- .../trunk/include/effects/SkAvoidXfermode.h | 11 +- .../include/effects/SkBicubicImageFilter.h | 18 +- .../effects/SkBitmapAlphaThresholdShader.h | 24 - .../trunk/include/effects/SkBitmapSource.h | 17 +- .../trunk/include/effects/SkBlurDrawLooper.h | 20 +- .../trunk/include/effects/SkBlurImageFilter.h | 23 +- .../effects/SkColorFilterImageFilter.h | 2 +- .../include/effects/SkColorMatrixFilter.h | 16 +- .../include/effects/SkComposeImageFilter.h | 12 +- .../include/effects/SkCornerPathEffect.h | 9 +- .../trunk/include/effects/SkDashPathEffect.h | 12 +- .../include/effects/SkDiscretePathEffect.h | 9 +- .../include/effects/SkDisplacementMapEffect.h | 31 +- .../include/effects/SkDropShadowImageFilter.h | 23 +- .../include/effects/SkEmbossMaskFilter.h | 14 +- .../include/effects/SkKernel33MaskFilter.h | 25 +- .../trunk/include/effects/SkLayerDrawLooper.h | 79 +- .../trunk/include/effects/SkLayerRasterizer.h | 44 +- .../trunk/include/effects/SkLerpXfermode.h | 2 +- .../trunk/include/effects/SkLumaColorFilter.h | 2 +- .../include/effects/SkMagnifierImageFilter.h | 11 +- .../effects/SkMatrixConvolutionImageFilter.h | 85 +- .../include/effects/SkMergeImageFilter.h | 29 +- .../include/effects/SkMorphologyImageFilter.h | 49 +- .../include/effects/SkOffsetImageFilter.h | 14 +- .../include/effects/SkPerlinNoiseShader.h | 32 +- .../include/effects/SkPictureImageFilter.h | 20 +- .../include/effects/SkPixelXorXfermode.h | 11 +- .../include/effects/SkRectShaderImageFilter.h | 2 +- .../include/effects/SkResizeImageFilter.h | 20 +- .../include/effects/SkStippleMaskFilter.h | 11 +- .../trunk/include/effects/SkTableMaskFilter.h | 14 +- .../include/effects/SkTestImageFilters.h | 7 +- .../trunk/include/effects/SkTileImageFilter.h | 16 +- .../include/effects/SkTransparentShader.h | 2 +- .../include/effects/SkXfermodeImageFilter.h | 19 +- .../trunk/include/gpu/GrBitmapTextContext.h | 46 - gfx/skia/trunk/include/gpu/GrContext.h | 13 + .../include/gpu/GrDistanceFieldTextContext.h | 46 - .../include/gpu/GrTBackendEffectFactory.h | 2 +- gfx/skia/trunk/include/gpu/GrTextContext.h | 40 - gfx/skia/trunk/include/gpu/GrTypesPriv.h | 51 + gfx/skia/trunk/include/gpu/SkGpuDevice.h | 40 +- gfx/skia/trunk/include/gpu/SkGr.h | 1 + .../trunk/include/gpu/gl/GrGLExtensions.h | 7 +- gfx/skia/trunk/include/gpu/gl/GrGLFunctions.h | 12 +- gfx/skia/trunk/include/gpu/gl/GrGLInterface.h | 218 +---- gfx/skia/trunk/include/pdf/SkPDFDevice.h | 7 +- .../trunk/include/utils/SkDeferredCanvas.h | 44 +- gfx/skia/trunk/include/utils/SkDumpCanvas.h | 46 +- gfx/skia/trunk/include/utils/SkLua.h | 6 + gfx/skia/trunk/include/utils/SkLuaCanvas.h | 37 +- gfx/skia/trunk/include/utils/SkNWayCanvas.h | 33 +- .../trunk/include/utils/SkNoSaveLayerCanvas.h | 47 + gfx/skia/trunk/include/utils/SkProxyCanvas.h | 37 +- gfx/skia/trunk/include/utils/SkRunnable.h | 14 +- gfx/skia/trunk/include/utils/SkThreadPool.h | 161 +++- gfx/skia/trunk/include/views/SkWindow.h | 6 +- gfx/skia/trunk/src/animator/SkDisplayType.cpp | 2 +- gfx/skia/trunk/src/animator/SkDrawDash.cpp | 2 +- .../trunk/src/animator/SkDrawDiscrete.cpp | 2 +- .../src/animator/SkDrawExtraPathEffect.cpp | 4 +- gfx/skia/trunk/src/core/Sk64.cpp | 345 ------- gfx/skia/trunk/src/core/SkAnnotation.cpp | 2 +- .../trunk/src/core/SkBBoxHierarchyRecord.cpp | 82 +- .../trunk/src/core/SkBBoxHierarchyRecord.h | 44 +- gfx/skia/trunk/src/core/SkBBoxRecord.cpp | 7 + gfx/skia/trunk/src/core/SkBBoxRecord.h | 6 +- gfx/skia/trunk/src/core/SkBitmap.cpp | 100 +- gfx/skia/trunk/src/core/SkBitmapDevice.cpp | 219 ++++- gfx/skia/trunk/src/core/SkBitmapFilter.cpp | 4 +- gfx/skia/trunk/src/core/SkBitmapHeap.cpp | 2 +- gfx/skia/trunk/src/core/SkBitmapHeap.h | 2 +- .../trunk/src/core/SkBitmapProcShader.cpp | 61 +- gfx/skia/trunk/src/core/SkBitmapProcShader.h | 13 +- gfx/skia/trunk/src/core/SkBitmapScaler.cpp | 23 +- gfx/skia/trunk/src/core/SkBitmap_scroll.cpp | 22 +- gfx/skia/trunk/src/core/SkBlitter.cpp | 126 +-- gfx/skia/trunk/src/core/SkBlitter.h | 15 +- gfx/skia/trunk/src/core/SkBlitter_RGB16.cpp | 25 +- gfx/skia/trunk/src/core/SkBlitter_Sprite.cpp | 23 +- gfx/skia/trunk/src/core/SkCanvas.cpp | 668 +++++++++---- gfx/skia/trunk/src/core/SkClipStack.cpp | 292 ++++-- gfx/skia/trunk/src/core/SkComposeShader.cpp | 2 +- gfx/skia/trunk/src/core/SkConfig8888.h | 5 +- gfx/skia/trunk/src/core/SkCordic.cpp | 289 ------ gfx/skia/trunk/src/core/SkCordic.h | 28 - gfx/skia/trunk/src/core/SkCoreBlitters.h | 8 +- gfx/skia/trunk/src/core/SkDebug.cpp | 5 + gfx/skia/trunk/src/core/SkDevice.cpp | 123 ++- .../trunk/src/core/SkDeviceImageFilterProxy.h | 7 +- .../trunk/src/core/SkDistanceFieldGen.cpp | 451 +++++++++ gfx/skia/trunk/src/core/SkDistanceFieldGen.h | 25 + gfx/skia/trunk/src/core/SkDraw.cpp | 99 +- gfx/skia/trunk/src/core/SkDrawLooper.cpp | 17 +- gfx/skia/trunk/src/core/SkFP.h | 79 -- gfx/skia/trunk/src/core/SkFilterShader.cpp | 2 +- gfx/skia/trunk/src/core/SkFilterShader.h | 2 +- .../trunk/src/core/SkFlattenableBuffers.cpp | 116 --- gfx/skia/trunk/src/core/SkGeometry.cpp | 454 ++++----- gfx/skia/trunk/src/core/SkImageFilter.cpp | 123 ++- .../trunk/src/core/SkImageFilterUtils.cpp | 55 -- gfx/skia/trunk/src/core/SkMaskFilter.cpp | 7 + gfx/skia/trunk/src/core/SkMatrix.cpp | 2 + .../trunk/src/core/SkMatrixClipStateMgr.cpp | 258 +++-- .../trunk/src/core/SkMatrixClipStateMgr.h | 89 +- gfx/skia/trunk/src/core/SkOffsetTable.h | 115 +++ .../trunk/src/core/SkOrderedReadBuffer.cpp | 317 ------ .../trunk/src/core/SkOrderedWriteBuffer.cpp | 319 ------ .../trunk/src/core/SkOrderedWriteBuffer.h | 117 --- gfx/skia/trunk/src/core/SkPaint.cpp | 206 +++- gfx/skia/trunk/src/core/SkPathHeap.cpp | 33 + gfx/skia/trunk/src/core/SkPathHeap.h | 26 + gfx/skia/trunk/src/core/SkPicture.cpp | 131 +-- gfx/skia/trunk/src/core/SkPictureFlat.h | 27 +- gfx/skia/trunk/src/core/SkPicturePlayback.cpp | 345 ++++--- gfx/skia/trunk/src/core/SkPicturePlayback.h | 20 + gfx/skia/trunk/src/core/SkPictureRecord.cpp | 240 +++-- gfx/skia/trunk/src/core/SkPictureRecord.h | 58 +- gfx/skia/trunk/src/core/SkQuadTree.cpp | 366 ++++--- gfx/skia/trunk/src/core/SkQuadTree.h | 51 +- gfx/skia/trunk/src/core/SkQuadTreePicture.cpp | 2 +- gfx/skia/trunk/src/core/SkRRect.cpp | 7 + .../trunk/src/core/SkScaledImageCache.cpp | 8 +- gfx/skia/trunk/src/core/SkScalerContext.cpp | 6 +- gfx/skia/trunk/src/core/SkShader.cpp | 16 +- gfx/skia/trunk/src/core/SkSmallAllocator.h | 149 +++ gfx/skia/trunk/src/core/SkSpriteBlitter.h | 9 +- .../trunk/src/core/SkSpriteBlitter_ARGB32.cpp | 30 +- .../trunk/src/core/SkSpriteBlitter_RGB16.cpp | 46 +- gfx/skia/trunk/src/core/SkStream.cpp | 29 +- gfx/skia/trunk/src/core/SkTDynamicHash.h | 27 + gfx/skia/trunk/src/core/SkTInternalSList.h | 132 +++ gfx/skia/trunk/src/core/SkTLList.h | 4 +- gfx/skia/trunk/src/core/SkTObjectPool.h | 104 ++ gfx/skia/trunk/src/core/SkTRefArray.h | 0 gfx/skia/trunk/src/core/SkTemplatesPriv.h | 76 -- .../trunk/src/core/SkValidatingReadBuffer.cpp | 4 +- .../trunk/src/core/SkValidatingReadBuffer.h | 1 - gfx/skia/trunk/src/core/SkWriteBuffer.cpp | 11 +- gfx/skia/trunk/src/core/SkWriter32.cpp | 40 +- gfx/skia/trunk/src/core/SkXfermode.cpp | 50 +- .../trunk/src/core/SkXfermode_proccoeff.h | 18 +- gfx/skia/trunk/src/device/xps/SkXPSDevice.cpp | 13 +- .../src/effects/SkAlphaThresholdFilter.cpp | 10 +- .../trunk/src/effects/SkArithmeticMode.cpp | 21 +- .../trunk/src/effects/SkAvoidXfermode.cpp | 2 +- .../src/effects/SkBicubicImageFilter.cpp | 16 +- .../effects/SkBitmapAlphaThresholdShader.cpp | 277 ------ gfx/skia/trunk/src/effects/SkBitmapSource.cpp | 6 +- .../trunk/src/effects/SkBlurDrawLooper.cpp | 28 +- .../trunk/src/effects/SkBlurImageFilter.cpp | 44 +- gfx/skia/trunk/src/effects/SkBlurMask.cpp | 27 +- gfx/skia/trunk/src/effects/SkBlurMask.h | 23 +- .../trunk/src/effects/SkBlurMaskFilter.cpp | 83 +- .../src/effects/SkColorFilterImageFilter.cpp | 10 +- gfx/skia/trunk/src/effects/SkColorFilters.cpp | 4 +- gfx/skia/trunk/src/effects/SkColorMatrix.cpp | 3 - .../trunk/src/effects/SkColorMatrixFilter.cpp | 3 +- .../src/effects/SkComposeImageFilter.cpp | 8 +- .../trunk/src/effects/SkDashPathEffect.cpp | 4 +- .../src/effects/SkDisplacementMapEffect.cpp | 101 +- .../src/effects/SkDropShadowImageFilter.cpp | 17 +- .../trunk/src/effects/SkEmbossMaskFilter.cpp | 11 +- .../src/effects/SkKernel33MaskFilter.cpp | 4 +- .../trunk/src/effects/SkLayerDrawLooper.cpp | 154 +-- .../trunk/src/effects/SkLayerRasterizer.cpp | 65 +- gfx/skia/trunk/src/effects/SkLerpXfermode.cpp | 2 +- .../src/effects/SkLightingImageFilter.cpp | 65 +- .../trunk/src/effects/SkLumaColorFilter.cpp | 2 +- .../src/effects/SkMagnifierImageFilter.cpp | 8 +- .../SkMatrixConvolutionImageFilter.cpp | 72 +- .../trunk/src/effects/SkMergeImageFilter.cpp | 7 +- .../src/effects/SkMorphologyImageFilter.cpp | 44 +- .../trunk/src/effects/SkOffsetImageFilter.cpp | 24 +- .../trunk/src/effects/SkPerlinNoiseShader.cpp | 134 +-- .../src/effects/SkPictureImageFilter.cpp | 20 +- .../trunk/src/effects/SkPixelXorXfermode.cpp | 2 +- .../src/effects/SkRectShaderImageFilter.cpp | 9 +- .../trunk/src/effects/SkResizeImageFilter.cpp | 45 +- .../trunk/src/effects/SkStippleMaskFilter.cpp | 2 +- .../trunk/src/effects/SkTableColorFilter.cpp | 4 +- .../trunk/src/effects/SkTableMaskFilter.cpp | 2 +- .../trunk/src/effects/SkTestImageFilters.cpp | 2 +- .../trunk/src/effects/SkTileImageFilter.cpp | 8 +- .../trunk/src/effects/SkTransparentShader.cpp | 24 +- .../src/effects/SkXfermodeImageFilter.cpp | 35 +- .../effects/gradients/SkGradientShader.cpp | 8 +- .../effects/gradients/SkGradientShaderPriv.h | 2 +- .../effects/gradients/SkLinearGradient.cpp | 2 +- .../src/effects/gradients/SkLinearGradient.h | 2 +- .../effects/gradients/SkRadialGradient.cpp | 2 +- .../src/effects/gradients/SkRadialGradient.h | 2 +- .../src/effects/gradients/SkSweepGradient.cpp | 14 +- .../src/effects/gradients/SkSweepGradient.h | 2 +- .../gradients/SkTwoPointConicalGradient.cpp | 2 +- .../gradients/SkTwoPointConicalGradient.h | 2 +- .../gradients/SkTwoPointRadialGradient.cpp | 2 +- .../gradients/SkTwoPointRadialGradient.h | 2 +- .../src/gpu/GrAAHairLinePathRenderer.cpp | 4 +- gfx/skia/trunk/src/gpu/GrAllocator.h | 0 gfx/skia/trunk/src/gpu/GrAtlas.cpp | 184 ++-- gfx/skia/trunk/src/gpu/GrAtlas.h | 37 +- .../trunk/src/gpu/GrBitmapTextContext.cpp | 19 +- gfx/skia/trunk/src/gpu/GrClipMaskManager.cpp | 283 +++--- gfx/skia/trunk/src/gpu/GrClipMaskManager.h | 7 + gfx/skia/trunk/src/gpu/GrContext.cpp | 17 + .../src/gpu/GrDistanceFieldTextContext.cpp | 34 +- gfx/skia/trunk/src/gpu/GrDrawTarget.cpp | 28 +- gfx/skia/trunk/src/gpu/GrDrawTarget.h | 20 + gfx/skia/trunk/src/gpu/GrDrawTargetCaps.h | 2 + .../trunk/src/gpu/GrInOrderDrawBuffer.cpp | 12 + gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.h | 5 + gfx/skia/trunk/src/gpu/GrOrderedSet.h | 154 +++ gfx/skia/trunk/src/gpu/GrRedBlackTree.h | 5 + gfx/skia/trunk/src/gpu/GrReducedClip.cpp | 18 +- gfx/skia/trunk/src/gpu/GrReducedClip.h | 15 +- gfx/skia/trunk/src/gpu/GrTextStrike.cpp | 186 ++-- gfx/skia/trunk/src/gpu/GrTextStrike.h | 22 +- gfx/skia/trunk/src/gpu/GrTextStrike_impl.h | 6 - gfx/skia/trunk/src/gpu/SkGpuDevice.cpp | 220 ++++- gfx/skia/trunk/src/gpu/SkGr.cpp | 25 +- .../trunk/src/gpu/effects/GrBezierEffect.cpp | 63 +- .../trunk/src/gpu/effects/GrBezierEffect.h | 162 ++-- .../src/gpu/effects/GrConvexPolyEffect.cpp | 112 ++- .../src/gpu/effects/GrConvexPolyEffect.h | 30 +- .../effects/GrDistanceFieldTextureEffect.cpp | 74 +- .../effects/GrDistanceFieldTextureEffect.h | 11 +- .../trunk/src/gpu/effects/GrRRectEffect.cpp | 721 ++++++++++++++ .../trunk/src/gpu/effects/GrRRectEffect.h | 25 + .../src/gpu/effects/GrTextureDomainEffect.cpp | 221 ----- .../src/gpu/effects/GrTextureDomainEffect.h | 89 -- gfx/skia/trunk/src/gpu/gl/GrGLCaps.cpp | 2 + .../src/gpu/gl/GrGLCreateNullInterface.cpp | 283 +++--- gfx/skia/trunk/src/gpu/gl/GrGLExtensions.cpp | 11 + gfx/skia/trunk/src/gpu/gl/GrGLInterface.cpp | 331 ++----- .../trunk/src/gpu/gl/GrGLNoOpInterface.cpp | 16 +- gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.h | 10 +- .../trunk/src/gpu/gl/GrGLShaderBuilder.cpp | 11 +- gfx/skia/trunk/src/gpu/gl/GrGLUtil.cpp | 2 +- gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.cpp | 63 +- gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.h | 25 +- gfx/skia/trunk/src/gpu/gl/GrGpuGL.cpp | 19 +- gfx/skia/trunk/src/gpu/gl/GrGpuGL.h | 6 + gfx/skia/trunk/src/gpu/gl/GrGpuGL_program.cpp | 38 +- .../GrGLCreateNativeInterface_android.cpp | 17 +- .../gpu/gl/angle/GrGLCreateANGLEInterface.cpp | 6 + .../gpu/gl/debug/GrGLCreateDebugInterface.cpp | 15 +- .../gl/iOS/GrGLCreateNativeInterface_iOS.cpp | 6 + .../gl/mac/GrGLCreateNativeInterface_mac.cpp | 11 +- .../gpu/gl/mesa/GrGLCreateMesaInterface.cpp | 11 +- .../unix/GrGLCreateNativeInterface_unix.cpp | 11 +- .../gl/win/GrGLCreateNativeInterface_win.cpp | 11 +- gfx/skia/trunk/src/image/SkDataPixelRef.cpp | 43 - gfx/skia/trunk/src/image/SkDataPixelRef.h | 36 - gfx/skia/trunk/src/image/SkImagePriv.h | 2 - gfx/skia/trunk/src/image/SkImage_Gpu.cpp | 2 +- gfx/skia/trunk/src/image/SkImage_Raster.cpp | 2 +- gfx/skia/trunk/src/image/SkSurface.cpp | 4 + gfx/skia/trunk/src/image/SkSurface_Gpu.cpp | 31 +- gfx/skia/trunk/src/image/SkSurface_Raster.cpp | 2 +- .../src/images/SkDecodingImageGenerator.cpp | 102 +- .../src/images/SkDecodingImageGenerator.h | 5 +- .../src/images/SkImageDecoder_libpng.cpp | 15 +- .../src/images/SkImageDecoder_libwebp.cpp | 95 +- gfx/skia/trunk/src/images/SkImageRef.cpp | 13 + .../trunk/src/lazy/SkDiscardablePixelRef.cpp | 2 +- .../SkBitmapProcState_matrix_clamp_neon.h | 911 ------------------ .../src/opts/SkBitmapProcState_matrix_neon.h | 105 +- .../SkBitmapProcState_matrix_repeat_neon.h | 542 ----------- .../src/opts/SkBitmapProcState_opts_SSSE3.cpp | 38 +- .../trunk/src/opts/SkBlitRow_opts_SSE2.cpp | 511 ++++++++++ gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.h | 13 + .../src/opts/SkBlitRow_opts_arm_neon.cpp | 515 +++++----- gfx/skia/trunk/src/opts/SkColor_opts_SSE2.h | 31 + .../src/opts/SkXfermode_opts_arm_neon.cpp | 2 +- .../trunk/src/opts/SkXfermode_opts_arm_neon.h | 2 +- gfx/skia/trunk/src/opts/opts_check_SSE2.cpp | 17 +- .../trunk/src/pathops/SkDCubicToQuads.cpp | 11 +- gfx/skia/trunk/src/pathops/main.cpp | 16 - gfx/skia/trunk/src/pdf/SkPDFDevice.cpp | 44 +- gfx/skia/trunk/src/pdf/SkPDFFontImpl.h | 0 gfx/skia/trunk/src/pdf/SkPDFImage.cpp | 2 +- gfx/skia/trunk/src/pipe/SkGPipePriv.h | 1 + gfx/skia/trunk/src/pipe/SkGPipeRead.cpp | 13 +- gfx/skia/trunk/src/pipe/SkGPipeWrite.cpp | 151 +-- .../trunk/src/ports/SkFontHost_FreeType.cpp | 27 + gfx/skia/trunk/src/ports/SkFontHost_linux.cpp | 14 +- gfx/skia/trunk/src/ports/SkFontHost_mac.cpp | 26 +- .../src/ports/SkFontHost_sandbox_none.cpp | 0 gfx/skia/trunk/src/ports/SkFontHost_win.cpp | 10 + .../trunk/src/ports/SkFontHost_win_dw.cpp | 10 + .../ports/SkGlobalInitialization_chromium.cpp | 2 + .../ports/SkGlobalInitialization_default.cpp | 2 + .../trunk/src/ports/SkImageDecoder_CG.cpp | 4 +- .../trunk/src/ports/SkImageDecoder_WIC.cpp | 6 +- gfx/skia/trunk/src/ports/SkThread_none.cpp | 43 - gfx/skia/trunk/src/ports/SkThread_pthread.cpp | 197 ---- gfx/skia/trunk/src/ports/SkThread_win.cpp | 65 -- gfx/skia/trunk/src/sfnt/SkOTTableTypes.h | 13 + gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V0.h | 22 +- gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V1.h | 224 ++--- gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V2.h | 252 ++--- gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V3.h | 268 +++--- gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V4.h | 346 +++---- gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_VA.h | 20 +- gfx/skia/trunk/src/utils/SkBitSet.h | 0 gfx/skia/trunk/src/utils/SkBitmapHasher.cpp | 2 +- gfx/skia/trunk/src/utils/SkCanvasStack.cpp | 23 +- gfx/skia/trunk/src/utils/SkCanvasStack.h | 13 +- .../trunk/src/utils/SkCanvasStateUtils.cpp | 34 +- gfx/skia/trunk/src/utils/SkDeferredCanvas.cpp | 278 +++--- gfx/skia/trunk/src/utils/SkDumpCanvas.cpp | 84 +- .../src/utils/SkGatherPixelRefsAndRects.h | 22 +- gfx/skia/trunk/src/utils/SkLua.cpp | 198 +++- gfx/skia/trunk/src/utils/SkLuaCanvas.cpp | 71 +- gfx/skia/trunk/src/utils/SkMD5.h | 4 +- gfx/skia/trunk/src/utils/SkNWayCanvas.cpp | 72 +- .../trunk/src/utils/SkNoSaveLayerCanvas.h | 60 -- gfx/skia/trunk/src/utils/SkPictureUtils.cpp | 15 +- gfx/skia/trunk/src/utils/SkProxyCanvas.cpp | 66 +- gfx/skia/trunk/src/utils/SkSHA1.h | 2 + gfx/skia/trunk/src/utils/SkThreadPool.cpp | 127 --- .../src/utils/debugger/SkDebugCanvas.cpp | 191 +++- .../trunk/src/utils/debugger/SkDebugCanvas.h | 90 +- .../src/utils/debugger/SkDrawCommand.cpp | 72 ++ .../trunk/src/utils/debugger/SkDrawCommand.h | 74 +- .../src/utils/debugger/SkObjectParser.cpp | 4 +- .../src/utils/mac/SkCreateCGImageRef.cpp | 23 +- gfx/skia/trunk/src/views/SkWidgets.cpp | 8 +- gfx/skia/trunk/src/views/SkWindow.cpp | 22 +- gfx/skia/trunk/src/views/mac/SkNSView.mm | 2 +- 374 files changed, 11743 insertions(+), 10929 deletions(-) delete mode 100644 gfx/skia/trunk/include/core/Sk64.h delete mode 100644 gfx/skia/trunk/include/core/SkImageFilterUtils.h delete mode 100644 gfx/skia/trunk/include/core/SkScalarCompare.h delete mode 100644 gfx/skia/trunk/include/core/SkThread_platform.h delete mode 100644 gfx/skia/trunk/include/effects/SkBitmapAlphaThresholdShader.h delete mode 100644 gfx/skia/trunk/include/gpu/GrBitmapTextContext.h delete mode 100644 gfx/skia/trunk/include/gpu/GrDistanceFieldTextContext.h delete mode 100644 gfx/skia/trunk/include/gpu/GrTextContext.h create mode 100644 gfx/skia/trunk/include/utils/SkNoSaveLayerCanvas.h delete mode 100644 gfx/skia/trunk/src/core/Sk64.cpp delete mode 100644 gfx/skia/trunk/src/core/SkCordic.cpp delete mode 100644 gfx/skia/trunk/src/core/SkCordic.h create mode 100755 gfx/skia/trunk/src/core/SkDistanceFieldGen.cpp create mode 100644 gfx/skia/trunk/src/core/SkDistanceFieldGen.h delete mode 100644 gfx/skia/trunk/src/core/SkFP.h delete mode 100644 gfx/skia/trunk/src/core/SkFlattenableBuffers.cpp delete mode 100644 gfx/skia/trunk/src/core/SkImageFilterUtils.cpp create mode 100644 gfx/skia/trunk/src/core/SkOffsetTable.h delete mode 100644 gfx/skia/trunk/src/core/SkOrderedReadBuffer.cpp delete mode 100644 gfx/skia/trunk/src/core/SkOrderedWriteBuffer.cpp delete mode 100644 gfx/skia/trunk/src/core/SkOrderedWriteBuffer.h create mode 100644 gfx/skia/trunk/src/core/SkSmallAllocator.h create mode 100644 gfx/skia/trunk/src/core/SkTInternalSList.h create mode 100644 gfx/skia/trunk/src/core/SkTObjectPool.h mode change 100755 => 100644 gfx/skia/trunk/src/core/SkTRefArray.h delete mode 100644 gfx/skia/trunk/src/core/SkTemplatesPriv.h delete mode 100644 gfx/skia/trunk/src/effects/SkBitmapAlphaThresholdShader.cpp mode change 100755 => 100644 gfx/skia/trunk/src/gpu/GrAllocator.h create mode 100644 gfx/skia/trunk/src/gpu/GrOrderedSet.h mode change 100755 => 100644 gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.h create mode 100644 gfx/skia/trunk/src/gpu/effects/GrRRectEffect.cpp create mode 100644 gfx/skia/trunk/src/gpu/effects/GrRRectEffect.h delete mode 100644 gfx/skia/trunk/src/gpu/effects/GrTextureDomainEffect.cpp delete mode 100644 gfx/skia/trunk/src/gpu/effects/GrTextureDomainEffect.h delete mode 100644 gfx/skia/trunk/src/image/SkDataPixelRef.cpp delete mode 100644 gfx/skia/trunk/src/image/SkDataPixelRef.h delete mode 100644 gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_clamp_neon.h delete mode 100644 gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_repeat_neon.h create mode 100644 gfx/skia/trunk/src/opts/SkColor_opts_SSE2.h delete mode 100644 gfx/skia/trunk/src/pathops/main.cpp mode change 100755 => 100644 gfx/skia/trunk/src/pdf/SkPDFFontImpl.h delete mode 100644 gfx/skia/trunk/src/ports/SkFontHost_sandbox_none.cpp delete mode 100644 gfx/skia/trunk/src/ports/SkThread_none.cpp delete mode 100644 gfx/skia/trunk/src/ports/SkThread_pthread.cpp delete mode 100644 gfx/skia/trunk/src/ports/SkThread_win.cpp mode change 100755 => 100644 gfx/skia/trunk/src/utils/SkBitSet.h delete mode 100644 gfx/skia/trunk/src/utils/SkNoSaveLayerCanvas.h delete mode 100644 gfx/skia/trunk/src/utils/SkThreadPool.cpp diff --git a/gfx/skia/README_MOZILLA b/gfx/skia/README_MOZILLA index ef95ac716e78..d353985f9fdb 100644 --- a/gfx/skia/README_MOZILLA +++ b/gfx/skia/README_MOZILLA @@ -2,7 +2,7 @@ The source from this directory was copied from the skia subversion trunk using the update.sh script. The changes made were those applied by update.sh, the addition/update of Makefile.in files for the Mozilla build system. -The subversion revision used was r13424. +The subversion revision used was r13827. To update to a new version of Skia: diff --git a/gfx/skia/generate_mozbuild.py b/gfx/skia/generate_mozbuild.py index 077017588f2a..91993abfeb85 100755 --- a/gfx/skia/generate_mozbuild.py +++ b/gfx/skia/generate_mozbuild.py @@ -166,7 +166,7 @@ def generate_separated_sources(platform_sources): 'SkBitmapHasher', 'SkWGL', 'SkImages', - 'SkDiscardableMemory_ashmem' + 'SkDiscardableMemory_ashmem', 'SkMemory_malloc' ] diff --git a/gfx/skia/moz.build b/gfx/skia/moz.build index 1af5e753bbac..a3f04c23b777 100644 --- a/gfx/skia/moz.build +++ b/gfx/skia/moz.build @@ -5,7 +5,6 @@ EXPORTS.skia += [ 'trunk/include/animator/SkAnimator.h', 'trunk/include/animator/SkAnimatorView.h', 'trunk/include/config/SkUserConfig.h', - 'trunk/include/core/Sk64.h', 'trunk/include/core/SkAdvancedTypefaceMetrics.h', 'trunk/include/core/SkAnnotation.h', 'trunk/include/core/SkBitmap.h', @@ -51,7 +50,6 @@ EXPORTS.skia += [ 'trunk/include/core/SkImageDecoder.h', 'trunk/include/core/SkImageEncoder.h', 'trunk/include/core/SkImageFilter.h', - 'trunk/include/core/SkImageFilterUtils.h', 'trunk/include/core/SkImageGenerator.h', 'trunk/include/core/SkImageInfo.h', 'trunk/include/core/SkInstCnt.h', @@ -84,7 +82,6 @@ EXPORTS.skia += [ 'trunk/include/core/SkRegion.h', 'trunk/include/core/SkRRect.h', 'trunk/include/core/SkScalar.h', - 'trunk/include/core/SkScalarCompare.h', 'trunk/include/core/SkShader.h', 'trunk/include/core/SkSize.h', 'trunk/include/core/SkStream.h', @@ -98,7 +95,6 @@ EXPORTS.skia += [ 'trunk/include/core/SkTDStack.h', 'trunk/include/core/SkTemplates.h', 'trunk/include/core/SkThread.h', - 'trunk/include/core/SkThread_platform.h', 'trunk/include/core/SkTileGridPicture.h', 'trunk/include/core/SkTime.h', 'trunk/include/core/SkTInternalLList.h', @@ -123,7 +119,6 @@ EXPORTS.skia += [ 'trunk/include/effects/SkArithmeticMode.h', 'trunk/include/effects/SkAvoidXfermode.h', 'trunk/include/effects/SkBicubicImageFilter.h', - 'trunk/include/effects/SkBitmapAlphaThresholdShader.h', 'trunk/include/effects/SkBitmapSource.h', 'trunk/include/effects/SkBlurDrawLooper.h', 'trunk/include/effects/SkBlurImageFilter.h', @@ -177,14 +172,12 @@ EXPORTS.skia += [ 'trunk/include/gpu/gl/SkNativeGLContext.h', 'trunk/include/gpu/gl/SkNullGLContext.h', 'trunk/include/gpu/GrBackendEffectFactory.h', - 'trunk/include/gpu/GrBitmapTextContext.h', 'trunk/include/gpu/GrClipData.h', 'trunk/include/gpu/GrColor.h', 'trunk/include/gpu/GrConfig.h', 'trunk/include/gpu/GrContext.h', 'trunk/include/gpu/GrContextFactory.h', 'trunk/include/gpu/GrCoordTransform.h', - 'trunk/include/gpu/GrDistanceFieldTextContext.h', 'trunk/include/gpu/GrDrawEffect.h', 'trunk/include/gpu/GrEffect.h', 'trunk/include/gpu/GrEffectStage.h', @@ -200,7 +193,6 @@ EXPORTS.skia += [ 'trunk/include/gpu/GrResource.h', 'trunk/include/gpu/GrSurface.h', 'trunk/include/gpu/GrTBackendEffectFactory.h', - 'trunk/include/gpu/GrTextContext.h', 'trunk/include/gpu/GrTexture.h', 'trunk/include/gpu/GrTextureAccess.h', 'trunk/include/gpu/GrTypes.h', @@ -257,6 +249,7 @@ EXPORTS.skia += [ 'trunk/include/utils/SkMatrix44.h', 'trunk/include/utils/SkMeshUtils.h', 'trunk/include/utils/SkNinePatch.h', + 'trunk/include/utils/SkNoSaveLayerCanvas.h', 'trunk/include/utils/SkNullCanvas.h', 'trunk/include/utils/SkNWayCanvas.h', 'trunk/include/utils/SkParse.h', @@ -358,6 +351,7 @@ SOURCES += [ 'trunk/src/core/SkDevice.cpp', 'trunk/src/core/SkDeviceLooper.cpp', 'trunk/src/core/SkDeviceProfile.cpp', + 'trunk/src/core/SkDistanceFieldGen.cpp', 'trunk/src/core/SkDither.cpp', 'trunk/src/core/SkDraw.cpp', 'trunk/src/core/SkDrawLooper.cpp', @@ -378,7 +372,6 @@ SOURCES += [ 'trunk/src/core/SkGlyphCache.cpp', 'trunk/src/core/SkGraphics.cpp', 'trunk/src/core/SkImageFilter.cpp', - 'trunk/src/core/SkImageFilterUtils.cpp', 'trunk/src/core/SkImageInfo.cpp', 'trunk/src/core/SkInstCnt.cpp', 'trunk/src/core/SkLineClipper.cpp', @@ -515,6 +508,8 @@ SOURCES += [ 'trunk/src/gpu/effects/GrConvexPolyEffect.cpp', 'trunk/src/gpu/effects/GrConvolutionEffect.cpp', 'trunk/src/gpu/effects/GrCustomCoordsTextureEffect.cpp', + 'trunk/src/gpu/effects/GrDistanceFieldTextureEffect.cpp', + 'trunk/src/gpu/effects/GrRRectEffect.cpp', 'trunk/src/gpu/effects/GrSimpleTextureEffect.cpp', 'trunk/src/gpu/effects/GrSingleTextureEffect.cpp', 'trunk/src/gpu/effects/GrTextureDomain.cpp', @@ -570,6 +565,7 @@ SOURCES += [ 'trunk/src/gpu/GrClipMaskManager.cpp', 'trunk/src/gpu/GrContext.cpp', 'trunk/src/gpu/GrDefaultPathRenderer.cpp', + 'trunk/src/gpu/GrDistanceFieldTextContext.cpp', 'trunk/src/gpu/GrDrawState.cpp', 'trunk/src/gpu/GrDrawTarget.cpp', 'trunk/src/gpu/GrEffect.cpp', @@ -693,7 +689,6 @@ SOURCES += [ 'trunk/src/utils/SkProxyCanvas.cpp', 'trunk/src/utils/SkRTConf.cpp', 'trunk/src/utils/SkSHA1.cpp', - 'trunk/src/utils/SkThreadPool.cpp', 'trunk/src/utils/SkUnitMappers.cpp', ] if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gonk'): diff --git a/gfx/skia/trunk/include/core/Sk64.h b/gfx/skia/trunk/include/core/Sk64.h deleted file mode 100644 index 6db3001fb55b..000000000000 --- a/gfx/skia/trunk/include/core/Sk64.h +++ /dev/null @@ -1,230 +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 Sk64_DEFINED -#define Sk64_DEFINED - -#include "SkFixed.h" - -/** \class Sk64 - - Sk64 is a 64-bit math package that does not require long long support from the compiler. -*/ -struct SK_API Sk64 { - int32_t fHi; //!< the high 32 bits of the number (including sign) - uint32_t fLo; //!< the low 32 bits of the number - - /** Returns non-zero if the Sk64 can be represented as a signed 32 bit integer - */ - SkBool is32() const { return fHi == ((int32_t)fLo >> 31); } - - /** Returns non-zero if the Sk64 cannot be represented as a signed 32 bit integer - */ - SkBool is64() const { return fHi != ((int32_t)fLo >> 31); } - - /** Returns non-zero if the Sk64 can be represented as a signed 48 bit integer. Used to know - if we can shift the value down by 16 to treat it as a SkFixed. - */ - SkBool isFixed() const; - - /** Return the signed 32 bit integer equivalent. Asserts that is32() returns non-zero. - */ - int32_t get32() const { SkASSERT(this->is32()); return (int32_t)fLo; } - - /** Return the number >> 16. Asserts that this does not loose any significant high bits. - */ - SkFixed getFixed() const { - SkASSERT(this->isFixed()); - - uint32_t sum = fLo + (1 << 15); - int32_t hi = fHi; - if (sum < fLo) { - hi += 1; - } - return (hi << 16) | (sum >> 16); - } - - /** Return the number >> 30. Asserts that this does not loose any - significant high bits. - */ - SkFract getFract() const; - - /** Returns the square-root of the number as a signed 32 bit value. */ - int32_t getSqrt() const; - - /** Returns the number of leading zeros of the absolute value of this. - Will return in the range [0..64] - */ - int getClzAbs() const; - - /** Returns non-zero if the number is zero */ - SkBool isZero() const { return (fHi | fLo) == 0; } - - /** Returns non-zero if the number is non-zero */ - SkBool nonZero() const { return fHi | fLo; } - - /** Returns non-zero if the number is negative (number < 0) */ - SkBool isNeg() const { return (uint32_t)fHi >> 31; } - - /** Returns non-zero if the number is positive (number > 0) */ - SkBool isPos() const { return ~(fHi >> 31) & (fHi | fLo); } - - /** Returns -1,0,+1 based on the sign of the number */ - int getSign() const { return (fHi >> 31) | Sk32ToBool(fHi | fLo); } - - /** Negate the number */ - void negate(); - - /** If the number < 0, negate the number - */ - void abs(); - - /** Returns the number of bits needed to shift the Sk64 to the right - in order to make it fit in a signed 32 bit integer. - */ - int shiftToMake32() const; - - /** Set the number to zero */ - void setZero() { fHi = fLo = 0; } - - /** Set the high and low 32 bit values of the number */ - void set(int32_t hi, uint32_t lo) { fHi = hi; fLo = lo; } - - /** Set the number to the specified 32 bit integer */ - void set(int32_t a) { fHi = a >> 31; fLo = a; } - - /** Set the number to the product of the two 32 bit integers */ - void setMul(int32_t a, int32_t b); - - /** extract 32bits after shifting right by bitCount. - Note: itCount must be [0..63]. - Asserts that no significant high bits were lost. - */ - int32_t getShiftRight(unsigned bitCount) const; - - /** Shift the number left by the specified number of bits. - @param bits How far to shift left, must be [0..63] - */ - void shiftLeft(unsigned bits); - - /** Shift the number right by the specified number of bits. - @param bits How far to shift right, must be [0..63]. This - performs an arithmetic right-shift (sign extending). - */ - void shiftRight(unsigned bits); - - /** Shift the number right by the specified number of bits, but - round the result. - @param bits How far to shift right, must be [0..63]. This - performs an arithmetic right-shift (sign extending). - */ - void roundRight(unsigned bits); - - /** Add the specified 32 bit integer to the number */ - void add(int32_t lo) { - int32_t hi = lo >> 31; // 0 or -1 - uint32_t sum = fLo + (uint32_t)lo; - - fHi = fHi + hi + (sum < fLo); - fLo = sum; - } - - /** Add the specified Sk64 to the number */ - void add(int32_t hi, uint32_t lo) { - uint32_t sum = fLo + lo; - - fHi = fHi + hi + (sum < fLo); - fLo = sum; - } - - /** Add the specified Sk64 to the number */ - void add(const Sk64& other) { this->add(other.fHi, other.fLo); } - - /** Subtract the specified Sk64 from the number. (*this) = (*this) - num - */ - void sub(const Sk64& num); - - /** Subtract the number from the specified Sk64. (*this) = num - (*this) - */ - void rsub(const Sk64& num); - - /** Multiply the number by the specified 32 bit integer - */ - void mul(int32_t); - - enum DivOptions { - kTrunc_DivOption, //!< truncate the result when calling div() - kRound_DivOption //!< round the result when calling div() - }; - - /** Divide the number by the specified 32 bit integer, using the specified - divide option (either truncate or round). - */ - void div(int32_t, DivOptions); - - /** return (this + other >> 16) as a 32bit result */ - SkFixed addGetFixed(const Sk64& other) const { - return this->addGetFixed(other.fHi, other.fLo); - } - - /** return (this + Sk64(hi, lo) >> 16) as a 32bit result */ - SkFixed addGetFixed(int32_t hi, uint32_t lo) const { -#ifdef SK_DEBUG - Sk64 tmp(*this); - tmp.add(hi, lo); -#endif - - uint32_t sum = fLo + lo; - hi += fHi + (sum < fLo); - lo = sum; - - sum = lo + (1 << 15); - if (sum < lo) - hi += 1; - - hi = (hi << 16) | (sum >> 16); - SkASSERT(hi == tmp.getFixed()); - return hi; - } - - /** Return the result of dividing the number by denom, treating the answer - as a SkFixed. (*this) << 16 / denom. It is an error for denom to be 0. - */ - SkFixed getFixedDiv(const Sk64& denom) const; - - friend bool operator==(const Sk64& a, const Sk64& b) { - return a.fHi == b.fHi && a.fLo == b.fLo; - } - - friend bool operator!=(const Sk64& a, const Sk64& b) { - return a.fHi != b.fHi || a.fLo != b.fLo; - } - - friend bool operator<(const Sk64& a, const Sk64& b) { - return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo < b.fLo); - } - - friend bool operator<=(const Sk64& a, const Sk64& b) { - return a.fHi < b.fHi || (a.fHi == b.fHi && a.fLo <= b.fLo); - } - - friend bool operator>(const Sk64& a, const Sk64& b) { - return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo > b.fLo); - } - - friend bool operator>=(const Sk64& a, const Sk64& b) { - return a.fHi > b.fHi || (a.fHi == b.fHi && a.fLo >= b.fLo); - } - -#ifdef SkLONGLONG - SkLONGLONG getLongLong() const; -#endif -}; - -#endif diff --git a/gfx/skia/trunk/include/core/SkAnnotation.h b/gfx/skia/trunk/include/core/SkAnnotation.h index 872bb941a5dc..d7b9b84529d3 100644 --- a/gfx/skia/trunk/include/core/SkAnnotation.h +++ b/gfx/skia/trunk/include/core/SkAnnotation.h @@ -24,18 +24,27 @@ struct SkPoint; */ class SkAnnotation : public SkRefCnt { public: - SkAnnotation(const char key[], SkData* value); virtual ~SkAnnotation(); + static SkAnnotation* Create(const char key[], SkData* value) { + return SkNEW_ARGS(SkAnnotation, (key, value)); + } + + static SkAnnotation* Create(SkReadBuffer& buffer) { + return SkNEW_ARGS(SkAnnotation, (buffer)); + } + /** * Return the data for the specified key, or NULL. */ SkData* find(const char key[]) const; - SkAnnotation(SkReadBuffer&); void writeToBuffer(SkWriteBuffer&) const; private: + SkAnnotation(const char key[], SkData* value); + SkAnnotation(SkReadBuffer&); + SkString fKey; SkData* fData; diff --git a/gfx/skia/trunk/include/core/SkBitmap.h b/gfx/skia/trunk/include/core/SkBitmap.h index 42ef8778bfcf..18c467995030 100644 --- a/gfx/skia/trunk/include/core/SkBitmap.h +++ b/gfx/skia/trunk/include/core/SkBitmap.h @@ -14,6 +14,7 @@ #include "SkPoint.h" #include "SkRefCnt.h" +struct SkMask; struct SkIRect; struct SkRect; class SkPaint; @@ -21,7 +22,6 @@ class SkPixelRef; class SkPixelRefFactory; class SkRegion; class SkString; - class GrTexture; /** \class SkBitmap @@ -308,6 +308,22 @@ public: void (*ReleaseProc)(void* addr, void* context), void* context); + /** + * Call installPixels with no ReleaseProc specified. This means that the + * caller must ensure that the specified pixels are valid for the lifetime + * of the created bitmap (and its pixelRef). + */ + bool installPixels(const SkImageInfo& info, void* pixels, size_t rowBytes) { + return this->installPixels(info, pixels, rowBytes, NULL, NULL); + } + + /** + * Calls installPixels() with the value in the SkMask. The caller must + * ensure that the specified mask pixels are valid for the lifetime + * of the created bitmap (and its pixelRef). + */ + bool installMaskPixels(const SkMask&); + /** * DEPRECATED: call info(). */ @@ -455,7 +471,7 @@ public: */ bool readyToDraw() const { return this->getPixels() != NULL && - (this->config() != kIndex8_Config || NULL != fColorTable); + (this->colorType() != kIndex_8_SkColorType || NULL != fColorTable); } /** Returns the pixelRef's texture, or NULL @@ -599,33 +615,37 @@ public: */ bool extractSubset(SkBitmap* dst, const SkIRect& subset) const; - /** Makes a deep copy of this bitmap, respecting the requested config, + /** Makes a deep copy of this bitmap, respecting the requested colorType, * and allocating the dst pixels on the cpu. * Returns false if either there is an error (i.e. the src does not have * pixels) or the request cannot be satisfied (e.g. the src has per-pixel * alpha, and the requested config does not support alpha). * @param dst The bitmap to be sized and allocated - * @param c The desired config for dst + * @param ct The desired colorType for dst * @param allocator Allocator used to allocate the pixelref for the dst * bitmap. If this is null, the standard HeapAllocator * will be used. - * @return true if the copy could be made. + * @return true if the copy was made. */ - bool copyTo(SkBitmap* dst, Config c, Allocator* allocator = NULL) const; + bool copyTo(SkBitmap* dst, SkColorType ct, Allocator* = NULL) const; - /** Makes a deep copy of this bitmap, respecting the requested config, and - * with custom allocation logic that will keep the copied pixels + bool copyTo(SkBitmap* dst, Allocator* allocator = NULL) const { + return this->copyTo(dst, this->colorType(), allocator); + } + + /** + * Returns true if this bitmap's pixels can be converted into the requested + * colorType, such that copyTo() could succeed. + */ + bool canCopyTo(SkColorType colorType) const; + + /** Makes a deep copy of this bitmap, keeping the copied pixels * in the same domain as the source: If the src pixels are allocated for * the cpu, then so will the dst. If the src pixels are allocated on the * gpu (typically as a texture), the it will do the same for the dst. * If the request cannot be fulfilled, returns false and dst is unmodified. */ - bool deepCopyTo(SkBitmap* dst, Config c) const; - - /** Returns true if this bitmap can be deep copied into the requested config - by calling copyTo(). - */ - bool canCopyTo(Config newConfig) const; + bool deepCopyTo(SkBitmap* dst) const; SK_ATTR_DEPRECATED("use setFilterLevel on SkPaint") void buildMipMap(bool forceRebuild = false); @@ -727,7 +747,7 @@ public: int fHeight; }; - SkDEVCODE(void toString(SkString* str) const;) + SK_TO_STRING_NONVIRT() private: struct MipMap; @@ -870,31 +890,38 @@ private: inline uint32_t* SkBitmap::getAddr32(int x, int y) const { SkASSERT(fPixels); - SkASSERT(this->config() == kARGB_8888_Config); + SkASSERT(4 == this->bytesPerPixel()); SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height()); return (uint32_t*)((char*)fPixels + y * fRowBytes + (x << 2)); } inline uint16_t* SkBitmap::getAddr16(int x, int y) const { SkASSERT(fPixels); - SkASSERT(this->config() == kRGB_565_Config || this->config() == kARGB_4444_Config); + SkASSERT(2 == this->bytesPerPixel()); SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height()); return (uint16_t*)((char*)fPixels + y * fRowBytes + (x << 1)); } inline uint8_t* SkBitmap::getAddr8(int x, int y) const { SkASSERT(fPixels); - SkASSERT(this->config() == kA8_Config || this->config() == kIndex8_Config); + SkASSERT(1 == this->bytesPerPixel()); SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height()); return (uint8_t*)fPixels + y * fRowBytes + x; } inline SkPMColor SkBitmap::getIndex8Color(int x, int y) const { SkASSERT(fPixels); - SkASSERT(this->config() == kIndex8_Config); + SkASSERT(kIndex_8_SkColorType == this->colorType()); SkASSERT((unsigned)x < (unsigned)this->width() && (unsigned)y < (unsigned)this->height()); SkASSERT(fColorTable); return (*fColorTable)[*((const uint8_t*)fPixels + y * fRowBytes + x)]; } +/////////////////////////////////////////////////////////////////////////////// +// +// Helpers until we can fully deprecate SkBitmap::Config +// +extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType); +extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config); + #endif diff --git a/gfx/skia/trunk/include/core/SkBitmapDevice.h b/gfx/skia/trunk/include/core/SkBitmapDevice.h index e4f9b88a5e68..afbefc15f364 100644 --- a/gfx/skia/trunk/include/core/SkBitmapDevice.h +++ b/gfx/skia/trunk/include/core/SkBitmapDevice.h @@ -30,6 +30,7 @@ public: */ SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties); +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG /** * Create a new raster device and have the pixels be automatically * allocated. The rowBytes of the device will be computed automatically @@ -61,10 +62,9 @@ public: */ SkBitmapDevice(SkBitmap::Config config, int width, int height, bool isOpaque, const SkDeviceProperties& deviceProperties); - - virtual ~SkBitmapDevice(); - - virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; } +#endif + static SkBitmapDevice* Create(const SkImageInfo&, + const SkDeviceProperties* = NULL); /** Return the width of the device (in pixels). */ @@ -82,6 +82,9 @@ public: */ virtual SkBitmap::Config config() const SK_OVERRIDE { return fBitmap.config(); } + virtual SkImageInfo imageInfo() const SK_OVERRIDE; + +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG /** * DEPRECATED: This will be made protected once WebKit stops using it. * Instead use Canvas' writePixels method. @@ -99,7 +102,7 @@ public: */ virtual void writePixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) SK_OVERRIDE; - +#endif /** * Return the device's associated gpu render target, or NULL. */ @@ -183,7 +186,7 @@ protected: 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 - onCreateCompatibleDevice on this device with kSaveLayer_Usage. + onCreateDevice on this device with kSaveLayer_Usage. */ virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) SK_OVERRIDE; @@ -211,9 +214,9 @@ protected: * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is * contained in the device bounds. */ - virtual bool onReadPixels(const SkBitmap& bitmap, - int x, int y, - SkCanvas::Config8888 config8888) SK_OVERRIDE; + virtual bool onReadPixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) 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. @@ -245,7 +248,7 @@ protected: * If the device does not recognize or support this filter, * it just returns false and leaves result and offset unchanged. */ - virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkMatrix&, + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE; private: @@ -258,26 +261,24 @@ private: friend class SkSurface_Raster; - void init(SkBitmap::Config config, int width, int height, bool isOpaque); - // 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; - /** - * Subclasses should override this to implement createCompatibleDevice. - */ - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG + // in support of legacy constructors + void init(SkBitmap::Config config, int width, int height, bool isOpaque); +#endif + + virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; /** Causes any deferred drawing to the device to be completed. */ virtual void flush() SK_OVERRIDE {} virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE; + virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes) SK_OVERRIDE; SkBitmap fBitmap; diff --git a/gfx/skia/trunk/include/core/SkCanvas.h b/gfx/skia/trunk/include/core/SkCanvas.h index 7235efb2f0a9..b5df1e85e02f 100644 --- a/gfx/skia/trunk/include/core/SkCanvas.h +++ b/gfx/skia/trunk/include/core/SkCanvas.h @@ -18,6 +18,15 @@ #include "SkRegion.h" #include "SkXfermode.h" +// if not defined, we always assume ClipToLayer for saveLayer() +//#define SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG + + +//#define SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG +//#define SK_SUPPORT_LEGACY_GETCLIPTYPE +//#define SK_SUPPORT_LEGACY_GETTOTALCLIP +//#define SK_SUPPORT_LEGACY_GETTOPDEVICE + class SkBounder; class SkBaseDevice; class SkDraw; @@ -28,6 +37,7 @@ class SkRRect; class SkSurface; class SkSurface_Base; class GrContext; +class GrRenderTarget; /** \class SkCanvas @@ -48,6 +58,56 @@ 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 + * flush() or call peekPixels(...). + * + * On failure, return NULL. This can fail for several reasons: + * 1. invalid ImageInfo (e.g. negative dimensions) + * 2. 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* NewRasterDirect(const SkImageInfo&, void*, size_t); + + static SkCanvas* NewRasterDirectN32(int width, int height, SkPMColor* pixels, size_t rowBytes) { + return NewRasterDirect(SkImageInfo::MakeN32Premul(width, height), pixels, rowBytes); + } + /** * Creates an empty canvas with no backing device/pixels, and zero * dimensions. @@ -76,6 +136,12 @@ public: SkMetaData& getMetaData(); + /** + * Return ImageInfo for this canvas. If the canvas is not backed by pixels + * (cpu or gpu), then the info's ColorType will be kUnknown_SkColorType. + */ + SkImageInfo imageInfo() const; + /////////////////////////////////////////////////////////////////////////// /** @@ -84,16 +150,23 @@ public: void flush(); /** - * Return the width/height of the underlying device. The current drawable - * area may be small (due to clipping or saveLayer). For a canvas with - * no device, 0,0 will be returned. + * Gets the size of the base or root layer in global canvas coordinates. The + * origin of the base layer is always (0,0). The current drawable area may be + * smaller (due to clipping or saveLayer). */ - SkISize getDeviceSize() const; + SkISize getBaseLayerSize() const; - /** Return the canvas' device object, which may be null. The device holds - the bitmap of the pixels that the canvas draws into. The reference count - of the returned device is not changed by this call. - */ + /** + * DEPRECATED: call getBaseLayerSize + */ + SkISize getDeviceSize() const { return this->getBaseLayerSize(); } + + /** + * DEPRECATED. + * Return the canvas' device object, which may be null. The device holds + * the bitmap of the pixels that the canvas draws into. The reference count + * of the returned device is not changed by this call. + */ SkBaseDevice* getDevice() const; /** @@ -109,7 +182,11 @@ public: * is drawn to, but is optional here, as there is a small perf hit * sometimes. */ +#ifndef SK_SUPPORT_LEGACY_GETTOPDEVICE +private: +#endif SkBaseDevice* getTopDevice(bool updateMatrixClip = false) const; +public: /** * Create a new surface matching the specified info, one that attempts to @@ -125,6 +202,34 @@ public: /////////////////////////////////////////////////////////////////////////// + /** + * If the canvas has writable pixels in its top layer (and is not recording to a picture + * or other non-raster target) and has direct access to its pixels (i.e. they are in + * local RAM) return the address of those pixels, and if not null, + * return the ImageInfo and rowBytes. The returned address is only valid + * while the canvas object is in scope and unchanged. Any API calls made on + * canvas (or its parent surface if any) will invalidate the + * returned address (and associated information). + * + * On failure, returns NULL and the info and rowBytes parameters are + * ignored. + */ + void* accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes); + + /** + * If the canvas has readable pixels in its base layer (and is not recording to a picture + * or other non-raster target) and 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 the ImageInfo and rowBytes. The returned address is only valid + * while the canvas object is in scope and unchanged. Any API calls made on + * canvas (or its parent surface if any) will invalidate the + * returned address (and associated information). + * + * On failure, returns NULL and the info and rowBytes parameters are + * ignored. + */ + const void* peekPixels(SkImageInfo* info, size_t* rowBytes); + /** * This enum can be used with read/writePixels to perform a pixel ops to or * from an 8888 config other than Skia's native config (SkPMColor). There @@ -208,7 +313,9 @@ public: */ bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap); +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG /** + * DEPRECATED * Similar to draw sprite, this method will copy the pixels in bitmap onto * the canvas, with the top/left corner specified by (x, y). The canvas' * pixel values are completely replaced: there is no blending. @@ -223,9 +330,34 @@ public: * Note: If you are recording drawing commands on this canvas to * SkPicture, writePixels() is ignored! */ - void writePixels(const SkBitmap& bitmap, - int x, int y, - Config8888 config8888 = kNative_Premul_Config8888); + void writePixels(const SkBitmap& bitmap, int x, int y, Config8888 config8888); +#endif + + /** + * This method affects the pixels in the base-layer, and operates in pixel coordinates, + * ignoring the matrix and clip. + * + * The specified ImageInfo and (x,y) offset specifies a rectangle: target. + * + * target.setXYWH(x, y, info.width(), info.height()); + * + * Target 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), the "src" specified by info+pixels+rowBytes + * and the "dst" by the canvas' backend. 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 the src colortype/alphatype cannot be converted to the canvas' types + * - If this canvas is not backed by pixels (e.g. picture or PDF) + */ + bool writePixels(const SkImageInfo&, const void* pixels, size_t rowBytes, int x, int y); + + /** + * Helper for calling writePixels(info, ...) by passing its pixels and rowbytes. If the bitmap + * is just wrapping a texture, returns false and does nothing. + */ + bool writePixels(const SkBitmap& bitmap, int x, int y); /////////////////////////////////////////////////////////////////////////// @@ -238,12 +370,18 @@ public: kHasAlphaLayer_SaveFlag = 0x04, /** the layer needs to support 8-bits per color component */ kFullColorLayer_SaveFlag = 0x08, - /** the layer should clip against the bounds argument */ + /** + * the layer should clip against the bounds argument + * + * if SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG is undefined, this is treated as always on. + */ kClipToLayer_SaveFlag = 0x10, // helper masks for common choices kMatrixClip_SaveFlag = 0x03, +#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG kARGB_NoClipLayer_SaveFlag = 0x0F, +#endif kARGB_ClipLayer_SaveFlag = 0x1F }; @@ -261,7 +399,7 @@ public: by calls to save/restore. @return The value to pass to restoreToCount() to balance this save() */ - virtual int save(SaveFlags flags = kMatrixClip_SaveFlag); + int save(SaveFlags flags = kMatrixClip_SaveFlag); /** This behaves the same as save(), but in addition it allocates an offscreen bitmap. All drawing calls are directed there, and only when @@ -276,8 +414,8 @@ public: @param flags LayerFlags @return The value to pass to restoreToCount() to balance this save() */ - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags = kARGB_ClipLayer_SaveFlag); + int saveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags = kARGB_ClipLayer_SaveFlag); /** This behaves the same as save(), but in addition it allocates an offscreen bitmap. All drawing calls are directed there, and only when @@ -299,16 +437,18 @@ public: call. It is an error to call restore() more times than save() was called. */ - virtual void restore(); + void restore(); /** Returns the number of matrix/clip states on the SkCanvas' private stack. - This will equal # save() calls - # restore() calls. + This will equal # save() calls - # restore() calls + 1. The save count on + a new canvas is 1. */ int getSaveCount() const; /** Efficient way to pop any calls to save() that happened after the save - count reached saveCount. It is an error for saveCount to be less than - getSaveCount() + count reached saveCount. It is an error for saveCount to be greater than + getSaveCount(). To pop all the way back to the initial matrix/clip context + pass saveCount == 1. @param saveCount The number of save() levels to restore from */ void restoreToCount(int saveCount); @@ -323,38 +463,38 @@ public: @param dy The distance to translate in Y returns true if the operation succeeded (e.g. did not overflow) */ - virtual bool translate(SkScalar dx, SkScalar dy); + bool translate(SkScalar dx, SkScalar dy); /** Preconcat the current matrix with the specified scale. @param sx The amount to scale in X @param sy The amount to scale in Y returns true if the operation succeeded (e.g. did not overflow) */ - virtual bool scale(SkScalar sx, SkScalar sy); + bool scale(SkScalar sx, SkScalar sy); /** Preconcat the current matrix with the specified rotation. @param degrees The amount to rotate, in degrees returns true if the operation succeeded (e.g. did not overflow) */ - virtual bool rotate(SkScalar degrees); + bool rotate(SkScalar degrees); /** Preconcat the current matrix with the specified skew. @param sx The amount to skew in X @param sy The amount to skew in Y returns true if the operation succeeded (e.g. did not overflow) */ - virtual bool skew(SkScalar sx, SkScalar sy); + bool skew(SkScalar sx, SkScalar sy); /** Preconcat the current matrix with the specified matrix. @param matrix The matrix to preconcatenate with the current matrix @return true if the operation succeeded (e.g. did not overflow) */ - virtual bool concat(const SkMatrix& matrix); + bool concat(const SkMatrix& matrix); /** Replace the current matrix with a copy of the specified matrix. @param matrix The matrix that will be copied into the current matrix. */ - virtual void setMatrix(const SkMatrix& matrix); + void setMatrix(const SkMatrix& matrix); /** Helper for setMatrix(identity). Sets the current matrix to identity. */ @@ -365,33 +505,30 @@ public: * @param rect The rect to combine with the current clip * @param op The region op to apply to the current clip * @param doAntiAlias true if the clip should be antialiased - * @return true if the canvas' clip is non-empty */ - virtual bool clipRect(const SkRect& rect, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false); + void clipRect(const SkRect& rect, + SkRegion::Op op = SkRegion::kIntersect_Op, + bool doAntiAlias = false); /** * Modify the current clip with the specified SkRRect. * @param rrect The rrect to combine with the current clip * @param op The region op to apply to the current clip * @param doAntiAlias true if the clip should be antialiased - * @return true if the canvas' clip is non-empty */ - virtual bool clipRRect(const SkRRect& rrect, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false); + void clipRRect(const SkRRect& rrect, + SkRegion::Op op = SkRegion::kIntersect_Op, + bool doAntiAlias = false); /** * Modify the current clip with the specified path. * @param path The path to combine with the current clip * @param op The region op to apply to the current clip * @param doAntiAlias true if the clip should be antialiased - * @return true if the canvas' new clip is non-empty */ - virtual bool clipPath(const SkPath& path, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false); + void clipPath(const SkPath& path, + SkRegion::Op op = SkRegion::kIntersect_Op, + bool doAntiAlias = false); /** EXPERIMENTAL -- only used for testing Set to false to force clips to be hard, even if doAntiAlias=true is @@ -414,19 +551,17 @@ public: coordinates, and so no transformation is performed. @param deviceRgn The region to apply to the current clip @param op The region op to apply to the current clip - @return true if the canvas' new clip is non-empty */ - virtual bool clipRegion(const SkRegion& deviceRgn, - SkRegion::Op op = SkRegion::kIntersect_Op); + void clipRegion(const SkRegion& deviceRgn, + SkRegion::Op op = SkRegion::kIntersect_Op); /** Helper for clipRegion(rgn, kReplace_Op). Sets the current clip to the specified region. This does not intersect or in any other way account for the existing clip region. @param deviceRgn The region to copy into the current clip. - @return true if the new clip region is non-empty */ - bool setClipRegion(const SkRegion& deviceRgn) { - return this->clipRegion(deviceRgn, SkRegion::kReplace_Op); + void setClipRegion(const SkRegion& deviceRgn) { + this->clipRegion(deviceRgn, SkRegion::kReplace_Op); } /** Return true if the specified rectangle, after being transformed by the @@ -463,6 +598,20 @@ public: */ bool quickRejectY(SkScalar top, SkScalar bottom) const { SkASSERT(top <= bottom); + +#ifndef SK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT + // TODO: add a hasPerspective method similar to getLocalClipBounds. This + // would cache the SkMatrix::hasPerspective result. Alternatively, have + // the MC stack just set a hasPerspective boolean as it is updated. + if (this->getTotalMatrix().hasPerspective()) { + // TODO: consider implementing some half-plane test between the + // two Y planes and the device-bounds (i.e., project the top and + // bottom Y planes and then determine if the clip bounds is completely + // outside either one). + return false; + } +#endif + const SkRect& clipR = this->getLocalClipBounds(); // In the case where the clip is empty and we are provided with a // negative top and positive bottom parameter then this test will return @@ -476,13 +625,13 @@ public: in a way similar to quickReject, in that it tells you that drawing outside of these bounds will be clipped out. */ - bool getClipBounds(SkRect* bounds) const; + virtual bool getClipBounds(SkRect* bounds) const; /** Return the bounds of the current clip, in device coordinates; returns true if non-empty. Maybe faster than getting the clip explicitly and then taking its bounds. */ - bool getClipDeviceBounds(SkIRect* bounds) const; + virtual bool getClipDeviceBounds(SkIRect* bounds) const; /** Fill the entire canvas' bitmap (restricted to the current clip) with the @@ -596,8 +745,7 @@ public: @param rect The rect to be drawn @param paint The paint used to draw the rect */ - void drawIRect(const SkIRect& rect, const SkPaint& paint) - { + void drawIRect(const SkIRect& rect, const SkPaint& paint) { SkRect r; r.set(rect); // promotes the ints to scalars this->drawRect(r, paint); @@ -630,6 +778,12 @@ public: */ virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint); + /** + * Draw the annulus formed by the outer and inner rrects. The results + * are undefined if the outer does not contain the inner. + */ + void drawDRRect(const SkRRect& outer, const SkRRect& inner, const SkPaint&); + /** Draw the specified circle using the specified paint. If radius is <= 0, then nothing will be drawn. The circle will be filled or framed based on the Style in the paint. @@ -829,6 +983,14 @@ public: 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 + */ + void EXPERIMENTAL_optimize(SkPicture* picture); + /** Draw the picture into this canvas. This method effective brackets the playback of the picture's draw calls with save/restore, so the state of this canvas will be unchanged after this call. @@ -891,7 +1053,26 @@ public: // do nothing. Subclasses may do something } + /** + * 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. + */ + void pushCull(const SkRect& cullRect) { + ++fCullCount; + this->onPushCull(cullRect); + } + /** + * Terminates the current culling block, and restores the previous one (if any). + */ + void popCull() { + if (fCullCount > 0) { + --fCullCount; + this->onPopCull(); + } + } ////////////////////////////////////////////////////////////////////////// /** Get the current bounder object. @@ -928,29 +1109,47 @@ public: ////////////////////////////////////////////////////////////////////////// + /** + * Return true if the current clip is empty (i.e. nothing will draw). + * Note: this is not always a free call, so it should not be used + * more often than necessary. However, once the canvas has computed this + * result, subsequent calls will be cheap (until the clip state changes, + * which can happen on any clip..() or restore() call. + */ + virtual bool isClipEmpty() const; + + /** + * Returns true if the current clip is just a (non-empty) rectangle. + * Returns false if the clip is empty, or if it is complex. + */ + virtual bool isClipRect() const; + /** Return the current matrix on the canvas. This does not account for the translate in any of the devices. @return The current matrix on the canvas. */ 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. */ - ClipType getClipType() const; + virtual ClipType getClipType() const; +#endif +#ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP /** DEPRECATED -- need to move this guy to private/friend * Return the current device clip (concatenation of all clip calls). * This does not account for the translate in any of the devices. * @return the current device clip (concatenation of all clip calls). */ const SkRegion& getTotalClip() const; +#endif /** Return the clip stack. The clip stack stores all the individual * clips organized by the save/restore frame in which they were @@ -965,6 +1164,7 @@ public: public: virtual ~ClipVisitor(); virtual void clipRect(const SkRect&, SkRegion::Op, bool antialias) = 0; + virtual void clipRRect(const SkRRect&, SkRegion::Op, bool antialias) = 0; virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) = 0; }; @@ -1015,10 +1215,51 @@ 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(); + protected: // default impl defers to getDevice()->newSurface(info) virtual SkSurface* onNewSurface(const SkImageInfo&); + // default impl defers to its device + virtual const void* onPeekPixels(SkImageInfo*, size_t* rowBytes); + virtual void* onAccessTopLayerPixels(SkImageInfo*, size_t* rowBytes); + + // Subclass save/restore notifiers. + // Overriders should call the corresponding INHERITED method up the inheritance chain. + // willSaveLayer()'s return value may suppress full layer allocation. + enum SaveLayerStrategy { + kFullLayer_SaveLayerStrategy, + kNoLayer_SaveLayerStrategy + }; + virtual void willSave(SaveFlags); + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags); + virtual void willRestore(); + + virtual void didTranslate(SkScalar, SkScalar); + virtual void didScale(SkScalar, SkScalar); + virtual void didRotate(SkScalar); + virtual void didSkew(SkScalar, SkScalar); + virtual void didConcat(const SkMatrix&); + virtual void didSetMatrix(const SkMatrix&); + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&); + + enum ClipEdgeStyle { + kHard_ClipEdgeStyle, + kSoft_ClipEdgeStyle + }; + + virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle); + virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle); + virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle); + virtual void onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op); + // Returns the canvas to be used by DrawIter. Default implementation // returns this. Subclasses that encapsulate an indirect canvas may // need to overload this method. The impl must keep track of this, as it @@ -1035,23 +1276,15 @@ protected: // Called by child classes that override clipPath and clipRRect to only // track fast conservative clip bounds, rather than exact clips. - bool updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op, + void updateClipConservativelyUsingBounds(const SkRect&, SkRegion::Op, bool inverseFilled); // 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(); - /** - DEPRECATED -- need to remove when subclass stop relying on it. - Marked as 'protected' to avoid new clients using this before we can - completely remove it. - - 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. - */ - virtual SkBaseDevice* setDevice(SkBaseDevice* device); + virtual void onPushCull(const SkRect& cullRect); + virtual void onPopCull(); private: class MCRec; @@ -1065,6 +1298,7 @@ private: SkBounder* fBounder; int fSaveLayerCount; // number of successful saveLayer calls + int fCullCount; // number of active culls SkMetaData* fMetaData; @@ -1079,14 +1313,31 @@ private: bool fDeviceCMDirty; // cleared by updateDeviceCMCache() void updateDeviceCMCache(); - friend class SkDrawIter; // needs setupDrawForLayerDevice() + friend class SkDrawIter; // needs setupDrawForLayerDevice() friend class AutoDrawLooper; + friend class SkLua; // needs top layer size and offset + friend class SkDeferredDevice; // needs getTopDevice() - SkBaseDevice* createLayerDevice(SkBitmap::Config, int width, int height, - bool isOpaque); + SkBaseDevice* createLayerDevice(const SkImageInfo&); SkBaseDevice* init(SkBaseDevice*); + /** + * 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); + + /** + * Gets the size/origin of the top level layer in global canvas coordinates. We don't want this + * to be public because it exposes decisions about layer sizes that are internal to the canvas. + */ + 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); @@ -1097,7 +1348,7 @@ private: const SkRect& dst, const SkPaint* paint); void internalDrawPaint(const SkPaint& paint); int internalSaveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags, bool justForImageFilter); + SaveFlags, bool justForImageFilter, SaveLayerStrategy strategy); void internalDrawDevice(SkBaseDevice*, int x, int y, const SkPaint*); // shared by save() and saveLayer() @@ -1206,4 +1457,47 @@ private: }; #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 + * pixels on a raster-backed canvas. + * + * If the canvas has pixels, but they are not readily available to the CPU + * (e.g. gpu-backed), then peekPixels() will fail, but readPixels() will + * succeed (though be slower, since it will return a copy of the pixels). + * + * SkAutoROCanvasPixels encapsulates these two techniques, trying first to call + * peekPixels() (for performance), but if that fails, calling readPixels() and + * storing the copy locally. + * + * The caller must respect the restrictions associated with peekPixels(), since + * that may have been called: The returned information is invalidated if... + * - any API is called on the canvas (or its parent surface if present) + * - the canvas goes out of scope + */ +class SkAutoROCanvasPixels : SkNoncopyable { +public: + SkAutoROCanvasPixels(SkCanvas* canvas); + + // returns NULL on failure + const void* addr() const { return fAddr; } + + // undefined if addr() == NULL + size_t rowBytes() const { return fRowBytes; } + + // undefined if addr() == NULL + const SkImageInfo& info() const { return fInfo; } + + // helper that, if returns true, installs the pixels into the bitmap. Note + // that the bitmap may reference the address returned by peekPixels(), so + // the caller must respect the restrictions associated with peekPixels(). + bool asROBitmap(SkBitmap*) const; + +private: + SkBitmap fBitmap; // used if peekPixels() fails + const void* fAddr; // NULL on failure + SkImageInfo fInfo; + size_t fRowBytes; +}; + #endif diff --git a/gfx/skia/trunk/include/core/SkClipStack.h b/gfx/skia/trunk/include/core/SkClipStack.h index 0d6cfb296fc5..028d55156068 100644 --- a/gfx/skia/trunk/include/core/SkClipStack.h +++ b/gfx/skia/trunk/include/core/SkClipStack.h @@ -11,8 +11,10 @@ #include "SkDeque.h" #include "SkPath.h" #include "SkRect.h" +#include "SkRRect.h" #include "SkRegion.h" #include "SkTDArray.h" +#include "SkTLazy.h" // Because a single save/restore state can have multiple clips, this class @@ -41,6 +43,8 @@ public: kEmpty_Type, //!< This element combines a rect with the current clip using a set operation kRect_Type, + //!< This element combines a round-rect with the current clip using a set operation + kRRect_Type, //!< This element combines a path with the current clip using a set operation kPath_Type, }; @@ -50,50 +54,44 @@ public: this->setEmpty(); } + Element(const Element&); + Element(const SkRect& rect, SkRegion::Op op, bool doAA) { this->initRect(0, rect, op, doAA); } + Element(const SkRRect& rrect, SkRegion::Op op, bool doAA) { + this->initRRect(0, rrect, op, doAA); + } + Element(const SkPath& path, SkRegion::Op op, bool doAA) { this->initPath(0, path, op, doAA); } - bool operator== (const Element& element) const { - if (this == &element) { - return true; - } - if (fOp != element.fOp || - fType != element.fType || - fDoAA != element.fDoAA || - fSaveCount != element.fSaveCount) { - return false; - } - switch (fType) { - case kPath_Type: - return fPath == element.fPath; - case kRect_Type: - return fRect == element.fRect; - case kEmpty_Type: - return true; - default: - SkDEBUGFAIL("Unexpected type."); - return false; - } - } + bool operator== (const Element& element) const; bool operator!= (const Element& element) const { return !(*this == element); } //!< Call to get the type of the clip element. Type getType() const { return fType; } //!< Call if getType() is kPath to get the path. - const SkPath& getPath() const { return fPath; } + const SkPath& getPath() const { SkASSERT(kPath_Type == fType); return *fPath.get(); } + + //!< Call if getType() is kRRect to get the round-rect. + const SkRRect& getRRect() const { SkASSERT(kRRect_Type == fType); return fRRect; } //!< Call if getType() is kRect to get the rect. - const SkRect& getRect() const { return fRect; } + const SkRect& getRect() const { + SkASSERT(kRect_Type == fType && (fRRect.isRect() || fRRect.isEmpty())); + return fRRect.getBounds(); + } //!< Call if getType() is not kEmpty to get the set operation used to combine this element. SkRegion::Op getOp() const { return fOp; } + //!< Call to get the element as a path, regardless of its type. + void asPath(SkPath* path) const; + /** If getType() is not kEmpty this indicates whether the clip shape should be anti-aliased when it is rasterized. */ bool isAA() const { return fDoAA; } @@ -118,10 +116,11 @@ public: const SkRect& getBounds() const { static const SkRect kEmpty = { 0, 0, 0, 0 }; switch (fType) { - case kRect_Type: - return fRect; + case kRect_Type: // fallthrough + case kRRect_Type: + return fRRect.getBounds(); case kPath_Type: - return fPath.getBounds(); + return fPath.get()->getBounds(); case kEmpty_Type: return kEmpty; default: @@ -137,9 +136,11 @@ public: bool contains(const SkRect& rect) const { switch (fType) { case kRect_Type: - return fRect.contains(rect); + return this->getRect().contains(rect); + case kRRect_Type: + return fRRect.contains(rect); case kPath_Type: - return fPath.conservativelyContainsRect(rect); + return fPath.get()->conservativelyContainsRect(rect); case kEmpty_Type: return false; default: @@ -152,14 +153,14 @@ public: * Is the clip shape inverse filled. */ bool isInverseFilled() const { - return kPath_Type == fType && fPath.isInverseFillType(); + return kPath_Type == fType && fPath.get()->isInverseFillType(); } private: friend class SkClipStack; - SkPath fPath; - SkRect fRect; + SkTLazy fPath; + SkRRect fRRect; int fSaveCount; // save count of stack when this element was added. SkRegion::Op fOp; Type fType; @@ -189,6 +190,10 @@ public: this->setEmpty(); } + Element(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) { + this->initRRect(saveCount, rrect, op, doAA); + } + Element(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) { this->initRect(saveCount, rect, op, doAA); } @@ -210,26 +215,25 @@ public: } void initRect(int saveCount, const SkRect& rect, SkRegion::Op op, bool doAA) { - fRect = rect; + fRRect.setRect(rect); fType = kRect_Type; this->initCommon(saveCount, op, doAA); } - void initPath(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA) { - fPath = path; - fType = kPath_Type; + void initRRect(int saveCount, const SkRRect& rrect, SkRegion::Op op, bool doAA) { + SkRRect::Type type = rrect.getType(); + fRRect = rrect; + if (SkRRect::kRect_Type == type || SkRRect::kEmpty_Type == type) { + fType = kRect_Type; + } else { + fType = kRRect_Type; + } this->initCommon(saveCount, op, doAA); } - void setEmpty() { - fType = kEmpty_Type; - fFiniteBound.setEmpty(); - fFiniteBoundType = kNormal_BoundsType; - fIsIntersectionOfRects = false; - fRect.setEmpty(); - fPath.reset(); - fGenID = kEmptyGenID; - } + void initPath(int saveCount, const SkPath& path, SkRegion::Op op, bool doAA); + + void setEmpty(); // All Element methods below are only used within SkClipStack.cpp inline void checkEmpty() const; @@ -305,6 +309,7 @@ public: this->clipDevRect(r, op, false); } void clipDevRect(const SkRect&, SkRegion::Op, bool doAA); + void clipDevRRect(const SkRRect&, SkRegion::Op, bool doAA); void clipDevPath(const SkPath&, SkRegion::Op, bool doAA); // An optimized version of clipDevRect(emptyRect, kIntersect, ...) void clipEmpty(); @@ -427,6 +432,11 @@ private: // invalid ID. static int32_t gGenID; + /** + * Helper for clipDevPath, etc. + */ + void pushElement(const Element& element); + /** * Restore the stack back to the specified save count. */ diff --git a/gfx/skia/trunk/include/core/SkColorFilter.h b/gfx/skia/trunk/include/core/SkColorFilter.h index a5ffca818dee..c26bc075c983 100644 --- a/gfx/skia/trunk/include/core/SkColorFilter.h +++ b/gfx/skia/trunk/include/core/SkColorFilter.h @@ -128,7 +128,7 @@ public: */ virtual GrEffectRef* asNewEffect(GrContext*) const; - SkDEVCODE(virtual void toString(SkString* str) const = 0;) + SK_TO_STRING_PUREVIRT() SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() SK_DEFINE_FLATTENABLE_TYPE(SkColorFilter) diff --git a/gfx/skia/trunk/include/core/SkColorShader.h b/gfx/skia/trunk/include/core/SkColorShader.h index 5b8a86dfc1b0..975156c0eb3a 100644 --- a/gfx/skia/trunk/include/core/SkColorShader.h +++ b/gfx/skia/trunk/include/core/SkColorShader.h @@ -48,7 +48,7 @@ public: virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorShader) protected: diff --git a/gfx/skia/trunk/include/core/SkComposeShader.h b/gfx/skia/trunk/include/core/SkComposeShader.h index 1fefd1369a1c..e29578cabc86 100644 --- a/gfx/skia/trunk/include/core/SkComposeShader.h +++ b/gfx/skia/trunk/include/core/SkComposeShader.h @@ -39,7 +39,7 @@ public: virtual void endContext() SK_OVERRIDE; virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader) protected: diff --git a/gfx/skia/trunk/include/core/SkDevice.h b/gfx/skia/trunk/include/core/SkDevice.h index 016e2babc88d..3c677744895b 100644 --- a/gfx/skia/trunk/include/core/SkDevice.h +++ b/gfx/skia/trunk/include/core/SkDevice.h @@ -15,6 +15,14 @@ #include "SkCanvas.h" #include "SkColor.h" #include "SkDeviceProperties.h" +#include "SkImageFilter.h" + +// getDeviceCapabilities() is not called by skia, but this flag keeps it around +// for clients that have "override" annotations on their subclass. These overrides +// should be deleted. +//#define SK_SUPPORT_LEGACY_GETDEVICECAPABILITIES + +//#define SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG class SkClipStack; class SkDraw; @@ -41,6 +49,7 @@ public: virtual ~SkBaseDevice(); +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG /** * Creates a device that is of the same type as this device (e.g. SW-raster, * GPU, or PDF). The backing store for this device is created automatically @@ -55,13 +64,17 @@ public: SkBaseDevice* createCompatibleDevice(SkBitmap::Config config, int width, int height, bool isOpaque); +#endif + SkBaseDevice* createCompatibleDevice(const SkImageInfo&); SkMetaData& getMetaData(); +#ifdef SK_SUPPORT_LEGACY_GETDEVICECAPABILITIES enum Capabilities { - kVector_Capability = 0x1, //!< mask indicating a vector representation + kVector_Capability = 0x1, }; - virtual uint32_t getDeviceCapabilities() = 0; + virtual uint32_t getDeviceCapabilities() { return 0; } +#endif /** Return the width of the device (in pixels). */ @@ -76,6 +89,12 @@ public: 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. + */ + virtual SkImageInfo imageInfo() const; + /** * Return the bounds of the device in the coordinate space of the root * canvas. The root device will have its top-left at 0,0, but other devices @@ -95,7 +114,6 @@ public: /** Return the bitmap config of the device's pixels */ - SK_ATTR_DEPRECATED("want to hide configness of the device -- don't use") virtual SkBitmap::Config config() const = 0; /** Return the bitmap associated with this device. Call this each time you need @@ -106,6 +124,7 @@ public: */ const SkBitmap& accessBitmap(bool changePixels); +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG /** * DEPRECATED: This will be made protected once WebKit stops using it. * Instead use Canvas' writePixels method. @@ -122,7 +141,12 @@ public: * not kARGB_8888_Config then this parameter is ignored. */ virtual void writePixels(const SkBitmap& bitmap, int x, int y, - SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888) = 0; + SkCanvas::Config8888 config8888 = SkCanvas::kNative_Premul_Config8888); +#endif + + bool writePixelsDirect(const SkImageInfo&, const void*, size_t rowBytes, int x, int y); + + void* accessPixels(SkImageInfo* info, size_t* rowBytes); /** * Return the device's associated gpu render target, or NULL. @@ -227,6 +251,10 @@ protected: virtual void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) = 0; + // Default impl calls drawPath() + virtual void drawDRRect(const SkDraw&, const SkRRect& outer, + const SkRRect& inner, const SkPaint&); + /** * If pathIsMutable, then the implementation is allowed to cast path to a * non-const pointer and modify it in place (as an optimization). Canvas @@ -274,7 +302,7 @@ protected: const uint16_t indices[], int indexCount, const SkPaint& paint) = 0; /** The SkDevice passed will be an SkDevice which was returned by a call to - onCreateCompatibleDevice on this device with kSaveLayer_Usage. + onCreateDevice on this device with kSaveLayer_Usage. */ virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) = 0; @@ -318,17 +346,6 @@ protected: */ virtual const SkBitmap& onAccessBitmap() = 0; - /** - * Implements readPixels API. The caller will ensure that: - * 1. bitmap has pixel config kARGB_8888_Config. - * 2. bitmap has pixels. - * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is - * contained in the device bounds. - */ - virtual bool onReadPixels(const SkBitmap& bitmap, - int x, int y, - SkCanvas::Config8888 config8888) = 0; - /** Called when this device is installed into a Canvas. Balanced by a call to unlockPixels() when the device is removed from a Canvas. */ @@ -359,7 +376,8 @@ protected: * If the device does not recognize or support this filter, * it just returns false and leaves result and offset unchanged. */ - virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkMatrix&, + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, + const SkImageFilter::Context& ctx, SkBitmap* result, SkIPoint* offset) = 0; // This is equal kBGRA_Premul_Config8888 or kRGBA_Premul_Config8888 if @@ -370,6 +388,33 @@ protected: // default impl returns NULL virtual SkSurface* newSurface(const SkImageInfo&); + // default impl returns NULL + virtual const void* peekPixels(SkImageInfo*, size_t* rowBytes); + + /** + * Implements readPixels API. The caller will ensure that: + * 1. bitmap has pixel config kARGB_8888_Config. + * 2. bitmap has pixels. + * 3. The rectangle (x, y, x + bitmap->width(), y + bitmap->height()) is + * contained in the device bounds. + */ + virtual bool onReadPixels(const SkBitmap& bitmap, + int x, int y, + SkCanvas::Config8888 config8888); + + /** + * The caller is responsible for "pre-clipping" the src. The impl can assume that the src + * image at the specified x,y offset will fit within the device's bounds. + * + * This is explicitly asserted in writePixelsDirect(), the public way to call this. + */ + 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); + /** * 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. @@ -378,6 +423,24 @@ protected: */ SkDeviceProperties fLeakyProperties; + /** + * PRIVATE / EXPERIMENTAL -- do not call + * Construct an acceleration object and attach it to 'picture' + */ + virtual void EXPERIMENTAL_optimize(SkPicture* picture); + + /** + * PRIVATE / EXPERIMENTAL -- do not call + * This entry point gives the backend an opportunity to take over the rendering + * of 'picture'. If optimization data is available (due to an earlier + * 'optimize' call) this entry point should make use of it and return true + * if all rendering has been done. If false is returned, SkCanvas will + * perform its own rendering pass. It is acceptable for the backend + * 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(const SkPicture& picture); + private: friend class SkCanvas; friend struct DeviceCM; //for setMatrixClip @@ -385,7 +448,7 @@ private: friend class SkDrawIter; friend class SkDeviceFilteredPaint; friend class SkDeviceImageFilterProxy; - friend class DeferredDevice; // for newSurface + friend class SkDeferredDevice; // for newSurface friend class SkSurface_Raster; @@ -398,17 +461,23 @@ private: // 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(SkBitmap::Config config, - int width, int height, - bool isOpaque); + SkBaseDevice* createCompatibleDeviceForSaveLayer(const SkImageInfo&); +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG /** - * Subclasses should override this to implement createCompatibleDevice. + * Justs exists during the period where clients still "override" this + * signature. They are supported by our base-impl calling this old + * signature from the new one (using ImageInfo). */ virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, int width, int height, - bool isOpaque, - Usage usage) = 0; + bool isOpaque, Usage) { + return NULL; + } +#endif + virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) { + return NULL; + } /** Causes any deferred drawing to the device to be completed. */ diff --git a/gfx/skia/trunk/include/core/SkDrawLooper.h b/gfx/skia/trunk/include/core/SkDrawLooper.h index 4609c1dcf90d..3c45a6a5b635 100644 --- a/gfx/skia/trunk/include/core/SkDrawLooper.h +++ b/gfx/skia/trunk/include/core/SkDrawLooper.h @@ -30,24 +30,49 @@ public: SK_DECLARE_INST_COUNT(SkDrawLooper) /** - * Called right before something is being drawn. This will be followed by - * calls to next() until next() returns false. + * Holds state during a draw. Users call next() until it returns false. + * + * Subclasses of SkDrawLooper should create a subclass of this object to + * hold state specific to their subclass. */ - virtual void init(SkCanvas*) = 0; + class SK_API Context : public SkNoncopyable { + public: + Context() {} + virtual ~Context() {} + + /** + * Called in a loop on objects returned by SkDrawLooper::createContext(). + * Each time true is returned, the object is drawn (possibly with a modified + * canvas and/or paint). When false is finally returned, drawing for the object + * stops. + * + * On each call, the paint will be in its original state, but the + * canvas will be as it was following the previous call to next() or + * createContext(). + * + * The implementation must ensure that, when next() finally returns + * false, the canvas has been restored to the state it was + * initially, before createContext() was first called. + */ + virtual bool next(SkCanvas* canvas, SkPaint* paint) = 0; + }; /** - * Called in a loop (after init()). Each time true is returned, the object - * is drawn (possibly with a modified canvas and/or paint). When false is - * finally returned, drawing for the object stops. - * - * On each call, the paint will be in its original state, but the canvas - * will be as it was following the previous call to next() or init(). - * - * The implementation must ensure that, when next() finally returns false, - * that the canvas has been restored to the state it was initially, before - * init() was first called. + * Called right before something is being drawn. Returns a Context + * whose next() method should be called until it returns false. + * The caller has to ensure that the storage pointer provides enough + * memory for the Context. The required size can be queried by calling + * contextSize(). It is also the caller's responsibility to destroy the + * object after use. */ - virtual bool next(SkCanvas*, SkPaint* paint) = 0; + virtual Context* createContext(SkCanvas*, void* storage) const = 0; + + /** + * Returns the number of bytes needed to store subclasses of Context (belonging to the + * corresponding SkDrawLooper subclass). + */ + virtual size_t contextSize() const = 0; + /** * The fast bounds functions are used to enable the paint to be culled early @@ -59,11 +84,11 @@ 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); + virtual bool canComputeFastBounds(const SkPaint& paint) const; virtual void computeFastBounds(const SkPaint& paint, - const SkRect& src, SkRect* dst); + const SkRect& src, SkRect* dst) const; - SkDEVCODE(virtual void toString(SkString* str) const = 0;) + SK_TO_STRING_PUREVIRT() SK_DEFINE_FLATTENABLE_TYPE(SkDrawLooper) protected: diff --git a/gfx/skia/trunk/include/core/SkEmptyShader.h b/gfx/skia/trunk/include/core/SkEmptyShader.h index 3f7dae41a9f4..d2ebb61221fe 100644 --- a/gfx/skia/trunk/include/core/SkEmptyShader.h +++ b/gfx/skia/trunk/include/core/SkEmptyShader.h @@ -30,7 +30,7 @@ public: virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader) protected: diff --git a/gfx/skia/trunk/include/core/SkGeometry.h b/gfx/skia/trunk/include/core/SkGeometry.h index d7836db735ea..119cfc68db54 100644 --- a/gfx/skia/trunk/include/core/SkGeometry.h +++ b/gfx/skia/trunk/include/core/SkGeometry.h @@ -255,6 +255,15 @@ struct SkConic { void computeTightBounds(SkRect* bounds) const; void computeFastBounds(SkRect* bounds) const; + + /** Find the parameter value where the conic takes on its maximum curvature. + * + * @param t output scalar for max curvature. Will be unchanged if + * max curvature outside 0..1 range. + * + * @return true if max curvature found inside 0..1 range, false otherwise + */ + bool findMaxCurvature(SkScalar* t) const; }; #include "SkTemplates.h" diff --git a/gfx/skia/trunk/include/core/SkImageFilter.h b/gfx/skia/trunk/include/core/SkImageFilter.h index a3e5a62ee505..0f52b69b84ba 100644 --- a/gfx/skia/trunk/include/core/SkImageFilter.h +++ b/gfx/skia/trunk/include/core/SkImageFilter.h @@ -9,12 +9,12 @@ #define SkImageFilter_DEFINED #include "SkFlattenable.h" +#include "SkMatrix.h" #include "SkRect.h" class SkBitmap; class SkColorFilter; class SkBaseDevice; -class SkMatrix; struct SkIPoint; class SkShader; class GrEffectRef; @@ -49,6 +49,18 @@ public: uint32_t fFlags; }; + class Context { + public: + Context(const SkMatrix& ctm, const SkIRect& clipBounds) : + fCTM(ctm), fClipBounds(clipBounds) { + } + const SkMatrix& ctm() const { return fCTM; } + const SkIRect& clipBounds() const { return fClipBounds; } + private: + SkMatrix fCTM; + SkIRect fClipBounds; + }; + class Proxy { public: virtual ~Proxy() {}; @@ -59,7 +71,7 @@ public: // 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 SkMatrix& ctm, + const Context&, SkBitmap* result, SkIPoint* offset) = 0; }; @@ -76,7 +88,7 @@ public: * If the result image cannot be created, return false, in which case both * the result and offset parameters will be ignored by the caller. */ - bool filterImage(Proxy*, const SkBitmap& src, const SkMatrix& ctm, + bool filterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const; /** @@ -104,7 +116,7 @@ public: * relative to the src when it is drawn. The default implementation does * single-pass processing using asNewEffect(). */ - virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const SkMatrix& ctm, + virtual bool filterImageGPU(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const; /** @@ -146,6 +158,20 @@ public: // Default impl returns union of all input bounds. virtual void computeFastBounds(const SkRect&, SkRect*) const; +#ifdef 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; +#endif + SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter) protected: @@ -186,7 +212,7 @@ protected: * case both the result and offset parameters will be ignored by the * caller. */ - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const; // Given the bounds of the destination rect to be filled in device // coordinates (first parameter), and the CTM, compute (conservatively) @@ -197,10 +223,25 @@ protected: // no inputs. virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const; - // Applies "matrix" to the crop rect, and sets "rect" to the intersection of - // "rect" and the transformed crop rect. If there is no overlap, returns - // false and leaves "rect" unchanged. - bool applyCropRect(SkIRect* rect, const SkMatrix& matrix) 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. + */ + bool applyCropRect(const Context&, const SkBitmap& src, const SkIPoint& srcOffset, + SkIRect* bounds) 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 + * bitmap in "result" and pads the edges with transparent black. In that + * case, the srcOffset is modified to be the same as the bounds, since no + * further adjustment is needed by the caller. This version should only + * be used by filters which are not capable of processing a smaller + * source bitmap into a larger destination. + */ + bool applyCropRect(const Context&, Proxy* proxy, const SkBitmap& src, SkIPoint* srcOffset, + SkIRect* bounds, SkBitmap* result) const; /** * Returns true if the filter can be expressed a single-pass @@ -222,6 +263,7 @@ protected: const SkMatrix& matrix, const SkIRect& bounds) const; + private: typedef SkFlattenable INHERITED; int fInputCount; diff --git a/gfx/skia/trunk/include/core/SkImageFilterUtils.h b/gfx/skia/trunk/include/core/SkImageFilterUtils.h deleted file mode 100644 index b533c3bca25e..000000000000 --- a/gfx/skia/trunk/include/core/SkImageFilterUtils.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2013 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 SkImageFilterUtils_DEFINED -#define SkImageFilterUtils_DEFINED - -#if SK_SUPPORT_GPU - -#include "SkImageFilter.h" - -class SkBitmap; -class GrTexture; -class SkImageFilter; - -class SK_API SkImageFilterUtils { -public: - /** - * Wrap the given texture in a texture-backed SkBitmap. - */ - static bool WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result); - - /** - * Recursively evaluate the given filter on the GPU. If filter is NULL, - * this function returns src. If the filter has no GPU implementation, it - * will be processed in software and uploaded to the GPU. - */ - static bool GetInputResultGPU(const SkImageFilter* filter, SkImageFilter::Proxy* proxy, - const SkBitmap& src, const SkMatrix& ctm, SkBitmap* result, - SkIPoint* offset); -}; - -#endif - -#endif diff --git a/gfx/skia/trunk/include/core/SkImageInfo.h b/gfx/skia/trunk/include/core/SkImageInfo.h index 2b449dc2132c..1c73d959af54 100644 --- a/gfx/skia/trunk/include/core/SkImageInfo.h +++ b/gfx/skia/trunk/include/core/SkImageInfo.h @@ -165,6 +165,13 @@ struct SkImageInfo { return info; } + static SkImageInfo MakeUnknown(int width, int height) { + SkImageInfo info = { + width, height, kUnknown_SkColorType, kIgnore_SkAlphaType + }; + return info; + } + int width() const { return fWidth; } int height() const { return fHeight; } SkColorType colorType() const { return fColorType; } diff --git a/gfx/skia/trunk/include/core/SkMaskFilter.h b/gfx/skia/trunk/include/core/SkMaskFilter.h index b47e034e3cd6..3113c9344276 100644 --- a/gfx/skia/trunk/include/core/SkMaskFilter.h +++ b/gfx/skia/trunk/include/core/SkMaskFilter.h @@ -40,8 +40,6 @@ class SK_API SkMaskFilter : public SkFlattenable { public: SK_DECLARE_INST_COUNT(SkMaskFilter) - SkMaskFilter() {} - /** Returns the format of the resulting mask that this subclass will return when its filterMask() method is called. */ @@ -103,6 +101,14 @@ public: GrPaint* grp, 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, + GrPaint* grp, + const SkStrokeRec& strokeRec, + const SkRRect& rrect) const; /** * This function is used to implement filters that require an explicit src mask. It should only @@ -132,10 +138,11 @@ public: */ virtual void computeFastBounds(const SkRect& src, SkRect* dest) const; - SkDEVCODE(virtual void toString(SkString* str) const = 0;) + SK_TO_STRING_PUREVIRT() SK_DEFINE_FLATTENABLE_TYPE(SkMaskFilter) protected: + SkMaskFilter() {} // empty for now, but lets get our subclass to remember to init us for the future SkMaskFilter(SkReadBuffer& buffer) : INHERITED(buffer) {} diff --git a/gfx/skia/trunk/include/core/SkMatrix.h b/gfx/skia/trunk/include/core/SkMatrix.h index 9bbbc1745b3d..d7c163d439ed 100644 --- a/gfx/skia/trunk/include/core/SkMatrix.h +++ b/gfx/skia/trunk/include/core/SkMatrix.h @@ -560,7 +560,7 @@ public: size_t readFromMemory(const void* buffer, size_t length); SkDEVCODE(void dump() const;) - SkDEVCODE(void toString(SkString*) const;) + SK_TO_STRING_NONVIRT() /** * Calculates the minimum stretching factor of the matrix. If the matrix has diff --git a/gfx/skia/trunk/include/core/SkPaint.h b/gfx/skia/trunk/include/core/SkPaint.h index abb859950c5b..d1853c613c35 100644 --- a/gfx/skia/trunk/include/core/SkPaint.h +++ b/gfx/skia/trunk/include/core/SkPaint.h @@ -118,6 +118,8 @@ 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. @@ -284,6 +286,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, @@ -731,17 +746,60 @@ public: void setTextEncoding(TextEncoding encoding); struct FontMetrics { + /** Flags which indicate the confidence level of various metrics. + A set flag indicates that the metric may be trusted. + */ + enum FontMetricsFlags { + kUnderlineThinknessIsValid_Flag = 1 << 0, + kUnderlinePositionIsValid_Flag = 1 << 1, + }; + + uint32_t fFlags; //!< Bit field to identify which values are unknown SkScalar fTop; //!< The greatest distance above the baseline for any glyph (will be <= 0) SkScalar fAscent; //!< The recommended distance above the baseline (will be <= 0) SkScalar fDescent; //!< The recommended distance below the baseline (will be >= 0) SkScalar fBottom; //!< The greatest distance below the baseline for any glyph (will be >= 0) SkScalar fLeading; //!< The recommended distance to add between lines of text (will be >= 0) - SkScalar fAvgCharWidth; //!< the average charactor width (>= 0) - SkScalar fMaxCharWidth; //!< the max charactor width (>= 0) + SkScalar fAvgCharWidth; //!< the average character width (>= 0) + SkScalar fMaxCharWidth; //!< the max character width (>= 0) SkScalar fXMin; //!< The minimum bounding box x value for all glyphs SkScalar fXMax; //!< The maximum bounding box x value for all glyphs SkScalar fXHeight; //!< The height of an 'x' in px, or 0 if no 'x' in face SkScalar fCapHeight; //!< The cap height (> 0), or 0 if cannot be determined. + SkScalar fUnderlineThickness; //!< underline thickness, or 0 if cannot be determined + + /** Underline Position - position of the top of the Underline stroke + relative to the baseline, this can have following values + - Negative - means underline should be drawn above baseline. + - Positive - means below baseline. + - Zero - mean underline should be drawn on baseline. + */ + SkScalar fUnderlinePosition; //!< underline position, or 0 if cannot be determined + + /** If the fontmetrics has a valid underlinethickness, return true, and set the + thickness param to that value. If it doesn't return false and ignore the + thickness param. + */ + bool hasUnderlineThickness(SkScalar* thickness) const { + if (SkToBool(fFlags & kUnderlineThinknessIsValid_Flag)) { + *thickness = fUnderlineThickness; + return true; + } + return false; + } + + /** If the fontmetrics has a valid underlineposition, return true, and set the + thickness param to that value. If it doesn't return false and ignore the + thickness param. + */ + bool hasUnderlinePosition(SkScalar* position) const { + if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) { + *position = fUnderlinePosition; + return true; + } + return false; + } + }; /** Return the recommend spacing between lines (which will be @@ -880,10 +938,6 @@ public: const SkPoint pos[], SkPath* path) const; #ifdef SK_BUILD_FOR_ANDROID - const SkGlyph& getUnicharMetrics(SkUnichar, const SkMatrix*); - const SkGlyph& getGlyphMetrics(uint16_t, const SkMatrix*); - const void* findImage(const SkGlyph&, const SkMatrix*); - uint32_t getGenerationID() const; void setGenerationID(uint32_t generationID); @@ -978,7 +1032,12 @@ public: return SetTextMatrix(matrix, fTextSize, fTextScaleX, fTextSkewX); } - SkDEVCODE(void toString(SkString*) const;) + SK_TO_STRING_NONVIRT() + + struct FlatteningTraits { + static void Flatten(SkWriteBuffer& buffer, const SkPaint& paint); + static void Unflatten(SkReadBuffer& buffer, SkPaint* paint); + }; private: SkTypeface* fTypeface; @@ -999,16 +1058,25 @@ private: SkColor fColor; SkScalar fWidth; SkScalar fMiterLimit; - // all of these bitfields should add up to 32 - unsigned fFlags : 16; - unsigned fTextAlign : 2; - unsigned fCapType : 2; - unsigned fJoinType : 2; - unsigned fStyle : 2; - unsigned fTextEncoding : 2; // 3 values - unsigned fHinting : 2; - //unsigned fFreeBits : 4; + union { + struct { + // all of these bitfields should add up to 32 + unsigned fFlags : 16; + unsigned fTextAlign : 2; + unsigned fCapType : 2; + unsigned fJoinType : 2; + unsigned fStyle : 2; + unsigned fTextEncoding : 2; // 3 values + unsigned fHinting : 2; + //unsigned fFreeBits : 4; + }; + uint32_t fBitfields; + }; + uint32_t getBitfields() const { return fBitfields; } + void setBitfields(uint32_t bitfields); + + uint32_t fDirtyBits; SkDrawCacheProc getDrawCacheProc() const; SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir, diff --git a/gfx/skia/trunk/include/core/SkPathEffect.h b/gfx/skia/trunk/include/core/SkPathEffect.h index 3f38f3a101a5..86ccf86a9223 100644 --- a/gfx/skia/trunk/include/core/SkPathEffect.h +++ b/gfx/skia/trunk/include/core/SkPathEffect.h @@ -31,8 +31,6 @@ class SK_API SkPathEffect : public SkFlattenable { public: SK_DECLARE_INST_COUNT(SkPathEffect) - 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 @@ -109,6 +107,7 @@ public: SK_DEFINE_FLATTENABLE_TYPE(SkPathEffect) protected: + SkPathEffect() {} SkPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {} private: @@ -127,10 +126,10 @@ private: */ class SkPairPathEffect : public SkPathEffect { public: - SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1); virtual ~SkPairPathEffect(); protected: + SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1); SkPairPathEffect(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; @@ -153,8 +152,9 @@ public: The reference counts for outer and inner are both incremented in the constructor, and decremented in the destructor. */ - SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner) - : INHERITED(outer, inner) {} + static SkComposePathEffect* Create(SkPathEffect* outer, SkPathEffect* inner) { + return SkNEW_ARGS(SkComposePathEffect, (outer, inner)); + } virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const SK_OVERRIDE; @@ -164,6 +164,12 @@ public: protected: SkComposePathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {} +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkComposePathEffect(SkPathEffect* outer, SkPathEffect* inner) + : INHERITED(outer, inner) {} + private: // illegal SkComposePathEffect(const SkComposePathEffect&); @@ -184,8 +190,9 @@ public: The reference counts for first and second are both incremented in the constructor, and decremented in the destructor. */ - SkSumPathEffect(SkPathEffect* first, SkPathEffect* second) - : INHERITED(first, second) {} + static SkSumPathEffect* Create(SkPathEffect* first, SkPathEffect* second) { + return SkNEW_ARGS(SkSumPathEffect, (first, second)); + } virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const SK_OVERRIDE; @@ -195,6 +202,12 @@ public: protected: SkSumPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {} +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkSumPathEffect(SkPathEffect* first, SkPathEffect* second) + : INHERITED(first, second) {} + private: // illegal SkSumPathEffect(const SkSumPathEffect&); diff --git a/gfx/skia/trunk/include/core/SkPicture.h b/gfx/skia/trunk/include/core/SkPicture.h index a717153dbed9..3718d3a579b5 100644 --- a/gfx/skia/trunk/include/core/SkPicture.h +++ b/gfx/skia/trunk/include/core/SkPicture.h @@ -34,6 +34,27 @@ 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; + }; + /** The constructor prepares the picture to record. @param width the width of the virtual device the picture records. @param height the height of the virtual device the picture records. @@ -44,6 +65,18 @@ public: */ SkPicture(const SkPicture& src); + /** PRIVATE / EXPERIMENTAL -- do not call */ + void EXPERIMENTAL_addAccelData(const AccelData* data) { + SkRefCnt_SafeAssign(fAccelData, data); + } + /** PRIVATE / EXPERIMENTAL -- do not call */ + const AccelData* EXPERIMENTAL_getAccelData(AccelData::Key key) const { + if (NULL != fAccelData && fAccelData->getKey() == key) { + return fAccelData; + } + return NULL; + } + /** * Function signature defining a function that sets up an SkBitmap from encoded data. On * success, the SkBitmap should have its Config, width, height, rowBytes and pixelref set. @@ -125,15 +158,6 @@ public: discarded if you serialize into a stream and then deserialize. */ kOptimizeForClippedPlayback_RecordingFlag = 0x02, - /* - This flag disables 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). This - option doesn't affect the optimizations controlled by - 'kOptimizeForClippedPlayback_RecordingFlag'. - */ - kDisableRecordOptimizations_RecordingFlag = 0x04 }; /** Returns the canvas that records the drawing commands. @@ -217,6 +241,25 @@ public: void abortPlayback(); #endif + /** Return true if the SkStream/Buffer represents a serialized picture, and + fills out SkPictInfo. After this function returns, the data source is not + rewound so it will have to be manually reset before passing to + CreateFromStream or CreateFromBuffer. Note, CreateFromStream and + CreateFromBuffer perform this check internally so these entry points are + intended for stand alone tools. + If false is returned, SkPictInfo is unmodified. + */ + static bool InternalOnly_StreamIsSKP(SkStream*, SkPictInfo*); + static bool InternalOnly_BufferIsSKP(SkReadBuffer&, SkPictInfo*); + + /** 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); + protected: // V2 : adds SkPixelRef's generation ID. // V3 : PictInfo tag at beginning, and EOF tag at the end @@ -239,14 +282,23 @@ protected: // 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) - static const uint32_t PICTURE_VERSION = 20; + // V21: add pushCull, popCull + // V22: SK_PICT_FACTORY_TAG's size is now the chunk size in bytes + + // 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 + + // 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 = 22; // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to // install their own SkPicturePlayback-derived players,SkPictureRecord-derived // recorders and set the picture size - SkPicturePlayback* fPlayback; - SkPictureRecord* fRecord; - int fWidth, fHeight; + SkPicturePlayback* fPlayback; + SkPictureRecord* fRecord; + int fWidth, fHeight; + const AccelData* fAccelData; // Create a new SkPicture from an existing SkPicturePlayback. Ref count of // playback is unchanged. @@ -255,15 +307,9 @@ protected: // For testing. Derived classes may instantiate an alternate // SkBBoxHierarchy implementation virtual SkBBoxHierarchy* createBBoxHierarchy() const; - - // Return true if the SkStream represents a serialized picture, and fills out - // SkPictInfo. After this function returns, the SkStream is not rewound; it - // will be ready to be parsed to create an SkPicturePlayback. - // If false is returned, SkPictInfo is unmodified. - static bool StreamIsSKP(SkStream*, SkPictInfo*); - static bool BufferIsSKP(SkReadBuffer&, SkPictInfo*); private: - void createHeader(void* header) const; + void createHeader(SkPictInfo* info) const; + static bool IsValidPictInfo(const SkPictInfo& info); friend class SkFlatPicture; friend class SkPicturePlayback; diff --git a/gfx/skia/trunk/include/core/SkPreConfig.h b/gfx/skia/trunk/include/core/SkPreConfig.h index 1c2e24fba657..406a159d8916 100644 --- a/gfx/skia/trunk/include/core/SkPreConfig.h +++ b/gfx/skia/trunk/include/core/SkPreConfig.h @@ -116,40 +116,30 @@ // Are we in GCC? #ifndef SK_CPU_SSE_LEVEL - #if defined(__SSE2__) - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 + // These checks must be done in descending order to ensure we set the highest + // available SSE level. + #if defined(__SSSE3__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3 #elif defined(__SSE3__) #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3 - #elif defined(__SSSE3__) - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSSE3 + #elif defined(__SSE2__) + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 #endif #endif // Are we in VisualStudio? #ifndef SK_CPU_SSE_LEVEL + // These checks must be done in descending order to ensure we set the highest + // available SSE level. #if defined (_M_IX86_FP) - #if _M_IX86_FP == 1 - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1 - #elif _M_IX86_FP >= 2 + #if _M_IX86_FP >= 2 #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 + #elif _M_IX86_FP == 1 + #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE1 #endif #endif #endif -// 64bit intel guarantees at least SSE2 -#if defined(__x86_64__) || defined(_WIN64) - #if !defined(SK_CPU_SSE_LEVEL) || (SK_CPU_SSE_LEVEL < SK_CPU_SSE_LEVEL_SSE2) - #undef SK_CPU_SSE_LEVEL - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE2 - #endif -#endif - -// Android x86 NDK ABI requires SSE3 support -#if defined(SK_BUILD_FOR_ANDROID) - #undef SK_CPU_SSE_LEVEL - #define SK_CPU_SSE_LEVEL SK_CPU_SSE_LEVEL_SSE3 -#endif - ////////////////////////////////////////////////////////////////////// // ARM defines diff --git a/gfx/skia/trunk/include/core/SkRRect.h b/gfx/skia/trunk/include/core/SkRRect.h index 66c433f43b8d..c09d2d46fe85 100644 --- a/gfx/skia/trunk/include/core/SkRRect.h +++ b/gfx/skia/trunk/include/core/SkRRect.h @@ -26,15 +26,9 @@ class SkMatrix; // use growToInclude to fit skp round rects & generate stats (RRs vs. real paths) // check on # of rectorus's the RRs could handle // rendering work -// add entry points (clipRRect, drawRRect) - plumb down to SkBaseDevice -// update SkPath.addRRect() to take an SkRRect - only use quads -// -- alternatively add addRRectToPath here +// update SkPath.addRRect() to only use quads // add GM and bench -// clipping opt -// update SkClipStack to perform logic with RRs // further out -// add RR rendering shader to Ganesh (akin to cicle drawing code) -// - only for simple RRs // detect and triangulate RRectorii rather than falling back to SW in Ganesh // @@ -102,8 +96,24 @@ 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(); } + inline bool isSimpleCircular() const { + return this->isSimple() && fRadii[0].fX == fRadii[0].fY; + } inline bool isComplex() const { return kComplex_Type == this->getType(); } + bool allCornersCircular() const; + + /** + * Are both x-radii the same on the two left corners, and similar for the top, right, and + * bottom. When this is the case the four ellipse centers form a rectangle. + */ + bool isNinePatch() const { + return fRadii[kUpperLeft_Corner].fX == fRadii[kLowerLeft_Corner].fX && + fRadii[kUpperRight_Corner].fX == fRadii[kLowerRight_Corner].fX && + fRadii[kUpperLeft_Corner].fY == fRadii[kUpperRight_Corner].fY && + fRadii[kLowerLeft_Corner].fY == fRadii[kLowerRight_Corner].fY; + } + SkScalar width() const { return fRect.width(); } SkScalar height() const { return fRect.height(); } @@ -228,6 +238,13 @@ public: this->inset(-dx, -dy, this); } + /** + * Translate the rrect by (dx, dy). + */ + void offset(SkScalar dx, SkScalar dy) { + fRect.offset(dx, dy); + } + /** * Returns true if 'rect' is wholy inside the RR, and both * are not empty. diff --git a/gfx/skia/trunk/include/core/SkRasterizer.h b/gfx/skia/trunk/include/core/SkRasterizer.h index d916b231b7ac..d6e514c26321 100644 --- a/gfx/skia/trunk/include/core/SkRasterizer.h +++ b/gfx/skia/trunk/include/core/SkRasterizer.h @@ -22,8 +22,6 @@ class SK_API SkRasterizer : public SkFlattenable { public: SK_DECLARE_INST_COUNT(SkRasterizer) - SkRasterizer() {} - /** Turn the path into a mask, respecting the specified local->device matrix. */ bool rasterize(const SkPath& path, const SkMatrix& matrix, @@ -33,6 +31,7 @@ public: SK_DEFINE_FLATTENABLE_TYPE(SkRasterizer) protected: + SkRasterizer() {} SkRasterizer(SkReadBuffer& buffer) : INHERITED(buffer) {} virtual bool onRasterize(const SkPath& path, const SkMatrix& matrix, diff --git a/gfx/skia/trunk/include/core/SkReadBuffer.h b/gfx/skia/trunk/include/core/SkReadBuffer.h index 75cc64b2be19..dd3301ec133b 100644 --- a/gfx/skia/trunk/include/core/SkReadBuffer.h +++ b/gfx/skia/trunk/include/core/SkReadBuffer.h @@ -177,12 +177,14 @@ public: virtual bool isValid() const { return true; } virtual bool validateAvailable(size_t size) { return true; } +protected: + SkReader32 fReader; + private: bool readArray(void* value, size_t size, size_t elementSize); uint32_t fFlags; - SkReader32 fReader; void* fMemoryPtr; SkBitmapHeapReader* fBitmapStorage; diff --git a/gfx/skia/trunk/include/core/SkScalarCompare.h b/gfx/skia/trunk/include/core/SkScalarCompare.h deleted file mode 100644 index 5361294f9a66..000000000000 --- a/gfx/skia/trunk/include/core/SkScalarCompare.h +++ /dev/null @@ -1,38 +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 SkScalarCompare_DEFINED -#define SkScalarCompare_DEFINED - -#include "SkFloatBits.h" -#include "SkRect.h" - -/** Skia can spend a lot of time just comparing scalars (e.g. quickReject). - When scalar==fixed, this is very fast, and when scalar==hardware-float, this - is also reasonable, but if scalar==software-float, then each compare can be - a function call and take real time. To account for that, we have the flag - SK_SCALAR_SLOW_COMPARES. - - If this is defined, we have a special trick where we quickly convert floats - to a 2's compliment form, and then treat them as signed 32bit integers. In - this form we lose a few subtlties (e.g. NaNs always comparing false) but - we gain the speed of integer compares. - */ - -#ifdef SK_SCALAR_SLOW_COMPARES - typedef int32_t SkScalarCompareType; - typedef SkIRect SkRectCompareType; - #define SkScalarToCompareType(x) SkScalarAs2sCompliment(x) -#else - typedef SkScalar SkScalarCompareType; - typedef SkRect SkRectCompareType; - #define SkScalarToCompareType(x) (x) -#endif - -#endif diff --git a/gfx/skia/trunk/include/core/SkShader.h b/gfx/skia/trunk/include/core/SkShader.h index da23a20a4b5e..acff959949ba 100644 --- a/gfx/skia/trunk/include/core/SkShader.h +++ b/gfx/skia/trunk/include/core/SkShader.h @@ -345,8 +345,7 @@ public: static SkShader* CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy); - SkDEVCODE(virtual void toString(SkString* str) const;) - + SK_TO_STRING_VIRT() SK_DEFINE_FLATTENABLE_TYPE(SkShader) protected: @@ -371,10 +370,6 @@ private: uint8_t fTotalInverseClass; SkDEBUGCODE(SkBool8 fInSetContext;) - static SkShader* CreateBitmapShader(const SkBitmap& src, - TileMode, TileMode, - void* storage, size_t storageSize); - friend class SkAutoBitmapShaderInstall; typedef SkFlattenable INHERITED; }; diff --git a/gfx/skia/trunk/include/core/SkStream.h b/gfx/skia/trunk/include/core/SkStream.h index 50ed691e5ae4..516b036a55e6 100644 --- a/gfx/skia/trunk/include/core/SkStream.h +++ b/gfx/skia/trunk/include/core/SkStream.h @@ -189,6 +189,8 @@ public: virtual void newline(); virtual void flush(); + virtual size_t bytesWritten() const = 0; + // helpers bool write8(U8CPU); @@ -205,7 +207,7 @@ public: bool writeScalar(SkScalar); bool writePackedUInt(size_t); - bool writeStream(SkStream* input, size_t length); + bool writeStream(SkStream* input, size_t length); /** * Append an SkData object to the stream, such that it can be read @@ -216,6 +218,12 @@ public: * 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'. + */ + static int SizeOfPackedUInt(size_t value); }; //////////////////////////////////////////////////////////////////////////////////////// @@ -365,6 +373,7 @@ public: virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; virtual void flush() SK_OVERRIDE; + virtual size_t bytesWritten() const SK_OVERRIDE; private: SkFILE* fFILE; @@ -378,7 +387,7 @@ public: SkMemoryWStream(void* buffer, size_t size); virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; - size_t bytesWritten() const { return fBytesWritten; } + virtual size_t bytesWritten() const SK_OVERRIDE { return fBytesWritten; } private: char* fBuffer; @@ -396,12 +405,12 @@ public: virtual ~SkDynamicMemoryWStream(); virtual bool write(const void* buffer, size_t size) SK_OVERRIDE; + virtual size_t bytesWritten() const SK_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); bool read(void* buffer, size_t offset, size_t size); size_t getOffset() const { return fBytesWritten; } - size_t bytesWritten() const { return fBytesWritten; } // copy what has been written to the stream into dst void copyTo(void* dst) const; @@ -437,13 +446,16 @@ 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; } private: + size_t fBytesWritten; typedef SkWStream INHERITED; }; diff --git a/gfx/skia/trunk/include/core/SkSurface.h b/gfx/skia/trunk/include/core/SkSurface.h index 2f277b755df7..8e430d8f47d2 100644 --- a/gfx/skia/trunk/include/core/SkSurface.h +++ b/gfx/skia/trunk/include/core/SkSurface.h @@ -52,10 +52,7 @@ public: * pixels in SkPMColor format. */ static SkSurface* NewRasterPMColor(int width, int height) { - SkImageInfo info = { - width, height, kPMColor_SkColorType, kPremul_SkAlphaType - }; - return NewRaster(info); + return NewRaster(SkImageInfo::MakeN32Premul(width, height)); } /** @@ -151,6 +148,18 @@ public: */ void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*); + /** + * If the surface 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 + * the ImageInfo and rowBytes. The returned address is only valid while + * the surface object is in scope, and no API call is made on the surface + * or its canvas. + * + * On failure, returns NULL and the info and rowBytes parameters are + * ignored. + */ + const void* peekPixels(SkImageInfo* info, size_t* rowBytes); + protected: SkSurface(int width, int height); SkSurface(const SkImageInfo&); diff --git a/gfx/skia/trunk/include/core/SkTDArray.h b/gfx/skia/trunk/include/core/SkTDArray.h index 804b84f669df..ecbfbd90e99f 100644 --- a/gfx/skia/trunk/include/core/SkTDArray.h +++ b/gfx/skia/trunk/include/core/SkTDArray.h @@ -158,7 +158,6 @@ public: * It will never shrink the shrink the storage. */ void setCount(int count) { - // TODO(mtklein): eliminate this method, setCountExact -> setCount SkASSERT(count >= 0); if (count > fReserve) { this->resizeStorageToAtLeast(count); @@ -166,20 +165,6 @@ public: fCount = count; } - /** - * 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 exactly the amount required, with no remaining - * reserved space. - * It will never shrink the shrink the storage. - */ - void setCountExact(int count) { - if (count > fReserve) { - this->resizeStorageToExact(count); - } - fCount = count; - } - void setReserve(int reserve) { if (reserve > fReserve) { this->resizeStorageToAtLeast(reserve); @@ -382,22 +367,6 @@ private: this->setCount(fCount + delta); } - /** - * This resizes the storage to *exactly* count elements, growing or - * shrinking the allocation as needed. It does not ASSERT anything about - * the previous allocation size, or about fCount. - * - * note: does NOT modify fCount - */ - void resizeStorageToExact(int count) { - SkASSERT(count >= 0); - fArray = (T*)sk_realloc_throw(fArray, count * sizeof(T)); -#ifdef SK_DEBUG - fData = (ArrayT*)fArray; -#endif - fReserve = count; - } - /** * Increase the storage allocation such that it can hold (fCount + extra) * elements. @@ -408,9 +377,12 @@ private: */ void resizeStorageToAtLeast(int count) { SkASSERT(count > fReserve); - int space = count + 4; - space += space>>2; - this->resizeStorageToExact(space); + 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/trunk/include/core/SkTLazy.h b/gfx/skia/trunk/include/core/SkTLazy.h index 2147b6681fa6..a291e22a1376 100644 --- a/gfx/skia/trunk/include/core/SkTLazy.h +++ b/gfx/skia/trunk/include/core/SkTLazy.h @@ -74,6 +74,16 @@ public: return fPtr; } + /** + * Destroy the lazy object (if it was created via init() or set()) + */ + void reset() { + if (this->isValid()) { + fPtr->~T(); + fPtr = NULL; + } + } + /** * Returns true if a valid object has been initialized in the SkTLazy, * false otherwise. diff --git a/gfx/skia/trunk/include/core/SkTemplates.h b/gfx/skia/trunk/include/core/SkTemplates.h index a3a846600a9e..4bcaf3f7b3bd 100644 --- a/gfx/skia/trunk/include/core/SkTemplates.h +++ b/gfx/skia/trunk/include/core/SkTemplates.h @@ -11,6 +11,8 @@ #define SkTemplates_DEFINED #include "SkTypes.h" +#include +#include #include /** \file SkTemplates.h @@ -64,6 +66,15 @@ template static D* SkTAddOffset(S* ptr, size_t byteOffs ); } +/** SkTSetBit::value is a T with the Nth bit set. */ +template struct SkTSetBit { + static const T value = static_cast(1) << N; + SK_COMPILE_ASSERT(sizeof(T)*CHAR_BIT > N, SkTSetBit_N_too_large); + SK_COMPILE_ASSERT(std::numeric_limits::is_integer, SkTSetBit_T_must_be_integer); + SK_COMPILE_ASSERT(!std::numeric_limits::is_signed, SkTSetBit_T_must_be_unsigned); + SK_COMPILE_ASSERT(std::numeric_limits::radix == 2, SkTSetBit_T_radix_must_be_2); +}; + /** \class SkAutoTCallVProc Call a function when this goes out of scope. The template uses two diff --git a/gfx/skia/trunk/include/core/SkThread_platform.h b/gfx/skia/trunk/include/core/SkThread_platform.h deleted file mode 100644 index 7df778cb5e57..000000000000 --- a/gfx/skia/trunk/include/core/SkThread_platform.h +++ /dev/null @@ -1,194 +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_platform_DEFINED -#define SkThread_platform_DEFINED - -#if defined(SK_BUILD_FOR_ANDROID) - -#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) - -#include - -/* Just use the GCC atomic intrinsics. They're supported by the NDK toolchain, - * have reasonable performance, and provide full memory barriers - */ -static inline __attribute__((always_inline)) int32_t sk_atomic_inc(int32_t *addr) { - return __sync_fetch_and_add(addr, 1); -} - -static inline __attribute__((always_inline)) int32_t sk_atomic_add(int32_t *addr, int32_t inc) { - return __sync_fetch_and_add(addr, inc); -} - -static inline __attribute__((always_inline)) int32_t sk_atomic_dec(int32_t *addr) { - return __sync_fetch_and_add(addr, -1); -} -static inline __attribute__((always_inline)) void sk_membar_aquire__after_atomic_dec() { } - -static inline __attribute__((always_inline)) int32_t sk_atomic_conditional_inc(int32_t* addr) { - int32_t value = *addr; - - while (true) { - if (value == 0) { - return 0; - } - - int32_t before = __sync_val_compare_and_swap(addr, value, value + 1); - - if (before == value) { - return value; - } else { - value = before; - } - } -} -static inline __attribute__((always_inline)) void sk_membar_aquire__after_atomic_conditional_inc() { } - -#else // SK_BUILD_FOR_ANDROID_FRAMEWORK - -/* The platform atomics operations are slightly more efficient than the - * GCC built-ins, so use them. - */ -#include - -#define sk_atomic_inc(addr) android_atomic_inc(addr) -#define sk_atomic_add(addr, inc) android_atomic_add(inc, addr) -#define sk_atomic_dec(addr) android_atomic_dec(addr) - -static inline __attribute__((always_inline)) void sk_membar_aquire__after_atomic_dec() { - //HACK: Android is actually using full memory barriers. - // Should this change, uncomment below. - //int dummy; - //android_atomic_aquire_store(0, &dummy); -} -static inline __attribute__((always_inline)) int32_t sk_atomic_conditional_inc(int32_t* addr) { - while (true) { - int32_t value = *addr; - if (value == 0) { - return 0; - } - if (0 == android_atomic_release_cas(value, value + 1, addr)) { - return value; - } - } -} -static inline __attribute__((always_inline)) void sk_membar_aquire__after_atomic_conditional_inc() { - //HACK: Android is actually using full memory barriers. - // Should this change, uncomment below. - //int dummy; - //android_atomic_aquire_store(0, &dummy); -} - -#endif // SK_BUILD_FOR_ANDROID_FRAMEWORK - -#else // !SK_BUILD_FOR_ANDROID - -/** Implemented by the porting layer, this function adds one to the int - specified by the address (in a thread-safe manner), and returns the - previous value. - No additional memory barrier is required. - This must act as a compiler barrier. -*/ -SK_API int32_t sk_atomic_inc(int32_t* addr); - -/** Implemented by the porting layer, this function adds inc to the int - specified by the address (in a thread-safe manner), and returns the - previous value. - No additional memory barrier is required. - This must act as a compiler barrier. - */ -SK_API int32_t sk_atomic_add(int32_t* addr, int32_t inc); - -/** Implemented by the porting layer, this function subtracts one from the int - specified by the address (in a thread-safe manner), and returns the - previous value. - Expected to act as a release (SL/S) memory barrier and a compiler barrier. -*/ -SK_API int32_t sk_atomic_dec(int32_t* addr); -/** If sk_atomic_dec does not act as an aquire (L/SL) barrier, this is expected - to act as an aquire (L/SL) memory barrier and as a compiler barrier. -*/ -SK_API void sk_membar_aquire__after_atomic_dec(); - -/** Implemented by the porting layer, this function adds one to the int - specified by the address iff the int specified by the address is not zero - (in a thread-safe manner), and returns the previous value. - No additional memory barrier is required. - This must act as a compiler barrier. -*/ -SK_API int32_t sk_atomic_conditional_inc(int32_t*); -/** If sk_atomic_conditional_inc does not act as an aquire (L/SL) barrier, this - is expected to act as an aquire (L/SL) memory barrier and as a compiler - barrier. -*/ -SK_API void sk_membar_aquire__after_atomic_conditional_inc(); - -#endif // !SK_BUILD_FOR_ANDROID - -#ifdef SK_USE_POSIX_THREADS - -#include - -// A SkBaseMutex is a POD structure that can be directly initialized -// at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the -// generation of a static initializer in the final machine code (and -// a corresponding static finalizer). -// -struct SkBaseMutex { - void acquire() { pthread_mutex_lock(&fMutex); } - void release() { pthread_mutex_unlock(&fMutex); } - pthread_mutex_t fMutex; -}; - -// Using POD-style initialization prevents the generation of a static initializer -// and keeps the acquire() implementation small and fast. -#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } - -// Special case used when the static mutex must be available globally. -#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name = { PTHREAD_MUTEX_INITIALIZER } - -// A normal mutex that requires to be initialized through normal C++ construction, -// i.e. when it's a member of another class, or allocated on the heap. -class SK_API SkMutex : public SkBaseMutex, SkNoncopyable { -public: - SkMutex(); - ~SkMutex(); -}; - -#else // !SK_USE_POSIX_THREADS - -// In the generic case, SkBaseMutex and SkMutex are the same thing, and we -// can't easily get rid of static initializers. -// -class SK_API SkMutex : SkNoncopyable { -public: - SkMutex(); - ~SkMutex(); - - void acquire(); - void release(); - -private: - bool fIsGlobal; - enum { - kStorageIntCount = 64 - }; - uint32_t fStorage[kStorageIntCount]; -}; - -typedef SkMutex SkBaseMutex; - -#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name -#define SK_DECLARE_GLOBAL_MUTEX(name) SkBaseMutex name - -#endif // !SK_USE_POSIX_THREADS - - -#endif diff --git a/gfx/skia/trunk/include/core/SkTypes.h b/gfx/skia/trunk/include/core/SkTypes.h index 969aac77b66e..9b376041066f 100644 --- a/gfx/skia/trunk/include/core/SkTypes.h +++ b/gfx/skia/trunk/include/core/SkTypes.h @@ -115,20 +115,37 @@ inline void operator delete(void* p) { #ifdef SK_DEVELOPER #define SkDEVCODE(code) code - // the 'toString' helper functions convert Sk* objects to human-readable - // form in developer mode - #define SK_DEVELOPER_TO_STRING() virtual void toString(SkString* str) const SK_OVERRIDE; #else #define SkDEVCODE(code) - #define SK_DEVELOPER_TO_STRING() +#endif + +#ifdef SK_IGNORE_TO_STRING + #define SK_TO_STRING_NONVIRT() + #define SK_TO_STRING_VIRT() + #define SK_TO_STRING_PUREVIRT() + #define SK_TO_STRING_OVERRIDE() +#else + // the 'toString' helper functions convert Sk* objects to human-readable + // form in developer mode + #define SK_TO_STRING_NONVIRT() void toString(SkString* str) const; + #define SK_TO_STRING_VIRT() virtual void toString(SkString* str) const; + #define SK_TO_STRING_PUREVIRT() virtual void toString(SkString* str) const = 0; + #define SK_TO_STRING_OVERRIDE() virtual void toString(SkString* str) const SK_OVERRIDE; #endif template struct SkCompileAssert { }; +// Uses static_cast(expr) instead of bool(expr) due to +// https://connect.microsoft.com/VisualStudio/feedback/details/832915 + +// The extra parentheses in SkCompileAssert<(...)> are a work around for +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57771 +// which was fixed in gcc 4.8.2. #define SK_COMPILE_ASSERT(expr, msg) \ - typedef SkCompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] SK_UNUSED + typedef SkCompileAssert<(static_cast(expr))> \ + msg[static_cast(expr) ? 1 : -1] SK_UNUSED /* * Usage: SK_MACRO_CONCAT(a, b) to construct the symbol ab @@ -219,6 +236,7 @@ typedef uint8_t SkBool8; SK_API uint32_t SkToU32(uintmax_t); SK_API int SkToInt(intmax_t); SK_API unsigned SkToUInt(uintmax_t); + SK_API size_t SkToSizeT(uintmax_t); #else #define SkToS8(x) ((int8_t)(x)) #define SkToU8(x) ((uint8_t)(x)) @@ -228,6 +246,7 @@ typedef uint8_t SkBool8; #define SkToU32(x) ((uint32_t)(x)) #define SkToInt(x) ((int)(x)) #define SkToUInt(x) ((unsigned)(x)) + #define SkToSizeT(x) ((size_t)(x)) #endif /** Returns 0 or 1 based on the condition diff --git a/gfx/skia/trunk/include/core/SkWriter32.h b/gfx/skia/trunk/include/core/SkWriter32.h index 586fe9fb08e5..cadcaa7853d8 100644 --- a/gfx/skia/trunk/include/core/SkWriter32.h +++ b/gfx/skia/trunk/include/core/SkWriter32.h @@ -10,6 +10,7 @@ #ifndef SkWriter32_DEFINED #define SkWriter32_DEFINED +#include "SkData.h" #include "SkMatrix.h" #include "SkPath.h" #include "SkPoint.h" @@ -18,7 +19,7 @@ #include "SkRegion.h" #include "SkScalar.h" #include "SkStream.h" -#include "SkTDArray.h" +#include "SkTemplates.h" #include "SkTypes.h" class SkWriter32 : SkNoncopyable { @@ -30,12 +31,7 @@ public: * first time an allocation doesn't fit. From then it will use dynamically allocated storage. * This used to be optional behavior, but pipe now relies on it. */ - SkWriter32(void* external = NULL, size_t externalBytes = 0) - : fData(0) - , fCapacity(0) - , fUsed(0) - , fExternal(0) - { + SkWriter32(void* external = NULL, size_t externalBytes = 0) { this->reset(external, externalBytes); } @@ -49,6 +45,7 @@ public: SkASSERT(SkIsAlign4((uintptr_t)external)); SkASSERT(SkIsAlign4(externalBytes)); + fSnapshot.reset(NULL); fData = (uint8_t*)external; fCapacity = externalBytes; fUsed = 0; @@ -75,7 +72,7 @@ public: /** * Read a T record at offset, which must be a multiple of 4. Only legal if the record - * was writtern atomically using the write methods below. + * was written atomically using the write methods below. */ template const T& readTAt(size_t offset) const { @@ -86,12 +83,13 @@ public: /** * Overwrite a T record at offset, which must be a multiple of 4. Only legal if the record - * was writtern atomically using the write methods below. + * was written atomically using the write methods below. */ template void overwriteTAt(size_t offset, const T& value) { SkASSERT(SkAlign4(offset) == offset); SkASSERT(offset < fUsed); + SkASSERT(fSnapshot.get() == NULL); *(T*)(fData + offset) = value; } @@ -235,14 +233,27 @@ public: return stream->read(this->reservePad(length), length); } + /** + * Captures a snapshot of the data as it is right now, and return it. + * Multiple calls without intervening writes may return the same SkData, + * but this is not guaranteed. + * Future appends will not affect the returned buffer. + * It is illegal to call overwriteTAt after this without an intervening + * append. It may cause the snapshot buffer to be corrupted. + * Callers must unref the returned SkData. + * This is not thread safe, it should only be called on the writing thread, + * the result however can be shared across threads. + */ + SkData* snapshotAsData() const; private: void growToAtLeast(size_t size); - uint8_t* fData; // Points to either fInternal or fExternal. - size_t fCapacity; // Number of bytes we can write to fData. - size_t fUsed; // Number of bytes written. - void* fExternal; // Unmanaged memory block. - SkTDArray fInternal; // Managed memory block. + uint8_t* fData; // Points to either fInternal or fExternal. + size_t fCapacity; // Number of bytes we can write to fData. + size_t fUsed; // Number of bytes written. + void* fExternal; // Unmanaged memory block. + SkAutoTMalloc fInternal; // Managed memory block. + SkAutoTUnref fSnapshot; // Holds the result of last asData. }; /** diff --git a/gfx/skia/trunk/include/core/SkXfermode.h b/gfx/skia/trunk/include/core/SkXfermode.h index 31b8081f85b0..e2977255ddb8 100644 --- a/gfx/skia/trunk/include/core/SkXfermode.h +++ b/gfx/skia/trunk/include/core/SkXfermode.h @@ -32,8 +32,6 @@ class SK_API SkXfermode : public SkFlattenable { public: SK_DECLARE_INST_COUNT(SkXfermode) - SkXfermode() {} - virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, const SkAlpha aa[]) const; virtual void xfer16(uint16_t dst[], const SkPMColor src[], int count, @@ -213,7 +211,7 @@ public: Coeff* dst, GrTexture* background = NULL); - SkDEVCODE(virtual void toString(SkString* str) const = 0;) + SK_TO_STRING_PUREVIRT() SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() SK_DEFINE_FLATTENABLE_TYPE(SkXfermode) @@ -230,6 +228,11 @@ protected: */ virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkXfermode() {} + private: enum { kModeCount = kLastMode + 1 @@ -250,7 +253,9 @@ private: */ class SkProcXfermode : public SkXfermode { public: - SkProcXfermode(SkXfermodeProc proc) : fProc(proc) {} + static SkProcXfermode* Create(SkXfermodeProc proc) { + return SkNEW_ARGS(SkProcXfermode, (proc)); + } // overrides from SkXfermode virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, @@ -260,7 +265,7 @@ public: virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count, const SkAlpha aa[]) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcXfermode) protected: @@ -276,6 +281,11 @@ protected: return fProc; } +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkProcXfermode(SkXfermodeProc proc) : fProc(proc) {} + private: SkXfermodeProc fProc; diff --git a/gfx/skia/trunk/include/device/xps/SkXPSDevice.h b/gfx/skia/trunk/include/device/xps/SkXPSDevice.h index 13ae83492f60..7265fbbedc4e 100644 --- a/gfx/skia/trunk/include/device/xps/SkXPSDevice.h +++ b/gfx/skia/trunk/include/device/xps/SkXPSDevice.h @@ -67,8 +67,6 @@ public: virtual bool endSheet(); virtual bool endPortfolio(); - virtual uint32_t getDeviceCapabilities() SK_OVERRIDE; - protected: virtual void clear(SkColor color) SK_OVERRIDE; @@ -312,11 +310,7 @@ private: const SkVector& ppuScale, IXpsOMPath* shadedPath); - // override from SkBaseDevice - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) SK_OVERRIDE; + virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; // Disable the default copy and assign implementation. SkXPSDevice(const SkXPSDevice&); diff --git a/gfx/skia/trunk/include/effects/Sk1DPathEffect.h b/gfx/skia/trunk/include/effects/Sk1DPathEffect.h index 4ac8f73b266b..ce49460e6537 100644 --- a/gfx/skia/trunk/include/effects/Sk1DPathEffect.h +++ b/gfx/skia/trunk/include/effects/Sk1DPathEffect.h @@ -52,7 +52,10 @@ public: @param style how to transform path at each point (based on the current position and tangent) */ - SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style); + static SkPath1DPathEffect* Create(const SkPath& path, SkScalar advance, SkScalar phase, + Style style) { + return SkNEW_ARGS(SkPath1DPathEffect, (path, advance, phase, style)); + } virtual bool filterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const SK_OVERRIDE; @@ -67,6 +70,11 @@ protected: virtual SkScalar begin(SkScalar contourLength) const SK_OVERRIDE; virtual SkScalar next(SkPath*, SkScalar, SkPathMeasure&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkPath1DPathEffect(const SkPath& path, SkScalar advance, SkScalar phase, Style); + private: SkPath fPath; // copied from constructor SkScalar fAdvance; // copied from constructor diff --git a/gfx/skia/trunk/include/effects/Sk2DPathEffect.h b/gfx/skia/trunk/include/effects/Sk2DPathEffect.h index 859b5cd95292..f037e3350856 100644 --- a/gfx/skia/trunk/include/effects/Sk2DPathEffect.h +++ b/gfx/skia/trunk/include/effects/Sk2DPathEffect.h @@ -14,7 +14,9 @@ class SK_API Sk2DPathEffect : public SkPathEffect { public: - Sk2DPathEffect(const SkMatrix& mat); + static Sk2DPathEffect* Create(const SkMatrix& mat) { + return SkNEW_ARGS(Sk2DPathEffect, (mat)); + } virtual bool filterPath(SkPath*, const SkPath&, SkStrokeRec*, const SkRect*) const SK_OVERRIDE; @@ -44,6 +46,11 @@ protected: Sk2DPathEffect(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + Sk2DPathEffect(const SkMatrix& mat); + private: SkMatrix fMatrix, fInverse; bool fMatrixIsInvertible; @@ -58,8 +65,9 @@ private: class SK_API SkLine2DPathEffect : public Sk2DPathEffect { public: - SkLine2DPathEffect(SkScalar width, const SkMatrix& matrix) - : Sk2DPathEffect(matrix), fWidth(width) {} + static SkLine2DPathEffect* Create(SkScalar width, const SkMatrix& matrix) { + return SkNEW_ARGS(SkLine2DPathEffect, (width, matrix)); + } virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const SK_OVERRIDE; @@ -73,6 +81,12 @@ protected: virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkLine2DPathEffect(SkScalar width, const SkMatrix& matrix) + : Sk2DPathEffect(matrix), fWidth(width) {} + private: SkScalar fWidth; @@ -85,7 +99,9 @@ public: * Stamp the specified path to fill the shape, using the matrix to define * the latice. */ - SkPath2DPathEffect(const SkMatrix&, const SkPath&); + static SkPath2DPathEffect* Create(const SkMatrix& matrix, const SkPath& path) { + return SkNEW_ARGS(SkPath2DPathEffect, (matrix, path)); + } SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPath2DPathEffect) @@ -95,6 +111,11 @@ protected: virtual void next(const SkPoint&, int u, int v, SkPath*) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkPath2DPathEffect(const SkMatrix&, const SkPath&); + private: SkPath fPath; diff --git a/gfx/skia/trunk/include/effects/SkAvoidXfermode.h b/gfx/skia/trunk/include/effects/SkAvoidXfermode.h index afc3fc9d7009..3df8c8e9ddab 100644 --- a/gfx/skia/trunk/include/effects/SkAvoidXfermode.h +++ b/gfx/skia/trunk/include/effects/SkAvoidXfermode.h @@ -37,7 +37,9 @@ public: Tolerance near 0: draw only on colors that are nearly identical to the op-color Tolerance near 255: draw on any colors even remotely similar to the op-color */ - SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode); + static SkAvoidXfermode* Create(SkColor opColor, U8CPU tolerance, Mode mode) { + return SkNEW_ARGS(SkAvoidXfermode, (opColor, tolerance, mode)); + } // overrides from SkXfermode virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, @@ -47,13 +49,18 @@ public: virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count, const SkAlpha aa[]) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkAvoidXfermode) protected: SkAvoidXfermode(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkAvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode); + private: SkColor fOpColor; uint32_t fDistMul; // x.14 diff --git a/gfx/skia/trunk/include/effects/SkBicubicImageFilter.h b/gfx/skia/trunk/include/effects/SkBicubicImageFilter.h index 48105b1c5b7e..7c1e92344ad6 100644 --- a/gfx/skia/trunk/include/effects/SkBicubicImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkBicubicImageFilter.h @@ -20,30 +20,30 @@ class SK_API SkBicubicImageFilter : public SkImageFilter { public: + virtual ~SkBicubicImageFilter(); + + static SkBicubicImageFilter* CreateMitchell(const SkSize& scale, SkImageFilter* input = NULL); + + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBicubicImageFilter) + +protected: /** Construct a (scaling-only) bicubic resampling image filter. @param scale How much to scale the image. @param coefficients The 16 coefficients of the bicubic matrix. @param input The input image filter. If NULL, the src bitmap passed to filterImage() is used instead. */ - SkBicubicImageFilter(const SkSize& scale, const SkScalar coefficients[16], SkImageFilter* input = NULL); - static SkBicubicImageFilter* CreateMitchell(const SkSize& scale, SkImageFilter* input = NULL); - virtual ~SkBicubicImageFilter(); - - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBicubicImageFilter) - -protected: SkBicubicImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; } - virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, + virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #endif diff --git a/gfx/skia/trunk/include/effects/SkBitmapAlphaThresholdShader.h b/gfx/skia/trunk/include/effects/SkBitmapAlphaThresholdShader.h deleted file mode 100644 index 61596daff3e0..000000000000 --- a/gfx/skia/trunk/include/effects/SkBitmapAlphaThresholdShader.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkShader.h" -#include "SkBitmap.h" -#include "SkRegion.h" -#include "SkString.h" - -class SK_API SkBitmapAlphaThresholdShader : public SkShader { -public: - /** - * Creates a shader that samples a bitmap and a region. If the sample is inside the region - * the alpha of the bitmap color is boosted up to a threshold value. If it is - * outside the region then the bitmap alpha is decreased to the threshold value. - * The 0,0 point of the region corresponds to the upper left corner of the bitmap - * Currently, this only has a GPU implementation, doesn't respect the paint's bitmap - * filter setting, and always uses clamp mode. - */ - static SkShader* Create(const SkBitmap& bitmap, const SkRegion& region, U8CPU threshold); -}; diff --git a/gfx/skia/trunk/include/effects/SkBitmapSource.h b/gfx/skia/trunk/include/effects/SkBitmapSource.h index fcc1db97bc75..76f51f54e8d8 100644 --- a/gfx/skia/trunk/include/effects/SkBitmapSource.h +++ b/gfx/skia/trunk/include/effects/SkBitmapSource.h @@ -13,8 +13,13 @@ class SK_API SkBitmapSource : public SkImageFilter { public: - explicit SkBitmapSource(const SkBitmap& bitmap); - SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect); + static SkBitmapSource* Create(const SkBitmap& bitmap) { + return SkNEW_ARGS(SkBitmapSource, (bitmap)); + } + static SkBitmapSource* Create(const SkBitmap& bitmap, const SkRect& srcRect, + const SkRect& dstRect) { + return SkNEW_ARGS(SkBitmapSource, (bitmap, srcRect, dstRect)); + } virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapSource) @@ -22,10 +27,16 @@ public: protected: explicit SkBitmapSource(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; virtual bool onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + explicit SkBitmapSource(const SkBitmap& bitmap); + SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect); + private: SkBitmap fBitmap; SkRect fSrcRect, fDstRect; diff --git a/gfx/skia/trunk/include/effects/SkBlurDrawLooper.h b/gfx/skia/trunk/include/effects/SkBlurDrawLooper.h index 46b154debcae..5469e2cf02f8 100644 --- a/gfx/skia/trunk/include/effects/SkBlurDrawLooper.h +++ b/gfx/skia/trunk/include/effects/SkBlurDrawLooper.h @@ -43,11 +43,11 @@ public: uint32_t flags = kNone_BlurFlag); virtual ~SkBlurDrawLooper(); - // overrides from SkDrawLooper - virtual void init(SkCanvas*); - virtual bool next(SkCanvas*, SkPaint* paint); + virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + virtual size_t contextSize() const SK_OVERRIDE { return sizeof(BlurDrawLooperContext); } + + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurDrawLooper) protected: @@ -66,7 +66,17 @@ private: kAfterEdge, kDone }; - State fState; + + class BlurDrawLooperContext : public SkDrawLooper::Context { + public: + explicit BlurDrawLooperContext(const SkBlurDrawLooper* looper); + + virtual bool next(SkCanvas* canvas, SkPaint* paint) SK_OVERRIDE; + + private: + const SkBlurDrawLooper* fLooper; + State fState; + }; void init(SkScalar sigma, SkScalar dx, SkScalar dy, SkColor color, uint32_t flags); diff --git a/gfx/skia/trunk/include/effects/SkBlurImageFilter.h b/gfx/skia/trunk/include/effects/SkBlurImageFilter.h index 60dab729b407..e7d0db3c381f 100644 --- a/gfx/skia/trunk/include/effects/SkBlurImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkBlurImageFilter.h @@ -13,10 +13,13 @@ class SK_API SkBlurImageFilter : public SkImageFilter { public: - SkBlurImageFilter(SkScalar sigmaX, - SkScalar sigmaY, - SkImageFilter* input = NULL, - const CropRect* cropRect = NULL); + static SkBlurImageFilter* Create(SkScalar sigmaX, + SkScalar sigmaY, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkBlurImageFilter, (sigmaX, sigmaY, input, cropRect)); + } + virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter) @@ -25,15 +28,23 @@ protected: explicit SkBlurImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst) const SK_OVERRIDE; bool canFilterImageGPU() const SK_OVERRIDE { return true; } - virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, + virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkBlurImageFilter(SkScalar sigmaX, + SkScalar sigmaY, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL); + private: SkSize fSigma; typedef SkImageFilter INHERITED; diff --git a/gfx/skia/trunk/include/effects/SkColorFilterImageFilter.h b/gfx/skia/trunk/include/effects/SkColorFilterImageFilter.h index d127f36db3c3..6c88361b5857 100644 --- a/gfx/skia/trunk/include/effects/SkColorFilterImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkColorFilterImageFilter.h @@ -25,7 +25,7 @@ protected: SkColorFilterImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; virtual bool asColorFilter(SkColorFilter**) const SK_OVERRIDE; diff --git a/gfx/skia/trunk/include/effects/SkColorMatrixFilter.h b/gfx/skia/trunk/include/effects/SkColorMatrixFilter.h index a4144e17175d..eee99271573b 100644 --- a/gfx/skia/trunk/include/effects/SkColorMatrixFilter.h +++ b/gfx/skia/trunk/include/effects/SkColorMatrixFilter.h @@ -13,8 +13,12 @@ class SK_API SkColorMatrixFilter : public SkColorFilter { public: - explicit SkColorMatrixFilter(const SkColorMatrix&); - SkColorMatrixFilter(const SkScalar array[20]); + static SkColorMatrixFilter* Create(const SkColorMatrix& cm) { + return SkNEW_ARGS(SkColorMatrixFilter, (cm)); + } + static SkColorMatrixFilter* Create(const SkScalar array[20]) { + return SkNEW_ARGS(SkColorMatrixFilter, (array)); + } // overrides from SkColorFilter virtual void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const SK_OVERRIDE; @@ -30,7 +34,7 @@ public: int fShift; }; - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorMatrixFilter) @@ -38,6 +42,12 @@ protected: SkColorMatrixFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + explicit SkColorMatrixFilter(const SkColorMatrix&); + SkColorMatrixFilter(const SkScalar array[20]); + private: SkColorMatrix fMatrix; diff --git a/gfx/skia/trunk/include/effects/SkComposeImageFilter.h b/gfx/skia/trunk/include/effects/SkComposeImageFilter.h index 9e024ef84e19..61a32d3ea85f 100644 --- a/gfx/skia/trunk/include/effects/SkComposeImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkComposeImageFilter.h @@ -12,18 +12,26 @@ class SK_API SkComposeImageFilter : public SkImageFilter { public: - SkComposeImageFilter(SkImageFilter* outer, SkImageFilter* inner) : INHERITED(outer, inner) {} virtual ~SkComposeImageFilter(); + static SkComposeImageFilter* Create(SkImageFilter* outer, SkImageFilter* inner) { + return SkNEW_ARGS(SkComposeImageFilter, (outer, inner)); + } + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeImageFilter) protected: explicit SkComposeImageFilter(SkReadBuffer& buffer); - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkComposeImageFilter(SkImageFilter* outer, SkImageFilter* inner) : INHERITED(outer, inner) {} + private: typedef SkImageFilter INHERITED; }; diff --git a/gfx/skia/trunk/include/effects/SkCornerPathEffect.h b/gfx/skia/trunk/include/effects/SkCornerPathEffect.h index dcb7c9f736c3..c77505be3911 100644 --- a/gfx/skia/trunk/include/effects/SkCornerPathEffect.h +++ b/gfx/skia/trunk/include/effects/SkCornerPathEffect.h @@ -20,7 +20,9 @@ public: /** radius must be > 0 to have an effect. It specifies the distance from each corner that should be "rounded". */ - SkCornerPathEffect(SkScalar radius); + static SkCornerPathEffect* Create(SkScalar radius) { + return SkNEW_ARGS(SkCornerPathEffect, (radius)); + } virtual ~SkCornerPathEffect(); virtual bool filterPath(SkPath* dst, const SkPath& src, @@ -32,6 +34,11 @@ protected: SkCornerPathEffect(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkCornerPathEffect(SkScalar radius); + private: SkScalar fRadius; diff --git a/gfx/skia/trunk/include/effects/SkDashPathEffect.h b/gfx/skia/trunk/include/effects/SkDashPathEffect.h index 818e0739246f..a1c548265367 100644 --- a/gfx/skia/trunk/include/effects/SkDashPathEffect.h +++ b/gfx/skia/trunk/include/effects/SkDashPathEffect.h @@ -36,8 +36,10 @@ public: Note: only affects stroked paths. */ - SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase, - bool scaleToFit = false); + static SkDashPathEffect* Create(const SkScalar intervals[], int count, + SkScalar phase, bool scaleToFit = false) { + return SkNEW_ARGS(SkDashPathEffect, (intervals, count, phase, scaleToFit)); + } virtual ~SkDashPathEffect(); virtual bool filterPath(SkPath* dst, const SkPath& src, @@ -55,6 +57,12 @@ protected: SkDashPathEffect(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkDashPathEffect(const SkScalar intervals[], int count, SkScalar phase, + bool scaleToFit = false); + private: SkScalar* fIntervals; int32_t fCount; diff --git a/gfx/skia/trunk/include/effects/SkDiscretePathEffect.h b/gfx/skia/trunk/include/effects/SkDiscretePathEffect.h index 60eb85274c17..126b40821899 100644 --- a/gfx/skia/trunk/include/effects/SkDiscretePathEffect.h +++ b/gfx/skia/trunk/include/effects/SkDiscretePathEffect.h @@ -20,7 +20,9 @@ public: away from the original path by a maximum of deviation. Note: works on filled or framed paths */ - SkDiscretePathEffect(SkScalar segLength, SkScalar deviation); + static SkDiscretePathEffect* Create(SkScalar segLength, SkScalar deviation) { + return SkNEW_ARGS(SkDiscretePathEffect, (segLength, deviation)); + } virtual bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const SK_OVERRIDE; @@ -31,6 +33,11 @@ protected: SkDiscretePathEffect(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkDiscretePathEffect(SkScalar segLength, SkScalar deviation); + private: SkScalar fSegLength, fPerterb; diff --git a/gfx/skia/trunk/include/effects/SkDisplacementMapEffect.h b/gfx/skia/trunk/include/effects/SkDisplacementMapEffect.h index 5de4814951a6..4b4ea6021708 100644 --- a/gfx/skia/trunk/include/effects/SkDisplacementMapEffect.h +++ b/gfx/skia/trunk/include/effects/SkDisplacementMapEffect.h @@ -18,23 +18,25 @@ public: kR_ChannelSelectorType, kG_ChannelSelectorType, kB_ChannelSelectorType, - kA_ChannelSelectorType, - kKeyBits = 3 // Max value is 4, so 3 bits are required at most + kA_ChannelSelectorType }; - SkDisplacementMapEffect(ChannelSelectorType xChannelSelector, - ChannelSelectorType yChannelSelector, - SkScalar scale, SkImageFilter* displacement, - SkImageFilter* color = NULL, - const CropRect* cropRect = NULL); - ~SkDisplacementMapEffect(); + static SkDisplacementMapEffect* Create(ChannelSelectorType xChannelSelector, + ChannelSelectorType yChannelSelector, + SkScalar scale, SkImageFilter* displacement, + SkImageFilter* color = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkDisplacementMapEffect, (xChannelSelector, yChannelSelector, scale, + displacement, color, cropRect)); + } + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDisplacementMapEffect) virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE; virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE; @@ -44,7 +46,7 @@ public: #if SK_SUPPORT_GPU virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; } - virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, + virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #endif @@ -52,6 +54,15 @@ protected: explicit SkDisplacementMapEffect(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkDisplacementMapEffect(ChannelSelectorType xChannelSelector, + ChannelSelectorType yChannelSelector, + SkScalar scale, SkImageFilter* displacement, + SkImageFilter* color = NULL, + const CropRect* cropRect = NULL); + private: ChannelSelectorType fXChannelSelector; ChannelSelectorType fYChannelSelector; diff --git a/gfx/skia/trunk/include/effects/SkDropShadowImageFilter.h b/gfx/skia/trunk/include/effects/SkDropShadowImageFilter.h index aba2017eef6d..05eb6a00fd53 100644 --- a/gfx/skia/trunk/include/effects/SkDropShadowImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkDropShadowImageFilter.h @@ -11,19 +11,34 @@ class SK_API SkDropShadowImageFilter : public SkImageFilter { public: - SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor, SkImageFilter* input = NULL); - SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor, SkImageFilter* input = NULL, const CropRect* cropRect = NULL); + static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy, SkScalar sigma, + SkColor color, SkImageFilter* input = NULL) { + return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigma, color, input)); + } + static SkDropShadowImageFilter* Create(SkScalar dx, SkScalar dy, + SkScalar sigmaX, SkScalar sigmaY, SkColor color, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkDropShadowImageFilter, (dx, dy, sigmaX, sigmaY, + color, input, cropRect)); + } virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter) protected: explicit SkDropShadowImageFilter(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& source, const SkMatrix&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; + virtual bool onFilterImage(Proxy*, const SkBitmap& source, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst) const SK_OVERRIDE; - +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor, + SkImageFilter* input = NULL); + SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor, + SkImageFilter* input = NULL, const CropRect* cropRect = NULL); private: SkScalar fDx, fDy, fSigmaX, fSigmaY; diff --git a/gfx/skia/trunk/include/effects/SkEmbossMaskFilter.h b/gfx/skia/trunk/include/effects/SkEmbossMaskFilter.h index 263c5e054509..eb8f8117a486 100644 --- a/gfx/skia/trunk/include/effects/SkEmbossMaskFilter.h +++ b/gfx/skia/trunk/include/effects/SkEmbossMaskFilter.h @@ -23,10 +23,9 @@ public: uint8_t fSpecular; // exponent, 4.4 right now }; - SkEmbossMaskFilter(SkScalar blurSigma, const Light& light); - - SK_ATTR_DEPRECATED("use sigma version") - SkEmbossMaskFilter(const Light& light, SkScalar blurRadius); + static SkEmbossMaskFilter* Create(SkScalar blurSigma, const Light& light) { + return SkNEW_ARGS(SkEmbossMaskFilter, (blurSigma, light)); + } // overrides from SkMaskFilter // This method is not exported to java. @@ -35,13 +34,18 @@ public: virtual bool filterMask(SkMask* dst, const SkMask& src, const SkMatrix&, SkIPoint* margin) const SK_OVERRIDE; - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmbossMaskFilter) protected: SkEmbossMaskFilter(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkEmbossMaskFilter(SkScalar blurSigma, const Light& light); + private: Light fLight; SkScalar fBlurSigma; diff --git a/gfx/skia/trunk/include/effects/SkKernel33MaskFilter.h b/gfx/skia/trunk/include/effects/SkKernel33MaskFilter.h index bcd9b26b8481..3ec3cc9e5060 100644 --- a/gfx/skia/trunk/include/effects/SkKernel33MaskFilter.h +++ b/gfx/skia/trunk/include/effects/SkKernel33MaskFilter.h @@ -12,18 +12,17 @@ class SK_API SkKernel33ProcMaskFilter : public SkMaskFilter { public: - SkKernel33ProcMaskFilter(unsigned percent256 = 256) - : fPercent256(percent256) {} - virtual uint8_t computeValue(uint8_t* const* srcRows) const = 0; virtual SkMask::Format getFormat() const SK_OVERRIDE; virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&, SkIPoint*) const SK_OVERRIDE; - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() protected: + SkKernel33ProcMaskFilter(unsigned percent256 = 256) + : fPercent256(percent256) {} SkKernel33ProcMaskFilter(SkReadBuffer& rb); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; @@ -37,18 +36,26 @@ private: class SK_API SkKernel33MaskFilter : public SkKernel33ProcMaskFilter { public: - SkKernel33MaskFilter(const int coeff[3][3], int shift, int percent256 = 256) - : SkKernel33ProcMaskFilter(percent256) { - memcpy(fKernel, coeff, 9 * sizeof(int)); - fShift = shift; + static SkKernel33MaskFilter* Create(const int coeff[3][3], int shift, int percent256 = 256) { + return SkNEW_ARGS(SkKernel33MaskFilter, (coeff, shift, percent256)); } // override from SkKernel33ProcMaskFilter virtual uint8_t computeValue(uint8_t* const* srcRows) const SK_OVERRIDE; - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkKernel33MaskFilter) +protected: +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkKernel33MaskFilter(const int coeff[3][3], int shift, int percent256 = 256) + : SkKernel33ProcMaskFilter(percent256) { + memcpy(fKernel, coeff, 9 * sizeof(int)); + fShift = shift; + } + private: int fKernel[3][3]; int fShift; diff --git a/gfx/skia/trunk/include/effects/SkLayerDrawLooper.h b/gfx/skia/trunk/include/effects/SkLayerDrawLooper.h index 6955192b53f2..1e76ce21e581 100644 --- a/gfx/skia/trunk/include/effects/SkLayerDrawLooper.h +++ b/gfx/skia/trunk/include/effects/SkLayerDrawLooper.h @@ -24,8 +24,8 @@ public: * Bits specifies which aspects of the layer's paint should replace the * corresponding aspects on the draw's paint. * kEntirePaint_Bits means use the layer's paint completely. - * 0 means ignore the layer's paint... except that LayerInfo's fFlagsMask - * and fColorMode are always applied. + * 0 means ignore the layer's paint... except for fColorMode, which is + * always applied. */ enum Bits { kStyle_Bit = 1 << 0, //!< use this layer's Style/stroke settings @@ -40,8 +40,7 @@ public: * Use the layer's paint entirely, with these exceptions: * - We never override the draw's paint's text_encoding, since that is * used to interpret the text/len parameters in draw[Pos]Text. - * - Flags and Color are always computed using the LayerInfo's - * fFlagsMask and fColorMode. + * - Color is always computed using the LayerInfo's fColorMode. */ kEntirePaint_Bits = -1 @@ -51,12 +50,6 @@ public: /** * Info for how to apply the layer's paint and offset. * - * fFlagsMask selects which flags in the layer's paint should be applied. - * result = (draw-flags & ~fFlagsMask) | (layer-flags & fFlagsMask) - * In the extreme: - * If fFlagsMask is 0, we ignore all of the layer's flags - * If fFlagsMask is -1, we use all of the layer's flags - * * fColorMode controls how we compute the final color for the layer: * The layer's paint's color is treated as the SRC * The draw's paint's color is treated as the DST @@ -66,7 +59,6 @@ public: * kDst_Mode: to just keep the draw's color, ignoring the layer's */ struct SK_API LayerInfo { - uint32_t fFlagsMask; // SkPaint::Flags BitFlags fPaintBits; SkXfermode::Mode fColorMode; SkVector fOffset; @@ -102,15 +94,17 @@ public: /// Similar to addLayer, but adds a layer to the top. SkPaint* addLayerOnTop(const LayerInfo&); - // overrides from SkDrawLooper - virtual void init(SkCanvas*); - virtual bool next(SkCanvas*, SkPaint* paint); + virtual SkDrawLooper::Context* createContext(SkCanvas*, void* storage) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLayerDrawLooper) + virtual size_t contextSize() const SK_OVERRIDE { return sizeof(LayerDrawLooperContext); } + + SK_TO_STRING_OVERRIDE() + + /// Implements Flattenable. + virtual Factory getFactory() const SK_OVERRIDE { return CreateProc; } + static SkFlattenable* CreateProc(SkReadBuffer& buffer); protected: - SkLayerDrawLooper(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; private: @@ -124,9 +118,18 @@ private: int fCount; // state-machine during the init/next cycle - Rec* fCurrRec; + class LayerDrawLooperContext : public SkDrawLooper::Context { + public: + explicit LayerDrawLooperContext(const SkLayerDrawLooper* looper); - static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&); + protected: + virtual bool next(SkCanvas*, SkPaint* paint) SK_OVERRIDE; + + private: + Rec* fCurrRec; + + static void ApplyInfo(SkPaint* dst, const SkPaint& src, const LayerInfo&); + }; class MyRegistrar : public SkFlattenable::Registrar { public: @@ -134,6 +137,44 @@ private: }; typedef SkDrawLooper INHERITED; + +public: + class SK_API Builder { + public: + Builder(); + ~Builder(); + + /** + * Call for each layer you want to add (from top to bottom). + * This returns a paint you can modify, but that ptr is only valid until + * the next call made to addLayer(). + */ + SkPaint* addLayer(const LayerInfo&); + + /** + * This layer will draw with the original paint, at the specified offset + */ + void addLayer(SkScalar dx, SkScalar dy); + + /** + * This layer will with the original paint and no offset. + */ + void addLayer() { this->addLayer(0, 0); } + + /// Similar to addLayer, but adds a layer to the top. + SkPaint* addLayerOnTop(const LayerInfo&); + + /** + * Pass list of layers on to newly built looper and return it. This will + * also reset the builder, so it can be used to build another looper. + */ + SkLayerDrawLooper* detachLooper(); + + private: + Rec* fRecs; + Rec* fTopRec; + int fCount; + }; }; #endif diff --git a/gfx/skia/trunk/include/effects/SkLayerRasterizer.h b/gfx/skia/trunk/include/effects/SkLayerRasterizer.h index be81a2ba3def..fdfb179cb6ba 100644 --- a/gfx/skia/trunk/include/effects/SkLayerRasterizer.h +++ b/gfx/skia/trunk/include/effects/SkLayerRasterizer.h @@ -18,9 +18,36 @@ class SkPaint; class SK_API SkLayerRasterizer : public SkRasterizer { public: - SkLayerRasterizer(); virtual ~SkLayerRasterizer(); + class SK_API Builder { + public: + Builder(); + ~Builder(); + + void addLayer(const SkPaint& paint) { + this->addLayer(paint, 0, 0); + } + + /** + * Add a new layer (above any previous layers) to the rasterizer. + * The layer will extract those fields that affect the mask from + * the specified paint, but will not retain a reference to the paint + * object itself, so it may be reused without danger of side-effects. + */ + void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy); + + /** + * Pass queue of layers on to newly created layer rasterizer and return it. The builder + * cannot be used any more after calling this function. + */ + SkLayerRasterizer* detachRasterizer(); + + private: + SkDeque* fLayers; + }; + +#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API void addLayer(const SkPaint& paint) { this->addLayer(paint, 0, 0); } @@ -31,10 +58,12 @@ public: object itself, so it may be reused without danger of side-effects. */ void addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy); +#endif SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLayerRasterizer) protected: + SkLayerRasterizer(SkDeque* layers); SkLayerRasterizer(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; @@ -43,8 +72,19 @@ protected: const SkIRect* clipBounds, SkMask* mask, SkMask::CreateMode mode) const; +#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API +public: +#endif + SkLayerRasterizer(); + private: - SkDeque fLayers; +#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API + SkDeque* fLayers; +#else + const SkDeque* const fLayers; +#endif + + static SkDeque* ReadLayers(SkReadBuffer& buffer); typedef SkRasterizer INHERITED; }; diff --git a/gfx/skia/trunk/include/effects/SkLerpXfermode.h b/gfx/skia/trunk/include/effects/SkLerpXfermode.h index b6cc93fe0767..d9186d904c56 100644 --- a/gfx/skia/trunk/include/effects/SkLerpXfermode.h +++ b/gfx/skia/trunk/include/effects/SkLerpXfermode.h @@ -28,7 +28,7 @@ public: virtual void xferA8(SkAlpha dst[], const SkPMColor src[], int count, const SkAlpha aa[]) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLerpXfermode) protected: diff --git a/gfx/skia/trunk/include/effects/SkLumaColorFilter.h b/gfx/skia/trunk/include/effects/SkLumaColorFilter.h index 6c57f7cc7513..f2cee294c3f2 100644 --- a/gfx/skia/trunk/include/effects/SkLumaColorFilter.h +++ b/gfx/skia/trunk/include/effects/SkLumaColorFilter.h @@ -31,7 +31,7 @@ public: virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE; #endif - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLumaColorFilter) protected: diff --git a/gfx/skia/trunk/include/effects/SkMagnifierImageFilter.h b/gfx/skia/trunk/include/effects/SkMagnifierImageFilter.h index 44f0d0d6898e..14bccdbef920 100644 --- a/gfx/skia/trunk/include/effects/SkMagnifierImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkMagnifierImageFilter.h @@ -14,7 +14,9 @@ class SK_API SkMagnifierImageFilter : public SkImageFilter { public: - SkMagnifierImageFilter(SkRect srcRect, SkScalar inset); + static SkMagnifierImageFilter* Create(const SkRect& srcRect, SkScalar inset) { + return SkNEW_ARGS(SkMagnifierImageFilter, (srcRect, inset)); + } SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMagnifierImageFilter) @@ -22,12 +24,17 @@ protected: explicit SkMagnifierImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool asNewEffect(GrEffectRef** effect, GrTexture* texture, const SkMatrix& matrix, const SkIRect& bounds) const SK_OVERRIDE; #endif +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset); + private: SkRect fSrcRect; SkScalar fInset; diff --git a/gfx/skia/trunk/include/effects/SkMatrixConvolutionImageFilter.h b/gfx/skia/trunk/include/effects/SkMatrixConvolutionImageFilter.h index 59af83e02527..5b02fbaab59b 100644 --- a/gfx/skia/trunk/include/effects/SkMatrixConvolutionImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkMatrixConvolutionImageFilter.h @@ -28,61 +28,78 @@ public: kClampToBlack_TileMode, /*!< Fill with transparent black. */ }; - /** Construct a matrix convolution image filter. - @param kernelSize The kernel size in pixels, in each dimension (N by M). - @param kernel The image processing kernel. Must contain N * M - elements, in row order. - @param gain A scale factor applied to each pixel after - convolution. This can be used to normalize the - kernel, if it does not sum to 1. - @param bias A bias factor added to each pixel after convolution. - @param target An offset applied to each pixel coordinate before - convolution. This can be used to center the kernel - over the image (e.g., a 3x3 kernel should have a - target of {1, 1}). - @param tileMode How accesses outside the image are treated. (@see - TileMode). - @param convolveAlpha If true, all channels are convolved. If false, - only the RGB channels are convolved, and - alpha is copied from the source image. - @param input The input image filter. If NULL, the src bitmap - passed to filterImage() is used instead. - @param cropRect The rectangle to which the output processing will be limited. - */ - - SkMatrixConvolutionImageFilter(const SkISize& kernelSize, - const SkScalar* kernel, - SkScalar gain, - SkScalar bias, - const SkIPoint& target, - TileMode tileMode, - bool convolveAlpha, - SkImageFilter* input = NULL, - const CropRect* cropRect = NULL); virtual ~SkMatrixConvolutionImageFilter(); + /** Construct a matrix convolution image filter. + @param kernelSize The kernel size in pixels, in each dimension (N by M). + @param kernel The image processing kernel. Must contain N * M + elements, in row order. + @param gain A scale factor applied to each pixel after + convolution. This can be used to normalize the + kernel, if it does not sum to 1. + @param bias A bias factor added to each pixel after convolution. + @param kernelOffset An offset applied to each pixel coordinate before + convolution. This can be used to center the kernel + over the image (e.g., a 3x3 kernel should have an + offset of {1, 1}). + @param tileMode How accesses outside the image are treated. (@see + TileMode). + @param convolveAlpha If true, all channels are convolved. If false, + only the RGB channels are convolved, and + alpha is copied from the source image. + @param input The input image filter. If NULL, the src bitmap + passed to filterImage() is used instead. + @param cropRect The rectangle to which the output processing will be limited. + */ + static SkMatrixConvolutionImageFilter* Create(const SkISize& kernelSize, + const SkScalar* kernel, + SkScalar gain, + SkScalar bias, + const SkIPoint& kernelOffset, + TileMode tileMode, + bool convolveAlpha, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkMatrixConvolutionImageFilter, (kernelSize, kernel, gain, bias, + kernelOffset, tileMode, convolveAlpha, + input, cropRect)); + } + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMatrixConvolutionImageFilter) protected: SkMatrixConvolutionImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool asNewEffect(GrEffectRef** effect, GrTexture*, - const SkMatrix& matrix, + const SkMatrix& ctm, const SkIRect& bounds) const SK_OVERRIDE; #endif +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkMatrixConvolutionImageFilter(const SkISize& kernelSize, + const SkScalar* kernel, + SkScalar gain, + SkScalar bias, + const SkIPoint& kernelOffset, + TileMode tileMode, + bool convolveAlpha, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL); + private: SkISize fKernelSize; SkScalar* fKernel; SkScalar fGain; SkScalar fBias; - SkIPoint fTarget; + SkIPoint fKernelOffset; TileMode fTileMode; bool fConvolveAlpha; typedef SkImageFilter INHERITED; diff --git a/gfx/skia/trunk/include/effects/SkMergeImageFilter.h b/gfx/skia/trunk/include/effects/SkMergeImageFilter.h index 36eaaf3df177..f3f0d67f15d4 100644 --- a/gfx/skia/trunk/include/effects/SkMergeImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkMergeImageFilter.h @@ -14,22 +14,37 @@ class SK_API SkMergeImageFilter : public SkImageFilter { public: - SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second, - SkXfermode::Mode = SkXfermode::kSrcOver_Mode, - const CropRect* cropRect = NULL); - SkMergeImageFilter(SkImageFilter* filters[], int count, - const SkXfermode::Mode modes[] = NULL, - const CropRect* cropRect = NULL); virtual ~SkMergeImageFilter(); + static SkMergeImageFilter* Create(SkImageFilter* first, SkImageFilter* second, + SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkMergeImageFilter, (first, second, mode, cropRect)); + } + static SkMergeImageFilter* Create(SkImageFilter* filters[], int count, + const SkXfermode::Mode modes[] = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkMergeImageFilter, (filters, count, modes, cropRect)); + } + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkMergeImageFilter) protected: SkMergeImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; + +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkMergeImageFilter(SkImageFilter* first, SkImageFilter* second, + SkXfermode::Mode = SkXfermode::kSrcOver_Mode, + const CropRect* cropRect = NULL); + SkMergeImageFilter(SkImageFilter* filters[], int count, + const SkXfermode::Mode modes[] = NULL, + const CropRect* cropRect = NULL); private: uint8_t* fModes; // SkXfermode::Mode diff --git a/gfx/skia/trunk/include/effects/SkMorphologyImageFilter.h b/gfx/skia/trunk/include/effects/SkMorphologyImageFilter.h index 4d60180aeb67..0c1cc85601ec 100644 --- a/gfx/skia/trunk/include/effects/SkMorphologyImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkMorphologyImageFilter.h @@ -15,7 +15,6 @@ class SK_API SkMorphologyImageFilter : public SkImageFilter { public: - SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect); virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE; virtual bool onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const SK_OVERRIDE; @@ -30,15 +29,17 @@ public: int width, int height, int srcStride, int dstStride); protected: + SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input, + const CropRect* cropRect); bool filterImageGeneric(Proc procX, Proc procY, - Proxy*, const SkBitmap& src, const SkMatrix&, + Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const; SkMorphologyImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; } bool filterImageGPUGeneric(bool dilate, Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, SkBitmap* result, + const Context& ctm, SkBitmap* result, SkIPoint* offset) const; #endif @@ -51,15 +52,16 @@ private: class SK_API SkDilateImageFilter : public SkMorphologyImageFilter { public: - SkDilateImageFilter(int radiusX, int radiusY, - SkImageFilter* input = NULL, - const CropRect* cropRect = NULL) - : INHERITED(radiusX, radiusY, input, cropRect) {} + static SkDilateImageFilter* Create(int radiusX, int radiusY, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkDilateImageFilter, (radiusX, radiusY, input, cropRect)); + } - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #if SK_SUPPORT_GPU - virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, + virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #endif @@ -68,21 +70,30 @@ public: protected: SkDilateImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {} +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkDilateImageFilter(int radiusX, int radiusY, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL) + : INHERITED(radiusX, radiusY, input, cropRect) {} + private: typedef SkMorphologyImageFilter INHERITED; }; class SK_API SkErodeImageFilter : public SkMorphologyImageFilter { public: - SkErodeImageFilter(int radiusX, int radiusY, - SkImageFilter* input = NULL, - const CropRect* cropRect = NULL) - : INHERITED(radiusX, radiusY, input, cropRect) {} + static SkErodeImageFilter* Create(int radiusX, int radiusY, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkErodeImageFilter, (radiusX, radiusY, input, cropRect)); + } - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #if SK_SUPPORT_GPU - virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, + virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #endif @@ -91,6 +102,14 @@ public: protected: SkErodeImageFilter(SkReadBuffer& buffer) : INHERITED(buffer) {} +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkErodeImageFilter(int radiusX, int radiusY, + SkImageFilter* input = NULL, + const CropRect* cropRect = NULL) + : INHERITED(radiusX, radiusY, input, cropRect) {} + private: typedef SkMorphologyImageFilter INHERITED; }; diff --git a/gfx/skia/trunk/include/effects/SkOffsetImageFilter.h b/gfx/skia/trunk/include/effects/SkOffsetImageFilter.h index 31eead3ded37..8d9db64ac175 100644 --- a/gfx/skia/trunk/include/effects/SkOffsetImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkOffsetImageFilter.h @@ -15,8 +15,10 @@ class SK_API SkOffsetImageFilter : public SkImageFilter { typedef SkImageFilter INHERITED; public: - SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL, - const CropRect* cropRect = NULL); + static SkOffsetImageFilter* Create(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkOffsetImageFilter, (dx, dy, input, cropRect)); + } virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOffsetImageFilter) @@ -24,10 +26,16 @@ protected: SkOffsetImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; virtual bool onFilterBounds(const SkIRect&, const SkMatrix&, SkIRect*) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL, + const CropRect* cropRect = NULL); + private: SkVector fOffset; }; diff --git a/gfx/skia/trunk/include/effects/SkPerlinNoiseShader.h b/gfx/skia/trunk/include/effects/SkPerlinNoiseShader.h index dd89c7092595..03ae3832ca26 100644 --- a/gfx/skia/trunk/include/effects/SkPerlinNoiseShader.h +++ b/gfx/skia/trunk/include/effects/SkPerlinNoiseShader.h @@ -69,7 +69,7 @@ public: virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader) protected: @@ -79,28 +79,28 @@ protected: private: SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, SkScalar baseFrequencyX, SkScalar baseFrequencyY, int numOctaves, SkScalar seed, - const SkISize* tileSize = NULL); + const SkISize* tileSize); virtual ~SkPerlinNoiseShader(); - void setTileSize(const SkISize&); - - void initPaint(PaintingData& paintingData); - SkScalar noise2D(int channel, const PaintingData& paintingData, - const StitchData& stitchData, const SkPoint& noiseVector); + const StitchData& stitchData, const SkPoint& noiseVector) const; SkScalar calculateTurbulenceValueForPoint(int channel, const PaintingData& paintingData, - StitchData& stitchData, const SkPoint& point); + StitchData& stitchData, const SkPoint& point) const; - SkPMColor shade(const SkPoint& point, StitchData& stitchData); + SkPMColor shade(const SkPoint& point, StitchData& stitchData) const; - SkPerlinNoiseShader::Type fType; - SkScalar fBaseFrequencyX; - SkScalar fBaseFrequencyY; - int fNumOctaves; - SkScalar fSeed; - SkISize fTileSize; - bool fStitchTiles; + // TODO (scroggo): Once all SkShaders are created from a factory, and we have removed the + // constructor that creates SkPerlinNoiseShader from an SkReadBuffer, several fields can + // be made constant. + /*const*/ SkPerlinNoiseShader::Type fType; + /*const*/ SkScalar fBaseFrequencyX; + /*const*/ SkScalar fBaseFrequencyY; + /*const*/ int fNumOctaves; + /*const*/ SkScalar fSeed; + /*const*/ SkISize fTileSize; + /*const*/ bool fStitchTiles; + // TODO (scroggo): Once setContext creates a new object, place this on that object. SkMatrix fMatrix; PaintingData* fPaintingData; diff --git a/gfx/skia/trunk/include/effects/SkPictureImageFilter.h b/gfx/skia/trunk/include/effects/SkPictureImageFilter.h index a10d23eebb24..37da208347c2 100644 --- a/gfx/skia/trunk/include/effects/SkPictureImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkPictureImageFilter.h @@ -16,13 +16,17 @@ public: /** * Refs the passed-in picture. */ - explicit SkPictureImageFilter(SkPicture* picture); + static SkPictureImageFilter* Create(SkPicture* picture) { + return SkNEW_ARGS(SkPictureImageFilter, (picture)); + } /** - * Refs the passed-in picture. rect can be used to crop or expand the destination rect when + * Refs the passed-in picture. cropRect can be used to crop or expand the destination rect when * the picture is drawn. (No scaling is implied by the dest rect; only the CTM is applied.) */ - SkPictureImageFilter(SkPicture* picture, const SkRect& rect); + static SkPictureImageFilter* Create(SkPicture* picture, const SkRect& cropRect) { + return SkNEW_ARGS(SkPictureImageFilter, (picture, cropRect)); + } SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureImageFilter) @@ -36,12 +40,18 @@ protected: */ explicit SkPictureImageFilter(SkReadBuffer&); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + explicit SkPictureImageFilter(SkPicture* picture); + SkPictureImageFilter(SkPicture* picture, const SkRect& cropRect); + private: SkPicture* fPicture; - SkRect fRect; + SkRect fCropRect; typedef SkImageFilter INHERITED; }; diff --git a/gfx/skia/trunk/include/effects/SkPixelXorXfermode.h b/gfx/skia/trunk/include/effects/SkPixelXorXfermode.h index 9472d9426e3b..837257ec2c71 100644 --- a/gfx/skia/trunk/include/effects/SkPixelXorXfermode.h +++ b/gfx/skia/trunk/include/effects/SkPixelXorXfermode.h @@ -17,9 +17,11 @@ */ class SK_API SkPixelXorXfermode : public SkXfermode { public: - SkPixelXorXfermode(SkColor opColor) : fOpColor(opColor) {} + static SkPixelXorXfermode* Create(SkColor opColor) { + return SkNEW_ARGS(SkPixelXorXfermode, (opColor)); + } - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPixelXorXfermode) protected: @@ -29,6 +31,11 @@ protected: // override from SkXfermode virtual SkPMColor xferColor(SkPMColor src, SkPMColor dst) const; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkPixelXorXfermode(SkColor opColor) : fOpColor(opColor) {} + private: SkColor fOpColor; diff --git a/gfx/skia/trunk/include/effects/SkRectShaderImageFilter.h b/gfx/skia/trunk/include/effects/SkRectShaderImageFilter.h index 23c538e6883b..817c44e95f2d 100644 --- a/gfx/skia/trunk/include/effects/SkRectShaderImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkRectShaderImageFilter.h @@ -37,7 +37,7 @@ protected: SkRectShaderImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; private: diff --git a/gfx/skia/trunk/include/effects/SkResizeImageFilter.h b/gfx/skia/trunk/include/effects/SkResizeImageFilter.h index cc02a01d03e2..fb55eea42c29 100644 --- a/gfx/skia/trunk/include/effects/SkResizeImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkResizeImageFilter.h @@ -21,6 +21,8 @@ class SK_API SkResizeImageFilter : public SkImageFilter { public: + virtual ~SkResizeImageFilter(); + /** Construct a (scaling-only) resampling image filter. * @param sx The x scale parameter to apply when resizing. * @param sy The y scale parameter to apply when resizing. @@ -28,10 +30,12 @@ public: * @param input The input image filter. If NULL, the src bitmap * passed to filterImage() is used instead. */ + static SkResizeImageFilter* Create(SkScalar sx, SkScalar sy, SkPaint::FilterLevel filterLevel, + SkImageFilter* input = NULL) { + return SkNEW_ARGS(SkResizeImageFilter, (sx, sy, filterLevel, input)); + } - SkResizeImageFilter(SkScalar sx, SkScalar sy, SkPaint::FilterLevel filterLevel, - SkImageFilter* input = NULL); - virtual ~SkResizeImageFilter(); + virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkResizeImageFilter) @@ -39,8 +43,16 @@ protected: SkResizeImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; + virtual bool onFilterBounds(const SkIRect& src, const SkMatrix&, + SkIRect* dst) const SK_OVERRIDE; + +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkResizeImageFilter(SkScalar sx, SkScalar sy, SkPaint::FilterLevel filterLevel, + SkImageFilter* input = NULL); private: SkScalar fSx, fSy; diff --git a/gfx/skia/trunk/include/effects/SkStippleMaskFilter.h b/gfx/skia/trunk/include/effects/SkStippleMaskFilter.h index ee32ae1fe35e..d6f87988627b 100644 --- a/gfx/skia/trunk/include/effects/SkStippleMaskFilter.h +++ b/gfx/skia/trunk/include/effects/SkStippleMaskFilter.h @@ -15,7 +15,8 @@ */ class SK_API SkStippleMaskFilter : public SkMaskFilter { public: - SkStippleMaskFilter() : INHERITED() { + static SkStippleMaskFilter* Create() { + return SkNEW(SkStippleMaskFilter); } virtual bool filterMask(SkMask* dst, const SkMask& src, @@ -27,7 +28,7 @@ public: return SkMask::kA8_Format; } - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkStippleMaskFilter); protected: @@ -35,6 +36,12 @@ protected: : SkMaskFilter(buffer) { } +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkStippleMaskFilter() : INHERITED() { + } + private: typedef SkMaskFilter INHERITED; }; diff --git a/gfx/skia/trunk/include/effects/SkTableMaskFilter.h b/gfx/skia/trunk/include/effects/SkTableMaskFilter.h index 1c2bbd7a1b6c..d517db6994f7 100644 --- a/gfx/skia/trunk/include/effects/SkTableMaskFilter.h +++ b/gfx/skia/trunk/include/effects/SkTableMaskFilter.h @@ -18,8 +18,6 @@ */ class SK_API SkTableMaskFilter : public SkMaskFilter { public: - SkTableMaskFilter(); - SkTableMaskFilter(const uint8_t table[256]); virtual ~SkTableMaskFilter(); /** Utility that sets the gamma table @@ -31,6 +29,10 @@ public: */ static void MakeClipTable(uint8_t table[256], uint8_t min, uint8_t max); + static SkTableMaskFilter* Create(const uint8_t table[256]) { + return SkNEW_ARGS(SkTableMaskFilter, (table)); + } + static SkTableMaskFilter* CreateGamma(SkScalar gamma) { uint8_t table[256]; MakeGammaTable(table, gamma); @@ -47,13 +49,19 @@ public: virtual bool filterMask(SkMask*, const SkMask&, const SkMatrix&, SkIPoint*) const SK_OVERRIDE; - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTableMaskFilter) protected: SkTableMaskFilter(SkReadBuffer& rb); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkTableMaskFilter(); + SkTableMaskFilter(const uint8_t table[256]); + private: uint8_t fTable[256]; diff --git a/gfx/skia/trunk/include/effects/SkTestImageFilters.h b/gfx/skia/trunk/include/effects/SkTestImageFilters.h index abbaa92593e1..4b20936c3bf3 100644 --- a/gfx/skia/trunk/include/effects/SkTestImageFilters.h +++ b/gfx/skia/trunk/include/effects/SkTestImageFilters.h @@ -7,15 +7,18 @@ // Fun mode that scales down (only) and then scales back up to look pixelated class SK_API SkDownSampleImageFilter : public SkImageFilter { public: - SkDownSampleImageFilter(SkScalar scale) : INHERITED(0), fScale(scale) {} + static SkDownSampleImageFilter* Create(SkScalar scale) { + return SkNEW_ARGS(SkDownSampleImageFilter, (scale)); + } SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDownSampleImageFilter) protected: + SkDownSampleImageFilter(SkScalar scale) : INHERITED(0), fScale(scale) {} SkDownSampleImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* loc) const SK_OVERRIDE; private: diff --git a/gfx/skia/trunk/include/effects/SkTileImageFilter.h b/gfx/skia/trunk/include/effects/SkTileImageFilter.h index 390e00c9a47a..6c0fa68f3cd9 100644 --- a/gfx/skia/trunk/include/effects/SkTileImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkTileImageFilter.h @@ -14,15 +14,17 @@ class SK_API SkTileImageFilter : public SkImageFilter { typedef SkImageFilter INHERITED; public: - /** Tile image filter constructor + /** Create a tile image filter @param srcRect Defines the pixels to tile @param dstRect Defines the pixels where tiles are drawn @param input Input from which the subregion defined by srcRect will be tiled */ - SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input) - : INHERITED(input), fSrcRect(srcRect), fDstRect(dstRect) {} + static SkTileImageFilter* Create(const SkRect& srcRect, const SkRect& dstRect, + SkImageFilter* input) { + return SkNEW_ARGS(SkTileImageFilter, (srcRect, dstRect, input)); + } - virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, + virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTileImageFilter) @@ -32,6 +34,12 @@ protected: virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, SkImageFilter* input) + : INHERITED(input), fSrcRect(srcRect), fDstRect(dstRect) {} + private: SkRect fSrcRect; SkRect fDstRect; diff --git a/gfx/skia/trunk/include/effects/SkTransparentShader.h b/gfx/skia/trunk/include/effects/SkTransparentShader.h index 2b3f99814aa2..7428d442e3f6 100644 --- a/gfx/skia/trunk/include/effects/SkTransparentShader.h +++ b/gfx/skia/trunk/include/effects/SkTransparentShader.h @@ -21,7 +21,7 @@ public: virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTransparentShader) private: diff --git a/gfx/skia/trunk/include/effects/SkXfermodeImageFilter.h b/gfx/skia/trunk/include/effects/SkXfermodeImageFilter.h index 602dc4840493..cacd9b00b862 100644 --- a/gfx/skia/trunk/include/effects/SkXfermodeImageFilter.h +++ b/gfx/skia/trunk/include/effects/SkXfermodeImageFilter.h @@ -21,21 +21,24 @@ class SK_API SkXfermodeImageFilter : public SkImageFilter { */ public: - SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* background, - SkImageFilter* foreground = NULL, const CropRect* cropRect = NULL); - virtual ~SkXfermodeImageFilter(); + static SkXfermodeImageFilter* Create(SkXfermode* mode, SkImageFilter* background, + SkImageFilter* foreground = NULL, + const CropRect* cropRect = NULL) { + return SkNEW_ARGS(SkXfermodeImageFilter, (mode, background, foreground, cropRect)); + } + SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkXfermodeImageFilter) virtual bool onFilterImage(Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* dst, SkIPoint* offset) const SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool canFilterImageGPU() const SK_OVERRIDE { return !cropRectIsSet(); } - virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, + virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #endif @@ -43,6 +46,12 @@ protected: explicit SkXfermodeImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS +public: +#endif + SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* background, + SkImageFilter* foreground = NULL, const CropRect* cropRect = NULL); + private: SkXfermode* fMode; typedef SkImageFilter INHERITED; diff --git a/gfx/skia/trunk/include/gpu/GrBitmapTextContext.h b/gfx/skia/trunk/include/gpu/GrBitmapTextContext.h deleted file mode 100644 index e0900ecd7d62..000000000000 --- a/gfx/skia/trunk/include/gpu/GrBitmapTextContext.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrBitmapTextContext_DEFINED -#define GrBitmapTextContext_DEFINED - -#include "GrTextContext.h" - -class GrTextStrike; - -/* - * This class implements GrTextContext using standard bitmap fonts - */ -class GrBitmapTextContext : public GrTextContext { -public: - GrBitmapTextContext(GrContext*, const GrPaint&, SkColor); - virtual ~GrBitmapTextContext(); - - virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top, - GrFontScaler*) SK_OVERRIDE; - -private: - GrContext::AutoMatrix fAutoMatrix; - GrTextStrike* fStrike; - - void flushGlyphs(); // automatically called by destructor - - enum { - kMinRequestedGlyphs = 1, - kDefaultRequestedGlyphs = 64, - kMinRequestedVerts = kMinRequestedGlyphs * 4, - kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4, - }; - - SkColor fSkPaintColor; - SkPoint* fVertices; - int32_t fMaxVertices; - GrTexture* fCurrTexture; - int fCurrVertex; -}; - -#endif diff --git a/gfx/skia/trunk/include/gpu/GrContext.h b/gfx/skia/trunk/include/gpu/GrContext.h index ad3789b1a8ba..183458657828 100644 --- a/gfx/skia/trunk/include/gpu/GrContext.h +++ b/gfx/skia/trunk/include/gpu/GrContext.h @@ -306,6 +306,19 @@ public: */ int getMaxSampleCount() const; + /** + * Returns the recommended sample count for a render target when using this + * context. + * + * @param config the configuration of the render target. + * @param dpi the display density in dots per inch. + * + * @return sample count that should be perform well and have good enough + * rendering quality for the display. Alternatively returns 0 if + * MSAA is not supported or recommended to be used by default. + */ + int getRecommendedSampleCount(GrPixelConfig config, SkScalar dpi) const; + /////////////////////////////////////////////////////////////////////////// // Backend Surfaces diff --git a/gfx/skia/trunk/include/gpu/GrDistanceFieldTextContext.h b/gfx/skia/trunk/include/gpu/GrDistanceFieldTextContext.h deleted file mode 100644 index 217faf3cb021..000000000000 --- a/gfx/skia/trunk/include/gpu/GrDistanceFieldTextContext.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrDistanceFieldTextContext_DEFINED -#define GrDistanceFieldTextContext_DEFINED - -#include "GrTextContext.h" - -class GrTextStrike; - -/* - * This class implements GrTextContext using distance field fonts - */ -class GrDistanceFieldTextContext : public GrTextContext { -public: - GrDistanceFieldTextContext(GrContext*, const GrPaint&, SkColor, SkScalar textRatio); - virtual ~GrDistanceFieldTextContext(); - - virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top, - GrFontScaler*) SK_OVERRIDE; - -private: - GrTextStrike* fStrike; - SkScalar fTextRatio; - - void flushGlyphs(); // automatically called by destructor - - enum { - kMinRequestedGlyphs = 1, - kDefaultRequestedGlyphs = 64, - kMinRequestedVerts = kMinRequestedGlyphs * 4, - kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4, - }; - - SkColor fSkPaintColor; - SkPoint* fVertices; - int32_t fMaxVertices; - GrTexture* fCurrTexture; - int fCurrVertex; -}; - -#endif diff --git a/gfx/skia/trunk/include/gpu/GrTBackendEffectFactory.h b/gfx/skia/trunk/include/gpu/GrTBackendEffectFactory.h index 3711c7e86939..fd14b4fa8ecc 100644 --- a/gfx/skia/trunk/include/gpu/GrTBackendEffectFactory.h +++ b/gfx/skia/trunk/include/gpu/GrTBackendEffectFactory.h @@ -64,7 +64,7 @@ public: /** Returns a new instance of the appropriate *GL* implementation class for the given GrEffect; caller is responsible for deleting the object. */ - virtual GLEffect* createGLInstance(const GrDrawEffect& drawEffect) const SK_OVERRIDE { + virtual GrGLEffect* createGLInstance(const GrDrawEffect& drawEffect) const SK_OVERRIDE { return SkNEW_ARGS(GLEffect, (*this, drawEffect)); } diff --git a/gfx/skia/trunk/include/gpu/GrTextContext.h b/gfx/skia/trunk/include/gpu/GrTextContext.h deleted file mode 100644 index b367cf228d57..000000000000 --- a/gfx/skia/trunk/include/gpu/GrTextContext.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrTextContext_DEFINED -#define GrTextContext_DEFINED - -#include "GrContext.h" -#include "GrGlyph.h" -#include "GrPaint.h" - -class GrContext; -class GrDrawTarget; -class GrFontScaler; - -/* - * This class wraps the state for a single text render - */ -class GrTextContext { -public: - virtual void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top, - GrFontScaler*) = 0; - -protected: - GrTextContext(GrContext*, const GrPaint&); - virtual ~GrTextContext() {} - - GrPaint fPaint; - GrContext* fContext; - GrDrawTarget* fDrawTarget; - - SkIRect fClipRect; - -private: -}; - -#endif diff --git a/gfx/skia/trunk/include/gpu/GrTypesPriv.h b/gfx/skia/trunk/include/gpu/GrTypesPriv.h index 8888066d4faa..5a220459fd8c 100644 --- a/gfx/skia/trunk/include/gpu/GrTypesPriv.h +++ b/gfx/skia/trunk/include/gpu/GrTypesPriv.h @@ -60,6 +60,8 @@ static inline GrSLType GrSLFloatVectorType(int count) { GR_STATIC_ASSERT(kVec4f_GrSLType == 4); } +////////////////////////////////////////////////////////////////////////////// + /** * Types used to describe format of vertices in arrays. */ @@ -166,4 +168,53 @@ struct GrVertexAttrib { template class GrVertexAttribArray : public SkSTArray {}; +////////////////////////////////////////////////////////////////////////////// + +/** +* We have coverage effects that clip rendering to the edge of some geometric primitive. +* This enum specifies how that clipping is performed. Not all factories that take a +* GrEffectEdgeType will succeed with all values and it is up to the caller to check for +* a NULL return. +*/ +enum GrEffectEdgeType { + kFillBW_GrEffectEdgeType, + kFillAA_GrEffectEdgeType, + kInverseFillBW_GrEffectEdgeType, + kInverseFillAA_GrEffectEdgeType, + kHairlineAA_GrEffectEdgeType, + + kLast_GrEffectEdgeType = kHairlineAA_GrEffectEdgeType +}; + +static const int kGrEffectEdgeTypeCnt = kLast_GrEffectEdgeType + 1; + +static inline bool GrEffectEdgeTypeIsFill(const GrEffectEdgeType edgeType) { + return (kFillAA_GrEffectEdgeType == edgeType || kFillBW_GrEffectEdgeType == edgeType); +} + +static inline bool GrEffectEdgeTypeIsInverseFill(const GrEffectEdgeType edgeType) { + return (kInverseFillAA_GrEffectEdgeType == edgeType || + kInverseFillBW_GrEffectEdgeType == edgeType); +} + +static inline bool GrEffectEdgeTypeIsAA(const GrEffectEdgeType edgeType) { + return (kFillBW_GrEffectEdgeType != edgeType && kInverseFillBW_GrEffectEdgeType != edgeType); +} + +static inline GrEffectEdgeType GrInvertEffectEdgeType(const GrEffectEdgeType edgeType) { + switch (edgeType) { + case kFillBW_GrEffectEdgeType: + return kInverseFillBW_GrEffectEdgeType; + case kFillAA_GrEffectEdgeType: + return kInverseFillAA_GrEffectEdgeType; + case kInverseFillBW_GrEffectEdgeType: + return kFillBW_GrEffectEdgeType; + case kInverseFillAA_GrEffectEdgeType: + return kFillAA_GrEffectEdgeType; + case kHairlineAA_GrEffectEdgeType: + GrCrash("Hairline fill isn't invertible."); + } + return kFillAA_GrEffectEdgeType; // suppress warning. +} + #endif diff --git a/gfx/skia/trunk/include/gpu/SkGpuDevice.h b/gfx/skia/trunk/include/gpu/SkGpuDevice.h index 8b2170da6dbc..7394361ff135 100644 --- a/gfx/skia/trunk/include/gpu/SkGpuDevice.h +++ b/gfx/skia/trunk/include/gpu/SkGpuDevice.h @@ -14,6 +14,7 @@ #include "SkGr.h" #include "SkBitmap.h" #include "SkBitmapDevice.h" +#include "SkPicture.h" #include "SkRegion.h" #include "GrContext.h" @@ -35,6 +36,15 @@ public: */ static SkGpuDevice* Create(GrSurface* surface); + /** + * New device that will create an offscreen renderTarget based on the + * ImageInfo and sampleCount. The device's storage will not + * count against the GrContext's texture cache budget. The device's pixels + * will be uninitialized. On failure, returns NULL. + */ + static SkGpuDevice* Create(GrContext*, const SkImageInfo&, int sampleCount); + +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG /** * New device that will create an offscreen renderTarget based on the * config, width, height, and sampleCount. The device's storage will not @@ -42,6 +52,7 @@ public: * will be uninitialized. TODO: This can fail, replace with a factory function. */ SkGpuDevice(GrContext*, SkBitmap::Config, int width, int height, int sampleCount = 0); +#endif /** * DEPRECATED -- need to make this private, call Create(surface) @@ -64,9 +75,6 @@ public: virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE; // overrides from SkBaseDevice - virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { - return 0; - } virtual int width() const SK_OVERRIDE { return NULL == fRenderTarget ? 0 : fRenderTarget->width(); } @@ -80,9 +88,10 @@ public: virtual SkBitmap::Config config() const SK_OVERRIDE; virtual void clear(SkColor color) SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG virtual void writePixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) SK_OVERRIDE; - +#endif virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, const SkPoint[], const SkPaint& paint) SK_OVERRIDE; @@ -132,16 +141,21 @@ public: virtual void makeRenderTargetCurrent(); virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE; - virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkMatrix&, + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, + const SkImageFilter::Context&, SkBitmap*, SkIPoint*) SK_OVERRIDE; class SkAutoCachedTexture; // used internally + protected: - // overrides from SkBaseDevice - virtual bool onReadPixels(const SkBitmap& bitmap, - int x, int y, - SkCanvas::Config8888 config8888) SK_OVERRIDE; + virtual bool onReadPixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) SK_OVERRIDE; + virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int, int) SK_OVERRIDE; + + /** PRIVATE / EXPERIMENTAL -- do not call */ + virtual void EXPERIMENTAL_optimize(SkPicture* picture) SK_OVERRIDE; + /** PRIVATE / EXPERIMENTAL -- do not call */ + virtual bool EXPERIMENTAL_drawPicture(const SkPicture& picture) SK_OVERRIDE; private: GrContext* fContext; @@ -163,11 +177,7 @@ private: // used by createCompatibleDevice SkGpuDevice(GrContext*, GrTexture* texture, bool needClear); - // override from SkBaseDevice - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) SK_OVERRIDE; + virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE; @@ -212,6 +222,8 @@ private: int tileSize, bool bicubic); + static SkPicture::AccelData::Key ComputeAccelDataKey(); + typedef SkBitmapDevice INHERITED; }; diff --git a/gfx/skia/trunk/include/gpu/SkGr.h b/gfx/skia/trunk/include/gpu/SkGr.h index db08548f5d54..6cfa0faedfaf 100644 --- a/gfx/skia/trunk/include/gpu/SkGr.h +++ b/gfx/skia/trunk/include/gpu/SkGr.h @@ -50,6 +50,7 @@ GR_STATIC_ASSERT((int)kIDA_GrBlendCoeff == (int)SkXfermode::kIDA_Coeff); * kUnknown_PixelConfig if the conversion cannot be done. */ GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config); +GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType, SkAlphaType); bool GrPixelConfig2ColorType(GrPixelConfig, SkColorType*); static inline GrColor SkColor2GrColor(SkColor c) { diff --git a/gfx/skia/trunk/include/gpu/gl/GrGLExtensions.h b/gfx/skia/trunk/include/gpu/gl/GrGLExtensions.h index 76516cf11f9f..89adadfc48ec 100644 --- a/gfx/skia/trunk/include/gpu/gl/GrGLExtensions.h +++ b/gfx/skia/trunk/include/gpu/gl/GrGLExtensions.h @@ -19,7 +19,7 @@ struct GrGLInterface; * queried. It supports both glGetString- and glGetStringi-style extension string APIs and will * use the latter if it is available. */ -class GrGLExtensions { +class SK_API GrGLExtensions { public: GrGLExtensions() : fInitialized(false), fStrings(SkNEW(SkTArray)) {} @@ -54,6 +54,11 @@ public: */ bool remove(const char[]); + /** + * Adds an extension to list + */ + void add(const char[]); + void reset() { fStrings->reset(); } void print(const char* sep = "\n") const; diff --git a/gfx/skia/trunk/include/gpu/gl/GrGLFunctions.h b/gfx/skia/trunk/include/gpu/gl/GrGLFunctions.h index b6d68c7ff4bd..a896800d6b73 100644 --- a/gfx/skia/trunk/include/gpu/gl/GrGLFunctions.h +++ b/gfx/skia/trunk/include/gpu/gl/GrGLFunctions.h @@ -23,11 +23,6 @@ enum GrGLStandard { kGLES_GrGLStandard, }; -// Temporary aliases until Chromium can be updated. -typedef GrGLStandard GrGLBinding; -static const GrGLStandard kES2_GrGLBinding = kGLES_GrGLStandard; -static const GrGLStandard kDesktop_GrGLBinding = kGL_GrGLStandard; - /////////////////////////////////////////////////////////////////////////////// /** @@ -106,14 +101,12 @@ extern "C" { typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDeleteVertexArraysProc)(GrGLsizei n, const GrGLuint *arrays); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDepthMaskProc)(GrGLboolean flag); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDisableProc)(GrGLenum cap); - typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDisableClientStateProc)(GrGLenum cap); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDisableVertexAttribArrayProc)(GrGLuint index); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawArraysProc)(GrGLenum mode, GrGLint first, GrGLsizei count); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawBufferProc)(GrGLenum mode); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawBuffersProc)(GrGLsizei n, const GrGLenum* bufs); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLDrawElementsProc)(GrGLenum mode, GrGLsizei count, GrGLenum type, const GrGLvoid* indices); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableProc)(GrGLenum cap); - typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableClientStateProc)(GrGLenum cap); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEnableVertexAttribArrayProc)(GrGLuint index); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLEndQueryProc)(GrGLenum target); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLFinishProc)(); @@ -147,10 +140,13 @@ extern "C" { typedef const GrGLubyte* (GR_GL_FUNCTION_TYPE* GrGLGetStringiProc)(GrGLenum name, GrGLuint index); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLGetTexLevelParameterivProc)(GrGLenum target, GrGLint level, GrGLenum pname, GrGLint* params); typedef GrGLint (GR_GL_FUNCTION_TYPE* GrGLGetUniformLocationProc)(GrGLuint program, const char* name); + typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLInsertEventMarkerProc)(GrGLsizei length, const char* marker); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLLineWidthProc)(GrGLfloat width); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLLinkProgramProc)(GrGLuint program); typedef GrGLvoid* (GR_GL_FUNCTION_TYPE* GrGLMapBufferProc)(GrGLenum target, GrGLenum access); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPixelStoreiProc)(GrGLenum pname, GrGLint param); + typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPopGroupMarkerProc)(); + typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPushGroupMarkerProc)(GrGLsizei length, const char* marker); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLQueryCounterProc)(GrGLuint id, GrGLenum target); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLReadBufferProc)(GrGLenum src); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLReadPixelsProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, GrGLvoid* pixels); @@ -203,7 +199,6 @@ extern "C" { typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLUseProgramProc)(GrGLuint program); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttrib4fvProc)(GrGLuint indx, const GrGLfloat* values); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexAttribPointerProc)(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr); - typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLVertexPointerProc)(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer); typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLViewportProc)(GrGLint x, GrGLint y, GrGLsizei width, GrGLsizei height); // Experimental: Functions for GL_NV_path_rendering. These will be @@ -261,6 +256,7 @@ extern "C" { typedef GrGLboolean (GR_GL_FUNCTION_TYPE* GrGLIsPointInStrokePathProc)(GrGLuint path, GrGLfloat x, GrGLfloat y); typedef GrGLfloat (GR_GL_FUNCTION_TYPE* GrGLGetPathLengthProc)(GrGLuint path, GrGLsizei startSegment, GrGLsizei numSegments); typedef GrGLboolean (GR_GL_FUNCTION_TYPE* GrGLPointAlongPathProc)(GrGLuint path, GrGLsizei startSegment, GrGLsizei numSegments, GrGLfloat distance, GrGLfloat *x, GrGLfloat *y, GrGLfloat *tangentX, GrGLfloat *tangentY); + } // extern "C" #endif diff --git a/gfx/skia/trunk/include/gpu/gl/GrGLInterface.h b/gfx/skia/trunk/include/gpu/gl/GrGLInterface.h index f5bcd16682a9..3d34ae65bf25 100644 --- a/gfx/skia/trunk/include/gpu/gl/GrGLInterface.h +++ b/gfx/skia/trunk/include/gpu/gl/GrGLInterface.h @@ -76,6 +76,13 @@ typedef intptr_t GrGLInterfaceCallbackData; GL_NV_path_rendering. */ const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface*); +/** Function that returns a new interface identical to "interface" but with support for + test version of GL_EXT_debug_marker. */ +const GrGLInterface* GrGLInterfaceAddTestDebugMarker(const GrGLInterface*, + GrGLInsertEventMarkerProc insertEventMarkerFn, + GrGLPushGroupMarkerProc pushGroupMarkerFn, + GrGLPopGroupMarkerProc popGroupMarkerFn); + /** * GrContext uses the following interface to make all calls into OpenGL. When a * GrContext is created it is given a GrGLInterface. The interface's function @@ -131,18 +138,7 @@ public: GrGLExtensions fExtensions; - // This wrapper and const hackery is necessary because the factories in Chromium do not yet - // initialize fExtensions. - bool hasExtension(const char ext[]) const { - if (!fExtensions.isInitialized()) { - GrGLExtensions* extensions = const_cast(&fExtensions); - if (!extensions->init(fStandard, fFunctions.fGetString, - fFunctions.fGetStringi, fFunctions.fGetIntegerv)) { - return false; - } - } - return fExtensions.has(ext); - } + bool hasExtension(const char ext[]) const { return fExtensions.has(ext); } /** * The function pointers are in a struct so that we can have a compiler generated assignment @@ -169,7 +165,6 @@ public: GLPtr fClear; GLPtr fClearColor; GLPtr fClearStencil; - GLPtr fClientActiveTexture; GLPtr fColorMask; GLPtr fCompileShader; GLPtr fCompressedTexImage2D; @@ -187,14 +182,12 @@ public: GLPtr fDeleteVertexArrays; GLPtr fDepthMask; GLPtr fDisable; - GLPtr fDisableClientState; GLPtr fDisableVertexAttribArray; GLPtr fDrawArrays; GLPtr fDrawBuffer; GLPtr fDrawBuffers; GLPtr fDrawElements; GLPtr fEnable; - GLPtr fEnableClientState; GLPtr fEnableVertexAttribArray; GLPtr fEndQuery; GLPtr fFinish; @@ -228,6 +221,7 @@ public: GLPtr fGetStringi; GLPtr fGetTexLevelParameteriv; GLPtr fGetUniformLocation; + GLPtr fInsertEventMarker; GLPtr fLineWidth; GLPtr fLinkProgram; GLPtr fLoadIdentity; @@ -235,6 +229,8 @@ public: GLPtr fMapBuffer; GLPtr fMatrixMode; GLPtr fPixelStorei; + GLPtr fPopGroupMarker; + GLPtr fPushGroupMarker; GLPtr fQueryCounter; GLPtr fReadBuffer; GLPtr fReadPixels; @@ -275,7 +271,6 @@ public: GLPtr fStencilMaskSeparate; GLPtr fStencilOp; GLPtr fStencilOpSeparate; - GLPtr fTexGenf; GLPtr fTexGenfv; GLPtr fTexGeni; GLPtr fTexImage2D; @@ -307,7 +302,6 @@ public: GLPtr fUseProgram; GLPtr fVertexAttrib4fv; GLPtr fVertexAttribPointer; - GLPtr fVertexPointer; GLPtr fViewport; // Experimental: Functions for GL_NV_path_rendering. These will be @@ -364,201 +358,11 @@ public: GLPtr fPointAlongPath; } fFunctions; - // Temporary workaround aliases to keep Chromium GrGLInterface factories compiling until they - // assign the members of fFunctions. - GLPtrAlias fActiveTexture; - GLPtrAlias fAttachShader; - GLPtrAlias fBeginQuery; - GLPtrAlias fBindAttribLocation; - GLPtrAlias fBindBuffer; - GLPtrAlias fBindFragDataLocation; - GLPtrAlias fBindFragDataLocationIndexed; - GLPtrAlias fBindFramebuffer; - GLPtrAlias fBindRenderbuffer; - GLPtrAlias fBindTexture; - GLPtrAlias fBindVertexArray; - GLPtrAlias fBlendColor; - GLPtrAlias fBlendFunc; - GLPtrAlias fBlitFramebuffer; - GLPtrAlias fBufferData; - GLPtrAlias fBufferSubData; - GLPtrAlias fCheckFramebufferStatus; - GLPtrAlias fClear; - GLPtrAlias fClearColor; - GLPtrAlias fClearStencil; - GLPtrAlias fClientActiveTexture; - GLPtrAlias fColorMask; - GLPtrAlias fCompileShader; - GLPtrAlias fCompressedTexImage2D; - GLPtrAlias fCopyTexSubImage2D; - GLPtrAlias fCreateProgram; - GLPtrAlias fCreateShader; - GLPtrAlias fCullFace; - GLPtrAlias fDeleteBuffers; - GLPtrAlias fDeleteFramebuffers; - GLPtrAlias fDeleteProgram; - GLPtrAlias fDeleteQueries; - GLPtrAlias fDeleteRenderbuffers; - GLPtrAlias fDeleteShader; - GLPtrAlias fDeleteTextures; - GLPtrAlias fDeleteVertexArrays; - GLPtrAlias fDepthMask; - GLPtrAlias fDisable; - GLPtrAlias fDisableClientState; - GLPtrAlias fDisableVertexAttribArray; - GLPtrAlias fDrawArrays; - GLPtrAlias fDrawBuffer; - GLPtrAlias fDrawBuffers; - GLPtrAlias fDrawElements; - GLPtrAlias fEnable; - GLPtrAlias fEnableClientState; - GLPtrAlias fEnableVertexAttribArray; - GLPtrAlias fEndQuery; - GLPtrAlias fFinish; - GLPtrAlias fFlush; - GLPtrAlias fFramebufferRenderbuffer; - GLPtrAlias fFramebufferTexture2D; - GLPtrAlias fFramebufferTexture2DMultisample; - GLPtrAlias fFrontFace; - GLPtrAlias fGenBuffers; - GLPtrAlias fGenFramebuffers; - GLPtrAlias fGenerateMipmap; - GLPtrAlias fGenQueries; - GLPtrAlias fGenRenderbuffers; - GLPtrAlias fGenTextures; - GLPtrAlias fGenVertexArrays; - GLPtrAlias fGetBufferParameteriv; - GLPtrAlias fGetError; - GLPtrAlias fGetFramebufferAttachmentParameteriv; - GLPtrAlias fGetIntegerv; - GLPtrAlias fGetQueryObjecti64v; - GLPtrAlias fGetQueryObjectiv; - GLPtrAlias fGetQueryObjectui64v; - GLPtrAlias fGetQueryObjectuiv; - GLPtrAlias fGetQueryiv; - GLPtrAlias fGetProgramInfoLog; - GLPtrAlias fGetProgramiv; - GLPtrAlias fGetRenderbufferParameteriv; - GLPtrAlias fGetShaderInfoLog; - GLPtrAlias fGetShaderiv; - GLPtrAlias fGetString; - GLPtrAlias fGetStringi; - GLPtrAlias fGetTexLevelParameteriv; - GLPtrAlias fGetUniformLocation; - GLPtrAlias fLineWidth; - GLPtrAlias fLinkProgram; - GLPtrAlias fLoadIdentity; - GLPtrAlias fLoadMatrixf; - GLPtrAlias fMapBuffer; - GLPtrAlias fMatrixMode; - GLPtrAlias fPixelStorei; - GLPtrAlias fQueryCounter; - GLPtrAlias fReadBuffer; - GLPtrAlias fReadPixels; - GLPtrAlias fRenderbufferStorage; - GLPtrAlias fRenderbufferStorageMultisampleES2EXT; - GLPtrAlias fRenderbufferStorageMultisampleES2APPLE; - GLPtrAlias fRenderbufferStorageMultisample; - GLPtrAlias fBindUniformLocation; - GLPtrAlias fResolveMultisampleFramebuffer; - GLPtrAlias fScissor; - GLPtrAlias fShaderSource; - GLPtrAlias fStencilFunc; - GLPtrAlias fStencilFuncSeparate; - GLPtrAlias fStencilMask; - GLPtrAlias fStencilMaskSeparate; - GLPtrAlias fStencilOp; - GLPtrAlias fStencilOpSeparate; - GLPtrAlias fTexGenf; - GLPtrAlias fTexGenfv; - GLPtrAlias fTexGeni; - GLPtrAlias fTexImage2D; - GLPtrAlias fTexParameteri; - GLPtrAlias fTexParameteriv; - GLPtrAlias fTexSubImage2D; - GLPtrAlias fTexStorage2D; - GLPtrAlias fDiscardFramebuffer; - GLPtrAlias fUniform1f; - GLPtrAlias fUniform1i; - GLPtrAlias fUniform1fv; - GLPtrAlias fUniform1iv; - GLPtrAlias fUniform2f; - GLPtrAlias fUniform2i; - GLPtrAlias fUniform2fv; - GLPtrAlias fUniform2iv; - GLPtrAlias fUniform3f; - GLPtrAlias fUniform3i; - GLPtrAlias fUniform3fv; - GLPtrAlias fUniform3iv; - GLPtrAlias fUniform4f; - GLPtrAlias fUniform4i; - GLPtrAlias fUniform4fv; - GLPtrAlias fUniform4iv; - GLPtrAlias fUniformMatrix2fv; - GLPtrAlias fUniformMatrix3fv; - GLPtrAlias fUniformMatrix4fv; - GLPtrAlias fUnmapBuffer; - GLPtrAlias fUseProgram; - GLPtrAlias fVertexAttrib4fv; - GLPtrAlias fVertexAttribPointer; - GLPtrAlias fVertexPointer; - GLPtrAlias fViewport; - GLPtrAlias fPathCommands; - GLPtrAlias fPathCoords; - GLPtrAlias fPathSubCommands; - GLPtrAlias fPathSubCoords; - GLPtrAlias fPathString; - GLPtrAlias fPathGlyphs; - GLPtrAlias fPathGlyphRange; - GLPtrAlias fWeightPaths; - GLPtrAlias fCopyPath; - GLPtrAlias fInterpolatePaths; - GLPtrAlias fTransformPath; - GLPtrAlias fPathParameteriv; - GLPtrAlias fPathParameteri; - GLPtrAlias fPathParameterfv; - GLPtrAlias fPathParameterf; - GLPtrAlias fPathDashArray; - GLPtrAlias fGenPaths; - GLPtrAlias fDeletePaths; - GLPtrAlias fIsPath; - GLPtrAlias fPathStencilFunc; - GLPtrAlias fPathStencilDepthOffset; - GLPtrAlias fStencilFillPath; - GLPtrAlias fStencilStrokePath; - GLPtrAlias fStencilFillPathInstanced; - GLPtrAlias fStencilStrokePathInstanced; - GLPtrAlias fPathCoverDepthFunc; - GLPtrAlias fPathColorGen; - GLPtrAlias fPathTexGen; - GLPtrAlias fPathFogGen; - GLPtrAlias fCoverFillPath; - GLPtrAlias fCoverStrokePath; - GLPtrAlias fCoverFillPathInstanced; - GLPtrAlias fCoverStrokePathInstanced; - GLPtrAlias fGetPathParameteriv; - GLPtrAlias fGetPathParameterfv; - GLPtrAlias fGetPathCommands; - GLPtrAlias fGetPathCoords; - GLPtrAlias fGetPathDashArray; - GLPtrAlias fGetPathMetrics; - GLPtrAlias fGetPathMetricRange; - GLPtrAlias fGetPathSpacing; - GLPtrAlias fGetPathColorGeniv; - GLPtrAlias fGetPathColorGenfv; - GLPtrAlias fGetPathTexGeniv; - GLPtrAlias fGetPathTexGenfv; - GLPtrAlias fIsPointInFillPath; - GLPtrAlias fIsPointInStrokePath; - GLPtrAlias fGetPathLength; - GLPtrAlias fPointAlongPath; - // Per-GL func callback #if GR_GL_PER_GL_FUNC_CALLBACK GrGLInterfaceCallbackProc fCallback; GrGLInterfaceCallbackData fCallbackData; #endif - }; #endif diff --git a/gfx/skia/trunk/include/pdf/SkPDFDevice.h b/gfx/skia/trunk/include/pdf/SkPDFDevice.h index 9b21f8f90a22..daec7a3de749 100644 --- a/gfx/skia/trunk/include/pdf/SkPDFDevice.h +++ b/gfx/skia/trunk/include/pdf/SkPDFDevice.h @@ -70,8 +70,6 @@ public: const SkMatrix& initialTransform); SK_API virtual ~SkPDFDevice(); - virtual uint32_t getDeviceCapabilities() SK_OVERRIDE; - virtual void clear(SkColor color) SK_OVERRIDE; /** These are called inside the per-device-layer loop for each draw call. @@ -257,10 +255,7 @@ private: const SkRegion& existingClipRegion); // override from SkBaseDevice - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) SK_OVERRIDE; + virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; void init(); void cleanUp(bool clearFontUsage); diff --git a/gfx/skia/trunk/include/utils/SkDeferredCanvas.h b/gfx/skia/trunk/include/utils/SkDeferredCanvas.h index b0435de9bd26..58ea2c76c3e3 100644 --- a/gfx/skia/trunk/include/utils/SkDeferredCanvas.h +++ b/gfx/skia/trunk/include/utils/SkDeferredCanvas.h @@ -11,7 +11,7 @@ #include "SkCanvas.h" #include "SkPixelRef.h" -class DeferredDevice; +class SkDeferredDevice; class SkImage; class SkSurface; @@ -138,25 +138,7 @@ public: void silentFlush(); // Overrides of the SkCanvas interface - virtual int save(SaveFlags flags) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; virtual bool isDrawingToLayer() const SK_OVERRIDE; - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - virtual bool clipRect(const SkRect& rect, SkRegion::Op op, - bool doAntiAlias) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect& rect, SkRegion::Op op, - bool doAntiAlias) SK_OVERRIDE; - virtual bool clipPath(const SkPath& path, SkRegion::Op op, - bool doAntiAlias) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& deviceRgn, - SkRegion::Op op) SK_OVERRIDE; virtual void clear(SkColor) SK_OVERRIDE; virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], @@ -200,6 +182,26 @@ public: virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE; virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE; +protected: + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, + const SkPaint&) SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; + public: class NotificationClient { public: @@ -235,10 +237,10 @@ public: protected: virtual SkCanvas* canvasForDrawIter(); - DeferredDevice* getDeferredDevice() const; + SkDeferredDevice* getDeferredDevice() const; private: - SkDeferredCanvas(DeferredDevice*); + SkDeferredCanvas(SkDeferredDevice*); void recordedDrawCommand(); SkCanvas* drawingCanvas() const; diff --git a/gfx/skia/trunk/include/utils/SkDumpCanvas.h b/gfx/skia/trunk/include/utils/SkDumpCanvas.h index 96b45e7ba2bc..4508b46a8a79 100644 --- a/gfx/skia/trunk/include/utils/SkDumpCanvas.h +++ b/gfx/skia/trunk/include/utils/SkDumpCanvas.h @@ -40,6 +40,7 @@ public: kDrawOval_Verb, kDrawRect_Verb, kDrawRRect_Verb, + kDrawDRRect_Verb, kDrawPath_Verb, kDrawBitmap_Verb, kDrawText_Verb, @@ -49,7 +50,9 @@ public: kBeginCommentGroup_Verb, kAddComment_Verb, - kEndCommentGroup_Verb + kEndCommentGroup_Verb, + + kCull_Verb }; /** Subclasses of this are installed on the DumpCanvas, and then called for @@ -71,24 +74,6 @@ public: int getNestLevel() const { return fNestLevel; } - virtual int save(SaveFlags) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; - - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - - virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& deviceRgn, - SkRegion::Op) SK_OVERRIDE; - virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) SK_OVERRIDE; @@ -126,6 +111,29 @@ public: virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE; virtual void endCommentGroup() SK_OVERRIDE; +protected: + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; + virtual void onPushCull(const SkRect& cullRect) SK_OVERRIDE; + virtual void onPopCull() SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; + + static const char* EdgeStyleToAAString(ClipEdgeStyle edgeStyle); + private: Dumper* fDumper; int fNestLevel; // for nesting recursive elements like pictures diff --git a/gfx/skia/trunk/include/utils/SkLua.h b/gfx/skia/trunk/include/utils/SkLua.h index c6097464ef3f..2f29343d595c 100644 --- a/gfx/skia/trunk/include/utils/SkLua.h +++ b/gfx/skia/trunk/include/utils/SkLua.h @@ -8,6 +8,7 @@ #ifndef SkLua_DEFINED #define SkLua_DEFINED +#include "SkClipStack.h" #include "SkColor.h" #include "SkScalar.h" #include "SkString.h" @@ -53,6 +54,11 @@ public: void pushPaint(const SkPaint&, const char tableKey[] = NULL); void pushPath(const SkPath&, const char tableKey[] = NULL); void pushCanvas(SkCanvas*, const char tableKey[] = NULL); + void pushClipStack(const SkClipStack&, const char tableKey[] = NULL); + void pushClipStackElement(const SkClipStack::Element& element, const char tableKey[] = NULL); + + // This SkCanvas lua methods is declared here to benefit from SkLua's friendship with SkCanvas. + static int lcanvas_getReducedClipStack(lua_State* L); private: lua_State* fL; diff --git a/gfx/skia/trunk/include/utils/SkLuaCanvas.h b/gfx/skia/trunk/include/utils/SkLuaCanvas.h index c34d1344236d..fa537bd0913b 100644 --- a/gfx/skia/trunk/include/utils/SkLuaCanvas.h +++ b/gfx/skia/trunk/include/utils/SkLuaCanvas.h @@ -20,24 +20,6 @@ public: SkLuaCanvas(int width, int height, lua_State*, const char function[]); virtual ~SkLuaCanvas(); - virtual int save(SaveFlags flags) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; - - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - - virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& deviceRgn, - SkRegion::Op) SK_OVERRIDE; - virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) SK_OVERRIDE; @@ -72,6 +54,25 @@ public: const SkPaint& paint) SK_OVERRIDE; virtual void drawData(const void* data, size_t length) SK_OVERRIDE; +protected: + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; + private: lua_State* fL; SkString fFunc; diff --git a/gfx/skia/trunk/include/utils/SkNWayCanvas.h b/gfx/skia/trunk/include/utils/SkNWayCanvas.h index eae3bfc538d4..435df9b750bb 100644 --- a/gfx/skia/trunk/include/utils/SkNWayCanvas.h +++ b/gfx/skia/trunk/include/utils/SkNWayCanvas.h @@ -23,21 +23,6 @@ public: /////////////////////////////////////////////////////////////////////////// // These are forwarded to the N canvases we're referencing - virtual int save(SaveFlags) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint*, - SaveFlags) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& deviceRgn, - SkRegion::Op) SK_OVERRIDE; virtual void clear(SkColor) SK_OVERRIDE; virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], @@ -86,6 +71,24 @@ public: protected: SkTDArray fList; + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; + class Iter; private: diff --git a/gfx/skia/trunk/include/utils/SkNoSaveLayerCanvas.h b/gfx/skia/trunk/include/utils/SkNoSaveLayerCanvas.h new file mode 100644 index 000000000000..686f179901d6 --- /dev/null +++ b/gfx/skia/trunk/include/utils/SkNoSaveLayerCanvas.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. + */ + +#ifndef SkNoSaveLayerCanvas_DEFINED +#define SkNoSaveLayerCanvas_DEFINED + +#include "SkCanvas.h" +#include "SkRRect.h" + +// The NoSaveLayerCanvas is used to play back SkPictures when the saveLayer +// functionality isn't required (e.g., during analysis of the draw calls). +// It also simplifies the clipping calls to only use rectangles. +class SK_API SkNoSaveLayerCanvas : public SkCanvas { +public: + SkNoSaveLayerCanvas(SkBaseDevice* device) : INHERITED(device) {} + +protected: + virtual SaveLayerStrategy willSaveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags) SK_OVERRIDE { + this->INHERITED::willSaveLayer(bounds, paint, flags); + return kNoLayer_SaveLayerStrategy; + } + + // disable aa for speed + virtual void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE { + this->INHERITED::onClipRect(rect, op, kHard_ClipEdgeStyle); + } + + // for speed, just respect the bounds, and disable AA. May give us a few + // false positives and negatives. + virtual void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE { + this->updateClipConservativelyUsingBounds(path.getBounds(), op, + path.isInverseFillType()); + } + virtual void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle) SK_OVERRIDE { + this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); + } + +private: + typedef SkCanvas INHERITED; +}; + +#endif // SkNoSaveLayerCanvas_DEFINED diff --git a/gfx/skia/trunk/include/utils/SkProxyCanvas.h b/gfx/skia/trunk/include/utils/SkProxyCanvas.h index 383e532fbfca..1ac83c72d85a 100644 --- a/gfx/skia/trunk/include/utils/SkProxyCanvas.h +++ b/gfx/skia/trunk/include/utils/SkProxyCanvas.h @@ -26,24 +26,6 @@ public: SkCanvas* getProxy() const { return fProxy; } void setProxy(SkCanvas* proxy); - virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags = kARGB_ClipLayer_SaveFlag) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; - - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - - virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& deviceRgn, - SkRegion::Op op = SkRegion::kIntersect_Op) SK_OVERRIDE; - virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint) SK_OVERRIDE; @@ -85,6 +67,25 @@ public: virtual SkBounder* setBounder(SkBounder* bounder) SK_OVERRIDE; virtual SkDrawFilter* setDrawFilter(SkDrawFilter* filter) SK_OVERRIDE; +protected: + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; + private: SkCanvas* fProxy; diff --git a/gfx/skia/trunk/include/utils/SkRunnable.h b/gfx/skia/trunk/include/utils/SkRunnable.h index 84e43750f66d..5acf4dbc61a4 100644 --- a/gfx/skia/trunk/include/utils/SkRunnable.h +++ b/gfx/skia/trunk/include/utils/SkRunnable.h @@ -8,10 +8,18 @@ #ifndef SkRunnable_DEFINED #define SkRunnable_DEFINED -class SkRunnable { -public: - virtual ~SkRunnable() {}; +template +struct SkTRunnable { + virtual ~SkTRunnable() {}; + virtual void run(T&) = 0; +}; + +template <> +struct SkTRunnable { + virtual ~SkTRunnable() {}; virtual void run() = 0; }; +typedef SkTRunnable SkRunnable; + #endif diff --git a/gfx/skia/trunk/include/utils/SkThreadPool.h b/gfx/skia/trunk/include/utils/SkThreadPool.h index 0aa7c08ad53b..a75bed8be44f 100644 --- a/gfx/skia/trunk/include/utils/SkThreadPool.h +++ b/gfx/skia/trunk/include/utils/SkThreadPool.h @@ -12,24 +12,42 @@ #include "SkRunnable.h" #include "SkTDArray.h" #include "SkTInternalLList.h" +#include "SkThreadUtils.h" +#include "SkTypes.h" -class SkThread; +#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID) +# include +#endif -class SkThreadPool { +// Returns the number of cores on this machine. +static inline int num_cores() { +#if defined(SK_BUILD_FOR_WIN32) + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID) + return sysconf(_SC_NPROCESSORS_ONLN); +#else + return 1; +#endif +} +template +class SkTThreadPool { public: /** * Create a threadpool with count threads, or one thread per core if kThreadPerCore. */ static const int kThreadPerCore = -1; - explicit SkThreadPool(int count); - ~SkThreadPool(); + explicit SkTThreadPool(int count); + ~SkTThreadPool(); /** - * Queues up an SkRunnable to run when a thread is available, or immediately if - * count is 0. NULL is a safe no-op. Does not take ownership. + * Queues up an SkRunnable to run when a thread is available, or synchronously if count is 0. + * Does not take ownership. NULL is a safe no-op. If T is not void, the runnable will be passed + * a reference to a T on the thread's local stack. */ - void add(SkRunnable*); + void add(SkTRunnable*); /** * Block until all added SkRunnables have completed. Once called, calling add() is undefined. @@ -38,10 +56,7 @@ public: private: struct LinkedRunnable { - // Unowned pointer. - SkRunnable* fRunnable; - - private: + SkTRunnable* fRunnable; // Unowned. SK_DECLARE_INTERNAL_LLIST_INTERFACE(LinkedRunnable); }; @@ -60,4 +75,128 @@ public: static void Loop(void*); // Static because we pass in this. }; +template +SkTThreadPool::SkTThreadPool(int count) : fState(kRunning_State), fBusyThreads(0) { + if (count < 0) { + count = num_cores(); + } + // Create count threads, all running SkTThreadPool::Loop. + for (int i = 0; i < count; i++) { + SkThread* thread = SkNEW_ARGS(SkThread, (&SkTThreadPool::Loop, this)); + *fThreads.append() = thread; + thread->start(); + } +} + +template +SkTThreadPool::~SkTThreadPool() { + if (kRunning_State == fState) { + this->wait(); + } +} + +namespace SkThreadPoolPrivate { + +template +struct ThreadLocal { + void run(SkTRunnable* r) { r->run(data); } + T data; +}; + +template <> +struct ThreadLocal { + void run(SkTRunnable* r) { r->run(); } +}; + +} // namespace SkThreadPoolPrivate + +template +void SkTThreadPool::add(SkTRunnable* r) { + if (r == NULL) { + return; + } + + if (fThreads.isEmpty()) { + SkThreadPoolPrivate::ThreadLocal threadLocal; + threadLocal.run(r); + return; + } + + LinkedRunnable* linkedRunnable = SkNEW(LinkedRunnable); + linkedRunnable->fRunnable = r; + fReady.lock(); + SkASSERT(fState != kHalting_State); // Shouldn't be able to add work when we're halting. + fQueue.addToHead(linkedRunnable); + fReady.signal(); + fReady.unlock(); +} + + +template +void SkTThreadPool::wait() { + fReady.lock(); + fState = kWaiting_State; + fReady.broadcast(); + fReady.unlock(); + + // Wait for all threads to stop. + for (int i = 0; i < fThreads.count(); i++) { + fThreads[i]->join(); + SkDELETE(fThreads[i]); + } + SkASSERT(fQueue.isEmpty()); +} + +template +/*static*/ void SkTThreadPool::Loop(void* arg) { + // The SkTThreadPool passes itself as arg to each thread as they're created. + SkTThreadPool* pool = static_cast*>(arg); + SkThreadPoolPrivate::ThreadLocal threadLocal; + + while (true) { + // We have to be holding the lock to read the queue and to call wait. + pool->fReady.lock(); + while(pool->fQueue.isEmpty()) { + // Does the client want to stop and are all the threads ready to stop? + // If so, we move into the halting state, and whack all the threads so they notice. + if (kWaiting_State == pool->fState && pool->fBusyThreads == 0) { + pool->fState = kHalting_State; + pool->fReady.broadcast(); + } + // Any time we find ourselves in the halting state, it's quitting time. + if (kHalting_State == pool->fState) { + pool->fReady.unlock(); + return; + } + // wait yields the lock while waiting, but will have it again when awoken. + pool->fReady.wait(); + } + // We've got the lock back here, no matter if we ran wait or not. + + // The queue is not empty, so we have something to run. Claim it. + LinkedRunnable* r = pool->fQueue.tail(); + + pool->fQueue.remove(r); + + // Having claimed our SkRunnable, we now give up the lock while we run it. + // Otherwise, we'd only ever do work on one thread at a time, which rather + // defeats the point of this code. + pool->fBusyThreads++; + pool->fReady.unlock(); + + // OK, now really do the work. + threadLocal.run(r->fRunnable); + SkDELETE(r); + + // Let everyone know we're not busy. + pool->fReady.lock(); + pool->fBusyThreads--; + pool->fReady.unlock(); + } + + SkASSERT(false); // Unreachable. The only exit happens when pool->fState is kHalting_State. +} + +typedef SkTThreadPool SkThreadPool; + #endif diff --git a/gfx/skia/trunk/include/views/SkWindow.h b/gfx/skia/trunk/include/views/SkWindow.h index f8dffa3a0c23..2a9315dc8c77 100644 --- a/gfx/skia/trunk/include/views/SkWindow.h +++ b/gfx/skia/trunk/include/views/SkWindow.h @@ -32,8 +32,8 @@ public: const SkBitmap& getBitmap() const { return fBitmap; } - void setConfig(SkBitmap::Config); - void resize(int width, int height, SkBitmap::Config config = SkBitmap::kNo_Config); + void setColorType(SkColorType); + void resize(int width, int height, SkColorType = kUnknown_SkColorType); bool isDirty() const { return !fDirtyRgn.isEmpty(); } bool update(SkIRect* updateArea); @@ -81,7 +81,7 @@ protected: virtual bool onSetFocusView(SkView* focus); private: - SkBitmap::Config fConfig; + SkColorType fColorType; SkBitmap fBitmap; SkRegion fDirtyRgn; diff --git a/gfx/skia/trunk/src/animator/SkDisplayType.cpp b/gfx/skia/trunk/src/animator/SkDisplayType.cpp index dc52f0caccdf..4461a4b77b01 100644 --- a/gfx/skia/trunk/src/animator/SkDisplayType.cpp +++ b/gfx/skia/trunk/src/animator/SkDisplayType.cpp @@ -372,7 +372,7 @@ const SkMemberInfo* SkDisplayType::GetMembers(SkAnimateMaker* maker, const SkMemberInfo* SkDisplayType::GetMember(SkAnimateMaker* maker, SkDisplayTypes type, const char** matchPtr ) { - int infoCount; + int infoCount = 0; // Initialize to remove a warning. const SkMemberInfo* info = GetMembers(maker, type, &infoCount); info = SkMemberInfo::Find(info, infoCount, matchPtr); // SkASSERT(info); diff --git a/gfx/skia/trunk/src/animator/SkDrawDash.cpp b/gfx/skia/trunk/src/animator/SkDrawDash.cpp index 8e73aa1c2dee..cfef30335b90 100644 --- a/gfx/skia/trunk/src/animator/SkDrawDash.cpp +++ b/gfx/skia/trunk/src/animator/SkDrawDash.cpp @@ -31,5 +31,5 @@ SkPathEffect* SkDash::getPathEffect() { int count = intervals.count(); if (count == 0) return NULL; - return new SkDashPathEffect(intervals.begin(), count, phase); + return SkDashPathEffect::Create(intervals.begin(), count, phase); } diff --git a/gfx/skia/trunk/src/animator/SkDrawDiscrete.cpp b/gfx/skia/trunk/src/animator/SkDrawDiscrete.cpp index 18c3ee0f61b7..9376435950d7 100644 --- a/gfx/skia/trunk/src/animator/SkDrawDiscrete.cpp +++ b/gfx/skia/trunk/src/animator/SkDrawDiscrete.cpp @@ -30,5 +30,5 @@ SkPathEffect* SkDiscrete::getPathEffect() { if (deviation <= 0 || segLength <= 0) return NULL; else - return new SkDiscretePathEffect(segLength, deviation); + return SkDiscretePathEffect::Create(segLength, deviation); } diff --git a/gfx/skia/trunk/src/animator/SkDrawExtraPathEffect.cpp b/gfx/skia/trunk/src/animator/SkDrawExtraPathEffect.cpp index 7b991d251ef0..4b911d11c4ff 100644 --- a/gfx/skia/trunk/src/animator/SkDrawExtraPathEffect.cpp +++ b/gfx/skia/trunk/src/animator/SkDrawExtraPathEffect.cpp @@ -371,7 +371,7 @@ bool SkDrawComposePathEffect::addChild(SkAnimateMaker& , SkDisplayable* child) { SkPathEffect* SkDrawComposePathEffect::getPathEffect() { SkPathEffect* e1 = effect1->getPathEffect(); SkPathEffect* e2 = effect2->getPathEffect(); - SkPathEffect* composite = new SkComposePathEffect(e1, e2); + SkPathEffect* composite = SkComposePathEffect::Create(e1, e2); e1->unref(); e2->unref(); return composite; @@ -401,7 +401,7 @@ SkDrawCornerPathEffect::~SkDrawCornerPathEffect() { } SkPathEffect* SkDrawCornerPathEffect::getPathEffect() { - return new SkCornerPathEffect(radius); + return SkCornerPathEffect::Create(radius); } ///////// diff --git a/gfx/skia/trunk/src/core/Sk64.cpp b/gfx/skia/trunk/src/core/Sk64.cpp deleted file mode 100644 index 54b30221c906..000000000000 --- a/gfx/skia/trunk/src/core/Sk64.cpp +++ /dev/null @@ -1,345 +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. - */ - -#include "Sk64.h" -#include "SkMathPriv.h" - -#define shift_left(hi, lo) \ - hi = (hi << 1) | (lo >> 31); \ - lo <<= 1 - -#define shift_left_bits(hi, lo, bits) \ - SkASSERT((unsigned)(bits) < 31); \ - hi = (hi << (bits)) | (lo >> (32 - (bits))); \ - lo <<= (bits) - -////////////////////////////////////////////////////////////////////// - -int Sk64::getClzAbs() const -{ - int32_t hi = fHi; - uint32_t lo = fLo; - - // get abs - if (hi < 0) - { - hi = -hi - Sk32ToBool(lo); - lo = 0 - lo; - } - return hi ? SkCLZ(hi) : SkCLZ(lo) + 32; -} - -void Sk64::shiftLeft(unsigned bits) -{ - SkASSERT(bits <= 63); - if (bits == 0) - return; - - if (bits >= 32) - { - fHi = fLo << (bits - 32); - fLo = 0; - } - else - { - fHi = (fHi << bits) | (fLo >> (32 - bits)); - fLo <<= bits; - } -} - -int32_t Sk64::getShiftRight(unsigned bits) const -{ - SkASSERT(bits <= 63); - - if (bits == 0) - return fLo; - - if (bits >= 32) - return fHi >> (bits - 32); - else - { -#ifdef SK_DEBUG - int32_t tmp = fHi >> bits; - SkASSERT(tmp == 0 || tmp == -1); -#endif - return (fHi << (32 - bits)) | (fLo >> bits); - } -} - -void Sk64::shiftRight(unsigned bits) -{ - SkASSERT(bits <= 63); - if (bits == 0) - return; - - if (bits >= 32) - { - fLo = fHi >> (bits - 32); - fHi >>= 31; - } - else - { - fLo = (fHi << (32 - bits)) | (fLo >> bits); - fHi >>= bits; - } -} - -void Sk64::roundRight(unsigned bits) -{ - SkASSERT(bits <= 63); - if (bits) - { - Sk64 one; - one.set(1); - one.shiftLeft(bits - 1); - this->add(one); - this->shiftRight(bits); - } -} - -int Sk64::shiftToMake32() const -{ - int32_t hi = fHi; - uint32_t lo = fLo; - - if (hi < 0) // make it positive - { - hi = -hi - Sk32ToBool(lo); - lo = 0 - lo; - } - - if (hi == 0) - return lo >> 31; - else - return 33 - SkCLZ(hi); -} - -void Sk64::negate() -{ - fHi = -fHi - Sk32ToBool(fLo); - fLo = 0 - fLo; -} - -void Sk64::abs() -{ - if (fHi < 0) - { - fHi = -fHi - Sk32ToBool(fLo); - fLo = 0 - fLo; - } -} - -SkBool Sk64::isFixed() const -{ - Sk64 tmp = *this; - tmp.roundRight(16); - return tmp.is32(); -} - -SkFract Sk64::getFract() const -{ - Sk64 tmp = *this; - tmp.roundRight(30); - return tmp.get32(); -} - -void Sk64::sub(const Sk64& a) -{ - fHi = fHi - a.fHi - (fLo < a.fLo); - fLo = fLo - a.fLo; -} - -void Sk64::rsub(const Sk64& a) -{ - fHi = a.fHi - fHi - (a.fLo < fLo); - fLo = a.fLo - fLo; -} - -void Sk64::setMul(int32_t a, int32_t b) -{ - int sa = a >> 31; - int sb = b >> 31; - // now make them positive - a = (a ^ sa) - sa; - b = (b ^ sb) - sb; - - uint32_t ah = a >> 16; - uint32_t al = a & 0xFFFF; - uint32_t bh = b >> 16; - uint32_t bl = b & 0xFFFF; - - uint32_t A = ah * bh; - uint32_t B = ah * bl + al * bh; - uint32_t C = al * bl; - - /* [ A ] - [ B ] - [ C ] - */ - fLo = C + (B << 16); - fHi = A + (B >>16) + (fLo < C); - - if (sa != sb) - this->negate(); -} - -void Sk64::div(int32_t denom, DivOptions option) -{ - SkASSERT(denom); - - int32_t hi = fHi; - uint32_t lo = fLo; - int sign = denom ^ hi; - - denom = SkAbs32(denom); - if (hi < 0) - { - hi = -hi - Sk32ToBool(lo); - lo = 0 - lo; - } - - if (option == kRound_DivOption) // add denom/2 - { - uint32_t newLo = lo + (denom >> 1); - hi += (newLo < lo); - lo = newLo; - } - - if (hi == 0) // fast-case - { - if (lo < (uint32_t)denom) - this->set(0, 0); - else - { - this->set(0, lo / denom); - if (sign < 0) - this->negate(); - } - return; - } - - int bits; - - { - int dbits = SkCLZ(denom); - int nbits = SkCLZ(hi); - - bits = 32 + dbits - nbits; - SkASSERT(bits <= 63); - if (bits <= 0) - { - this->set(0, 0); - return; - } - denom <<= (dbits - 1); - shift_left_bits(hi, lo, nbits - 1); - } - - int32_t rhi = 0; - uint32_t rlo = 0; - - do { - shift_left(rhi, rlo); - if ((uint32_t)denom <= (uint32_t)hi) - { - hi -= denom; - rlo |= 1; - } - shift_left(hi, lo); - } while (--bits >= 0); - SkASSERT(rhi >= 0); - - fHi = rhi; - fLo = rlo; - if (sign < 0) - this->negate(); -} - -#define shift_left_2(a, b, c) \ - a = (a << 2) | (b >> 30); \ - b = (b << 2) | (c >> 30); \ - c <<= 2 - -int32_t Sk64::getSqrt() const -{ - SkASSERT(!this->isNeg()); - - uint32_t hi = fHi; - uint32_t lo = fLo; - uint32_t sqr = 0; - uint32_t root = 0; - int count = 31; - - do { - root <<= 1; - shift_left_2(sqr, hi, lo); - - uint32_t testDiv = (root << 1) + 1; - if (sqr >= testDiv) - { - sqr -= testDiv; - root++; - } - } while (--count >= 0); - SkASSERT((int32_t)root >= 0); - - return root; -} - -#ifdef SkLONGLONG - SkLONGLONG Sk64::getLongLong() const - { - SkLONGLONG value = fHi; - value <<= 32; - return value | fLo; - } -#endif - -SkFixed Sk64::getFixedDiv(const Sk64& denom) const -{ - Sk64 N = *this; - Sk64 D = denom; - int32_t sign = SkExtractSign(N.fHi ^ D.fHi); - SkFixed result; - - N.abs(); - D.abs(); - - // need to knock D down to just 31 bits - // either by rounding it to the right, or shifting N to the left - // then we can just call 64/32 div - - int nclz = N.fHi ? SkCLZ(N.fHi) : 32; - int dclz = D.fHi ? SkCLZ(D.fHi) : (33 - (D.fLo >> 31)); - - int shiftN = nclz - 1; - SkASSERT(shiftN >= 0); - int shiftD = 33 - dclz; - SkASSERT(shiftD >= 0); - - if (shiftD + shiftN < 16) - shiftD = 16 - shiftN; - else - shiftN = 16 - shiftD; - - D.roundRight(shiftD); - if (D.isZero()) - result = SK_MaxS32; - else - { - if (shiftN >= 0) - N.shiftLeft(shiftN); - else - N.roundRight(-shiftN); - N.div(D.get32(), Sk64::kTrunc_DivOption); - if (N.is32()) - result = N.get32(); - else - result = SK_MaxS32; - } - return SkApplySign(result, sign); -} diff --git a/gfx/skia/trunk/src/core/SkAnnotation.cpp b/gfx/skia/trunk/src/core/SkAnnotation.cpp index 6ba645ffed57..bddff64db84c 100644 --- a/gfx/skia/trunk/src/core/SkAnnotation.cpp +++ b/gfx/skia/trunk/src/core/SkAnnotation.cpp @@ -56,7 +56,7 @@ const char* SkAnnotationKeys::Link_Named_Dest_Key() { #include "SkCanvas.h" static void annotate_paint(SkPaint& paint, const char* key, SkData* value) { - paint.setAnnotation(SkNEW_ARGS(SkAnnotation, (key, value)))->unref(); + paint.setAnnotation(SkAnnotation::Create(key, value))->unref(); } void SkAnnotateRectWithURL(SkCanvas* canvas, const SkRect& rect, SkData* value) { diff --git a/gfx/skia/trunk/src/core/SkBBoxHierarchyRecord.cpp b/gfx/skia/trunk/src/core/SkBBoxHierarchyRecord.cpp index 8e5861bb21e6..eadd20613bfa 100644 --- a/gfx/skia/trunk/src/core/SkBBoxHierarchyRecord.cpp +++ b/gfx/skia/trunk/src/core/SkBBoxHierarchyRecord.cpp @@ -9,10 +9,10 @@ #include "SkBBoxHierarchyRecord.h" #include "SkPictureStateTree.h" -SkBBoxHierarchyRecord::SkBBoxHierarchyRecord(uint32_t recordFlags, - SkBBoxHierarchy* h, - SkBaseDevice* device) - : INHERITED(recordFlags, device) { +SkBBoxHierarchyRecord::SkBBoxHierarchyRecord(const SkISize& size, + uint32_t recordFlags, + SkBBoxHierarchy* h) + : INHERITED(size, recordFlags) { fStateTree = SkNEW(SkPictureStateTree); fBoundingHierarchy = h; fBoundingHierarchy->ref(); @@ -26,82 +26,78 @@ void SkBBoxHierarchyRecord::handleBBox(const SkRect& bounds) { fBoundingHierarchy->insert(draw, r, true); } -int SkBBoxHierarchyRecord::save(SaveFlags flags) { +void SkBBoxHierarchyRecord::willSave(SaveFlags flags) { fStateTree->appendSave(); - return INHERITED::save(flags); + this->INHERITED::willSave(flags); } -int SkBBoxHierarchyRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { +SkCanvas::SaveLayerStrategy SkBBoxHierarchyRecord::willSaveLayer(const SkRect* bounds, + const SkPaint* paint, + SaveFlags flags) { fStateTree->appendSaveLayer(this->writeStream().bytesWritten()); - return INHERITED::saveLayer(bounds, paint, flags); + return this->INHERITED::willSaveLayer(bounds, paint, flags); } -void SkBBoxHierarchyRecord::restore() { +void SkBBoxHierarchyRecord::willRestore() { fStateTree->appendRestore(); - INHERITED::restore(); + this->INHERITED::willRestore(); } -bool SkBBoxHierarchyRecord::translate(SkScalar dx, SkScalar dy) { - bool result = INHERITED::translate(dx, dy); +void SkBBoxHierarchyRecord::didTranslate(SkScalar dx, SkScalar dy) { fStateTree->appendTransform(getTotalMatrix()); - return result; + INHERITED::didTranslate(dx, dy); } -bool SkBBoxHierarchyRecord::scale(SkScalar sx, SkScalar sy) { - bool result = INHERITED::scale(sx, sy); +void SkBBoxHierarchyRecord::didScale(SkScalar sx, SkScalar sy) { fStateTree->appendTransform(getTotalMatrix()); - return result; + INHERITED::didScale(sx, sy); } -bool SkBBoxHierarchyRecord::rotate(SkScalar degrees) { - bool result = INHERITED::rotate(degrees); +void SkBBoxHierarchyRecord::didRotate(SkScalar degrees) { fStateTree->appendTransform(getTotalMatrix()); - return result; + INHERITED::didRotate(degrees); } -bool SkBBoxHierarchyRecord::skew(SkScalar sx, SkScalar sy) { - bool result = INHERITED::skew(sx, sy); +void SkBBoxHierarchyRecord::didSkew(SkScalar sx, SkScalar sy) { fStateTree->appendTransform(getTotalMatrix()); - return result; + INHERITED::didSkew(sx, sy); } -bool SkBBoxHierarchyRecord::concat(const SkMatrix& matrix) { - bool result = INHERITED::concat(matrix); +void SkBBoxHierarchyRecord::didConcat(const SkMatrix& matrix) { fStateTree->appendTransform(getTotalMatrix()); - return result; + INHERITED::didConcat(matrix); } -void SkBBoxHierarchyRecord::setMatrix(const SkMatrix& matrix) { - INHERITED::setMatrix(matrix); +void SkBBoxHierarchyRecord::didSetMatrix(const SkMatrix& matrix) { fStateTree->appendTransform(getTotalMatrix()); + INHERITED::didSetMatrix(matrix); } -bool SkBBoxHierarchyRecord::clipRect(const SkRect& rect, - SkRegion::Op op, - bool doAntiAlias) { +void SkBBoxHierarchyRecord::onClipRect(const SkRect& rect, + SkRegion::Op op, + ClipEdgeStyle edgeStyle) { fStateTree->appendClip(this->writeStream().bytesWritten()); - return INHERITED::clipRect(rect, op, doAntiAlias); + this->INHERITED::onClipRect(rect, op, edgeStyle); } -bool SkBBoxHierarchyRecord::clipRegion(const SkRegion& region, - SkRegion::Op op) { +void SkBBoxHierarchyRecord::onClipRegion(const SkRegion& region, + SkRegion::Op op) { fStateTree->appendClip(this->writeStream().bytesWritten()); - return INHERITED::clipRegion(region, op); + this->INHERITED::onClipRegion(region, op); } -bool SkBBoxHierarchyRecord::clipPath(const SkPath& path, - SkRegion::Op op, - bool doAntiAlias) { +void SkBBoxHierarchyRecord::onClipPath(const SkPath& path, + SkRegion::Op op, + ClipEdgeStyle edgeStyle) { fStateTree->appendClip(this->writeStream().bytesWritten()); - return INHERITED::clipPath(path, op, doAntiAlias); + this->INHERITED::onClipPath(path, op, edgeStyle); } -bool SkBBoxHierarchyRecord::clipRRect(const SkRRect& rrect, - SkRegion::Op op, - bool doAntiAlias) { +void SkBBoxHierarchyRecord::onClipRRect(const SkRRect& rrect, + SkRegion::Op op, + ClipEdgeStyle edgeStyle) { fStateTree->appendClip(this->writeStream().bytesWritten()); - return INHERITED::clipRRect(rrect, op, doAntiAlias); + this->INHERITED::onClipRRect(rrect, op, edgeStyle); } bool SkBBoxHierarchyRecord::shouldRewind(void* data) { diff --git a/gfx/skia/trunk/src/core/SkBBoxHierarchyRecord.h b/gfx/skia/trunk/src/core/SkBBoxHierarchyRecord.h index 7284ab04ecd8..08de7dbd814a 100644 --- a/gfx/skia/trunk/src/core/SkBBoxHierarchyRecord.h +++ b/gfx/skia/trunk/src/core/SkBBoxHierarchyRecord.h @@ -19,38 +19,30 @@ class SkBBoxHierarchyRecord : public SkBBoxRecord, public SkBBoxHierarchyClient { public: /** This will take a ref of h */ - SkBBoxHierarchyRecord(uint32_t recordFlags, SkBBoxHierarchy* h, - SkBaseDevice*); + SkBBoxHierarchyRecord(const SkISize& size, uint32_t recordFlags, SkBBoxHierarchy* h); virtual void handleBBox(const SkRect& bounds) SK_OVERRIDE; - virtual int save(SaveFlags flags = kMatrixClip_SaveFlag) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags = kARGB_ClipLayer_SaveFlag) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; - - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - - virtual bool clipRect(const SkRect& rect, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& region, - SkRegion::Op op = SkRegion::kIntersect_Op) SK_OVERRIDE; - virtual bool clipPath(const SkPath& path, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect& rrect, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false) SK_OVERRIDE; - // Implementation of the SkBBoxHierarchyClient interface virtual bool shouldRewind(void* data) SK_OVERRIDE; +protected: + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; + private: typedef SkBBoxRecord INHERITED; }; diff --git a/gfx/skia/trunk/src/core/SkBBoxRecord.cpp b/gfx/skia/trunk/src/core/SkBBoxRecord.cpp index a757a245ce1c..7075cd165129 100644 --- a/gfx/skia/trunk/src/core/SkBBoxRecord.cpp +++ b/gfx/skia/trunk/src/core/SkBBoxRecord.cpp @@ -26,6 +26,13 @@ void SkBBoxRecord::drawRect(const SkRect& rect, const SkPaint& paint) { } } +void SkBBoxRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + if (this->transformBounds(outer.rect(), &paint)) { + this->INHERITED::onDrawDRRect(outer, inner, paint); + } +} + void SkBBoxRecord::drawPath(const SkPath& path, const SkPaint& paint) { if (path.isInverseFillType()) { // If path is inverse filled, use the current clip bounds as the diff --git a/gfx/skia/trunk/src/core/SkBBoxRecord.h b/gfx/skia/trunk/src/core/SkBBoxRecord.h index fa8b282247e8..862e48e5b539 100644 --- a/gfx/skia/trunk/src/core/SkBBoxRecord.h +++ b/gfx/skia/trunk/src/core/SkBBoxRecord.h @@ -19,8 +19,7 @@ class SkBBoxRecord : public SkPictureRecord { public: - SkBBoxRecord(uint32_t recordFlags, SkBaseDevice* device) - : INHERITED(recordFlags, device) { } + SkBBoxRecord(const SkISize& size, uint32_t recordFlags) : INHERITED(size, recordFlags) {} virtual ~SkBBoxRecord() { } /** @@ -65,6 +64,9 @@ public: const SkPaint& paint) SK_OVERRIDE; virtual void drawPicture(SkPicture& picture) SK_OVERRIDE; +protected: + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; + private: /** * Takes a bounding box in current canvas view space, accounts for stroking and effects, and diff --git a/gfx/skia/trunk/src/core/SkBitmap.cpp b/gfx/skia/trunk/src/core/SkBitmap.cpp index 96d683c0e259..9ac621159c41 100644 --- a/gfx/skia/trunk/src/core/SkBitmap.cpp +++ b/gfx/skia/trunk/src/core/SkBitmap.cpp @@ -253,7 +253,14 @@ static bool validate_alphaType(SkColorType colorType, SkAlphaType alphaType, return true; } -bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) { +bool SkBitmap::setConfig(const SkImageInfo& origInfo, size_t rowBytes) { + SkImageInfo info = origInfo; + + if (!validate_alphaType(info.fColorType, info.fAlphaType, + &info.fAlphaType)) { + return reset_return_false(this); + } + // require that rowBytes fit in 31bits int64_t mrb = info.minRowBytes64(); if ((int32_t)mrb != mrb) { @@ -504,9 +511,23 @@ bool SkBitmap::installPixels(const SkImageInfo& info, void* pixels, size_t rb, } this->setPixelRef(pr)->unref(); + + // since we're already allocated, we lockPixels right away + this->lockPixels(); + SkDEBUGCODE(this->validate();) return true; } +bool SkBitmap::installMaskPixels(const SkMask& mask) { + if (SkMask::kA8_Format != mask.fFormat) { + this->reset(); + return false; + } + return this->installPixels(SkImageInfo::MakeA8(mask.fBounds.width(), + mask.fBounds.height()), + mask.fImage, mask.fRowBytes); +} + bool SkBitmap::allocConfigPixels(Config config, int width, int height, bool isOpaque) { SkColorType ct; @@ -961,32 +982,33 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const { #include "SkCanvas.h" #include "SkPaint.h" -bool SkBitmap::canCopyTo(Config dstConfig) const { - if (this->config() == kNo_Config) { +bool SkBitmap::canCopyTo(SkColorType dstColorType) const { + if (this->colorType() == kUnknown_SkColorType) { return false; } - bool sameConfigs = (this->config() == dstConfig); - switch (dstConfig) { - case kA8_Config: - case kRGB_565_Config: - case kARGB_8888_Config: + bool sameConfigs = (this->colorType() == dstColorType); + switch (dstColorType) { + case kAlpha_8_SkColorType: + case kRGB_565_SkColorType: + case kPMColor_SkColorType: break; - case kIndex8_Config: + case kIndex_8_SkColorType: if (!sameConfigs) { return false; } break; - case kARGB_4444_Config: - return sameConfigs || kARGB_8888_Config == this->config(); + case kARGB_4444_SkColorType: + return sameConfigs || kPMColor_SkColorType == this->colorType(); default: return false; } return true; } -bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { - if (!this->canCopyTo(dstConfig)) { +bool SkBitmap::copyTo(SkBitmap* dst, SkColorType dstColorType, + Allocator* alloc) const { + if (!this->canCopyTo(dstColorType)) { return false; } @@ -1003,7 +1025,7 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { SkASSERT(tmpSrc.height() == this->height()); // did we get lucky and we can just return tmpSrc? - if (tmpSrc.config() == dstConfig && NULL == alloc) { + if (tmpSrc.colorType() == dstColorType && NULL == alloc) { dst->swap(tmpSrc); // If the result is an exact copy, clone the gen ID. if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->info()) { @@ -1026,14 +1048,20 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { // The only way to be readyToDraw is if fPixelRef is non NULL. SkASSERT(fPixelRef != NULL); + SkImageInfo dstInfo = src->info(); + dstInfo.fColorType = dstColorType; + SkBitmap tmpDst; - tmpDst.setConfig(dstConfig, src->width(), src->height(), 0, - src->alphaType()); + if (!tmpDst.setConfig(dstInfo)) { + return false; + } // allocate colortable if srcConfig == kIndex8_Config - SkColorTable* ctable = (dstConfig == kIndex8_Config) ? - new SkColorTable(*src->getColorTable()) : NULL; - SkAutoUnref au(ctable); + SkAutoTUnref ctable; + if (dstColorType == kIndex_8_SkColorType) { + // TODO: can we just ref() the src colortable? Is it reentrant-safe? + ctable.reset(SkNEW_ARGS(SkColorTable, (*src->getColorTable()))); + } if (!tmpDst.allocPixels(alloc, ctable)) { return false; } @@ -1049,7 +1077,7 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { /* do memcpy for the same configs cases, else use drawing */ - if (src->config() == dstConfig) { + if (src->colorType() == dstColorType) { if (tmpDst.getSize() == src->getSize()) { memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); SkPixelRef* pixelRef = tmpDst.pixelRef(); @@ -1081,8 +1109,8 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { dstP += tmpDst.rowBytes(); } } - } else if (SkBitmap::kARGB_4444_Config == dstConfig - && SkBitmap::kARGB_8888_Config == src->config()) { + } else if (kARGB_4444_SkColorType == dstColorType + && kPMColor_SkColorType == src->colorType()) { SkASSERT(src->height() == tmpDst.height()); SkASSERT(src->width() == tmpDst.width()); for (int y = 0; y < src->height(); ++y) { @@ -1110,10 +1138,11 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const { return true; } -bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { +bool SkBitmap::deepCopyTo(SkBitmap* dst) const { + const SkBitmap::Config dstConfig = this->config(); const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig); - if (!this->canCopyTo(dstConfig)) { + if (!this->canCopyTo(dstCT)) { return false; } @@ -1148,7 +1177,7 @@ bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { if (this->getTexture()) { return false; } else { - return this->copyTo(dst, dstConfig, NULL); + return this->copyTo(dst, dstCT, NULL); } } @@ -1566,11 +1595,13 @@ void SkBitmap::unflatten(SkReadBuffer& buffer) { SkImageInfo info; info.unflatten(buffer); size_t rowBytes = buffer.readInt(); - buffer.validate((info.width() >= 0) && (info.height() >= 0) && - SkColorTypeIsValid(info.fColorType) && - SkAlphaTypeIsValid(info.fAlphaType) && - validate_alphaType(info.fColorType, info.fAlphaType) && - info.validRowBytes(rowBytes)); + if (!buffer.validate((info.width() >= 0) && (info.height() >= 0) && + SkColorTypeIsValid(info.fColorType) && + SkAlphaTypeIsValid(info.fAlphaType) && + validate_alphaType(info.fColorType, info.fAlphaType) && + info.validRowBytes(rowBytes))) { + return; + } bool configIsValid = this->setConfig(info, rowBytes); buffer.validate(configIsValid); @@ -1617,6 +1648,13 @@ SkBitmap::RLEPixels::~RLEPixels() { #ifdef SK_DEBUG void SkBitmap::validate() const { fInfo.validate(); + + // ImageInfo may not require this, but Bitmap ensures that opaque-only + // colorTypes report opaque for their alphatype + if (kRGB_565_SkColorType == fInfo.colorType()) { + SkASSERT(kOpaque_SkAlphaType == fInfo.alphaType()); + } + SkASSERT(fInfo.validRowBytes(fRowBytes)); uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImmutable_Flag; #ifdef SK_BUILD_FOR_ANDROID @@ -1641,7 +1679,7 @@ void SkBitmap::validate() const { } #endif -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkBitmap::toString(SkString* str) const { static const char* gConfigNames[kConfigCount] = { diff --git a/gfx/skia/trunk/src/core/SkBitmapDevice.cpp b/gfx/skia/trunk/src/core/SkBitmapDevice.cpp index 9dde6e172ec1..96f4e4029891 100644 --- a/gfx/skia/trunk/src/core/SkBitmapDevice.cpp +++ b/gfx/skia/trunk/src/core/SkBitmapDevice.cpp @@ -15,16 +15,60 @@ #define CHECK_FOR_ANNOTATION(paint) \ do { if (paint.getAnnotation()) { return; } } while (0) -SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap) - : fBitmap(bitmap) { - SkASSERT(SkBitmap::kARGB_4444_Config != bitmap.config()); +static bool valid_for_bitmap_device(const SkImageInfo& info, + SkAlphaType* newAlphaType) { + if (info.width() < 0 || info.height() < 0) { + return false; + } + + // TODO: can we stop supporting kUnknown in SkBitmkapDevice? + if (kUnknown_SkColorType == info.colorType()) { + if (newAlphaType) { + *newAlphaType = kIgnore_SkAlphaType; + } + return true; + } + + switch (info.alphaType()) { + case kPremul_SkAlphaType: + case kOpaque_SkAlphaType: + break; + default: + return false; + } + + SkAlphaType canonicalAlphaType = info.alphaType(); + + switch (info.colorType()) { + case kAlpha_8_SkColorType: + break; + case kRGB_565_SkColorType: + canonicalAlphaType = kOpaque_SkAlphaType; + break; + case kPMColor_SkColorType: + break; + default: + return false; + } + + if (newAlphaType) { + *newAlphaType = canonicalAlphaType; + } + return true; +} + +SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap) : fBitmap(bitmap) { + SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL)); } SkBitmapDevice::SkBitmapDevice(const SkBitmap& bitmap, const SkDeviceProperties& deviceProperties) : SkBaseDevice(deviceProperties) - , fBitmap(bitmap) { + , fBitmap(bitmap) +{ + SkASSERT(valid_for_bitmap_device(bitmap.info(), NULL)); } +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG void SkBitmapDevice::init(SkBitmap::Config config, int width, int height, bool isOpaque) { fBitmap.setConfig(config, width, height, 0, isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); @@ -50,8 +94,38 @@ SkBitmapDevice::SkBitmapDevice(SkBitmap::Config config, int width, int height, b { this->init(config, width, height, isOpaque); } +#endif +SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo, + const SkDeviceProperties* props) { + SkImageInfo info = origInfo; + if (!valid_for_bitmap_device(info, &info.fAlphaType)) { + return NULL; + } -SkBitmapDevice::~SkBitmapDevice() { + SkBitmap bitmap; + + if (kUnknown_SkColorType == info.colorType()) { + if (!bitmap.setConfig(info)) { + return NULL; + } + } else { + if (!bitmap.allocPixels(info)) { + return NULL; + } + if (!bitmap.info().isOpaque()) { + bitmap.eraseColor(SK_ColorTRANSPARENT); + } + } + + if (props) { + return SkNEW_ARGS(SkBitmapDevice, (bitmap, *props)); + } else { + return SkNEW_ARGS(SkBitmapDevice, (bitmap)); + } +} + +SkImageInfo SkBitmapDevice::imageInfo() const { + return fBitmap.info(); } void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) { @@ -61,18 +135,8 @@ void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) { fBitmap.lockPixels(); } -SkBaseDevice* SkBitmapDevice::onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) { - SkBitmapDevice* device = SkNEW_ARGS(SkBitmapDevice,(config, width, height, - isOpaque, this->getDeviceProperties())); - // Check if allocation failed and delete device if it did fail - if ((device->width() != width) || (device->height() != height)) { - SkDELETE(device); - device = NULL; - } - return device; +SkBaseDevice* SkBitmapDevice::onCreateDevice(const SkImageInfo& info, Usage usage) { + return SkBitmapDevice::Create(info, &this->getDeviceProperties()); } void SkBitmapDevice::lockPixels() { @@ -100,7 +164,7 @@ bool SkBitmapDevice::canHandleImageFilter(const SkImageFilter*) { } bool SkBitmapDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src, - const SkMatrix& ctm, SkBitmap* result, + const SkImageFilter::Context& ctx, SkBitmap* result, SkIPoint* offset) { return false; } @@ -125,9 +189,9 @@ bool SkBitmapDevice::onReadPixels(const SkBitmap& bitmap, if (!src.extractSubset(&subset, srcRect)) { return false; } - if (SkBitmap::kARGB_8888_Config != subset.config()) { + if (kPMColor_SkColorType != subset.colorType()) { // It'd be preferable to do this directly to bitmap. - subset.copyTo(&subset, SkBitmap::kARGB_8888_Config); + subset.copyTo(&subset, kPMColor_SkColorType); } SkAutoLockPixels alp(bitmap); uint32_t* bmpPixels = reinterpret_cast(bitmap.getPixels()); @@ -135,6 +199,7 @@ bool SkBitmapDevice::onReadPixels(const SkBitmap& bitmap, return true; } +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG void SkBitmapDevice::writePixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { @@ -201,6 +266,110 @@ void SkBitmapDevice::writePixels(const SkBitmap& bitmap, draw.fMatrix = &SkMatrix::I(); this->drawSprite(draw, *sprite, x, y, paint); } +#endif + +void* SkBitmapDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) { + if (fBitmap.getPixels()) { + *info = fBitmap.info(); + *rowBytes = fBitmap.rowBytes(); + return fBitmap.getPixels(); + } + return NULL; +} + +static void rect_memcpy(void* dst, size_t dstRB, const void* src, size_t srcRB, size_t bytesPerRow, + int rowCount) { + SkASSERT(bytesPerRow <= srcRB); + SkASSERT(bytesPerRow <= dstRB); + for (int i = 0; i < rowCount; ++i) { + memcpy(dst, src, bytesPerRow); + dst = (char*)dst + dstRB; + src = (const char*)src + srcRB; + } +} + +static bool info2config8888(const SkImageInfo& info, SkCanvas::Config8888* config) { + bool pre; + switch (info.alphaType()) { + case kPremul_SkAlphaType: + case kOpaque_SkAlphaType: + pre = true; + break; + case kUnpremul_SkAlphaType: + pre = false; + break; + default: + return false; + } + switch (info.colorType()) { + case kRGBA_8888_SkColorType: + *config = pre ? SkCanvas::kRGBA_Premul_Config8888 : SkCanvas::kRGBA_Unpremul_Config8888; + return true; + case kBGRA_8888_SkColorType: + *config = pre ? SkCanvas::kBGRA_Premul_Config8888 : SkCanvas::kBGRA_Unpremul_Config8888; + return true; + default: + return false; + } +} + +// TODO: make this guy real, and not rely on legacy config8888 utility +#include "SkConfig8888.h" +static bool write_pixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes, + const SkImageInfo& srcInfo, const void* srcPixels, size_t srcRowBytes) { + if (srcInfo.dimensions() != dstInfo.dimensions()) { + return false; + } + if (4 == srcInfo.bytesPerPixel() && 4 == dstInfo.bytesPerPixel()) { + SkCanvas::Config8888 srcConfig, dstConfig; + if (!info2config8888(srcInfo, &srcConfig) || !info2config8888(dstInfo, &dstConfig)) { + return false; + } + SkConvertConfig8888Pixels((uint32_t*)dstPixels, dstRowBytes, dstConfig, + (const uint32_t*)srcPixels, srcRowBytes, srcConfig, + srcInfo.width(), srcInfo.height()); + return true; + } + if (srcInfo.colorType() == dstInfo.colorType()) { + switch (srcInfo.colorType()) { + case kRGB_565_SkColorType: + case kAlpha_8_SkColorType: + break; + case kARGB_4444_SkColorType: + if (srcInfo.alphaType() != dstInfo.alphaType()) { + return false; + } + break; + default: + return false; + } + rect_memcpy(dstPixels, dstRowBytes, srcPixels, srcRowBytes, + srcInfo.width() * srcInfo.bytesPerPixel(), srcInfo.height()); + } + // TODO: add support for more conversions as needed + return false; +} + +bool SkBitmapDevice::onWritePixels(const SkImageInfo& srcInfo, const void* srcPixels, + size_t srcRowBytes, int x, int y) { + // since we don't stop creating un-pixeled devices yet, check for no pixels here + if (NULL == fBitmap.getPixels()) { + return false; + } + + SkImageInfo dstInfo = fBitmap.info(); + dstInfo.fWidth = srcInfo.width(); + dstInfo.fHeight = srcInfo.height(); + + void* dstPixels = fBitmap.getAddr(x, y); + size_t dstRowBytes = fBitmap.rowBytes(); + + if (write_pixels(dstInfo, dstPixels, dstRowBytes, srcInfo, srcPixels, srcRowBytes)) { + fBitmap.notifyPixelsChanged(); + return true; + } + return false; +} /////////////////////////////////////////////////////////////////////////////// @@ -386,6 +555,16 @@ SkSurface* SkBitmapDevice::newSurface(const SkImageInfo& info) { return SkSurface::NewRaster(info); } +const void* SkBitmapDevice::peekPixels(SkImageInfo* info, size_t* rowBytes) { + if (fBitmap.getPixels() && fBitmap.asImageInfo(info)) { + if (rowBytes) { + *rowBytes = fBitmap.rowBytes(); + } + return fBitmap.getPixels(); + } + return NULL; +} + /////////////////////////////////////////////////////////////////////////////// bool SkBitmapDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { diff --git a/gfx/skia/trunk/src/core/SkBitmapFilter.cpp b/gfx/skia/trunk/src/core/SkBitmapFilter.cpp index 7443cb61b7c9..1653cbb20ec3 100644 --- a/gfx/skia/trunk/src/core/SkBitmapFilter.cpp +++ b/gfx/skia/trunk/src/core/SkBitmapFilter.cpp @@ -123,8 +123,8 @@ bool SkBitmapProcState::setBitmapFilterProcs() { return false; } - // TODO: consider supporting other configs (e.g. 565, A8) - if (fBitmap->config() != SkBitmap::kARGB_8888_Config) { + // TODO: consider supporting other colortypes (e.g. 565, A8) + if (fBitmap->colorType() != kPMColor_SkColorType) { return false; } diff --git a/gfx/skia/trunk/src/core/SkBitmapHeap.cpp b/gfx/skia/trunk/src/core/SkBitmapHeap.cpp index da628937e903..efaa23fc64ac 100644 --- a/gfx/skia/trunk/src/core/SkBitmapHeap.cpp +++ b/gfx/skia/trunk/src/core/SkBitmapHeap.cpp @@ -265,7 +265,7 @@ bool SkBitmapHeap::copyBitmap(const SkBitmap& originalBitmap, SkBitmap& copiedBi // copiedBitmap.setPixelRef(sharedPixelRef, originalBitmap.pixelRefOffset()); } else if (originalBitmap.empty()) { copiedBitmap.reset(); - } else if (!originalBitmap.deepCopyTo(&copiedBitmap, originalBitmap.config())) { + } else if (!originalBitmap.deepCopyTo(&copiedBitmap)) { return false; } copiedBitmap.setImmutable(); diff --git a/gfx/skia/trunk/src/core/SkBitmapHeap.h b/gfx/skia/trunk/src/core/SkBitmapHeap.h index 467a21699757..56ed3584e81c 100644 --- a/gfx/skia/trunk/src/core/SkBitmapHeap.h +++ b/gfx/skia/trunk/src/core/SkBitmapHeap.h @@ -111,7 +111,7 @@ public: */ SkBitmapHeap(ExternalStorage* externalStorage, int32_t heapSize = UNLIMITED_SIZE); - ~SkBitmapHeap(); + virtual ~SkBitmapHeap(); /** * Makes a shallow copy of all bitmaps currently in the heap and returns them as an array. The diff --git a/gfx/skia/trunk/src/core/SkBitmapProcShader.cpp b/gfx/skia/trunk/src/core/SkBitmapProcShader.cpp index d7c7269c894c..9c2c77b9506c 100644 --- a/gfx/skia/trunk/src/core/SkBitmapProcShader.cpp +++ b/gfx/skia/trunk/src/core/SkBitmapProcShader.cpp @@ -18,11 +18,11 @@ #endif bool SkBitmapProcShader::CanDo(const SkBitmap& bm, TileMode tx, TileMode ty) { - switch (bm.config()) { - case SkBitmap::kA8_Config: - case SkBitmap::kRGB_565_Config: - case SkBitmap::kIndex8_Config: - case SkBitmap::kARGB_8888_Config: + switch (bm.colorType()) { + case kAlpha_8_SkColorType: + case kRGB_565_SkColorType: + case kIndex_8_SkColorType: + case kPMColor_SkColorType: // if (tx == ty && (kClamp_TileMode == tx || kRepeat_TileMode == tx)) return true; default: @@ -88,7 +88,7 @@ static bool valid_for_drawing(const SkBitmap& bm) { if (NULL == bm.pixelRef()) { return false; // no pixels to read } - if (SkBitmap::kIndex8_Config == bm.config()) { + if (kIndex_8_SkColorType == bm.colorType()) { // ugh, I have to lock-pixels to inspect the colortable SkAutoLockPixels alp(bm); if (!bm.getColorTable()) { @@ -125,23 +125,23 @@ bool SkBitmapProcShader::setContext(const SkBitmap& device, flags |= kOpaqueAlpha_Flag; } - switch (bitmap.config()) { - case SkBitmap::kRGB_565_Config: + switch (bitmap.colorType()) { + case kRGB_565_SkColorType: flags |= (kHasSpan16_Flag | kIntrinsicly16_Flag); break; - case SkBitmap::kIndex8_Config: - case SkBitmap::kARGB_8888_Config: + case kIndex_8_SkColorType: + case kPMColor_SkColorType: if (bitmapIsOpaque) { flags |= kHasSpan16_Flag; } break; - case SkBitmap::kA8_Config: + case kAlpha_8_SkColorType: break; // never set kHasSpan16_Flag default: break; } - if (paint.isDither() && bitmap.config() != SkBitmap::kRGB_565_Config) { + if (paint.isDither() && bitmap.colorType() != kRGB_565_SkColorType) { // gradients can auto-dither in their 16bit sampler, but we don't so // we clear the flag here. flags &= ~kHasSpan16_Flag; @@ -278,14 +278,14 @@ static bool canUseColorShader(const SkBitmap& bm, SkColor* color) { return false; } - switch (bm.config()) { - case SkBitmap::kARGB_8888_Config: + switch (bm.colorType()) { + case kPMColor_SkColorType: *color = SkUnPreMultiply::PMColorToColor(*bm.getAddr32(0, 0)); return true; - case SkBitmap::kRGB_565_Config: + case kRGB_565_SkColorType: *color = SkPixel16ToColor(*bm.getAddr16(0, 0)); return true; - case SkBitmap::kIndex8_Config: + case kIndex_8_SkColorType: *color = SkUnPreMultiply::PMColorToColor(bm.getIndex8Color(0, 0)); return true; default: // just skip the other configs for now @@ -294,8 +294,6 @@ static bool canUseColorShader(const SkBitmap& bm, SkColor* color) { return false; } -#include "SkTemplatesPriv.h" - static bool bitmapIsTooBig(const SkBitmap& bm) { // SkBitmapProcShader stores bitmap coordinates in a 16bit buffer, as it // communicates between its matrix-proc and its sampler-proc. Until we can @@ -306,27 +304,36 @@ static bool bitmapIsTooBig(const SkBitmap& bm) { return bm.width() > maxSize || bm.height() > maxSize; } -SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, - TileMode tmx, TileMode tmy, - void* storage, size_t storageSize) { +SkShader* CreateBitmapShader(const SkBitmap& src, SkShader::TileMode tmx, + SkShader::TileMode tmy, SkTBlitterAllocator* allocator) { SkShader* shader; SkColor color; if (src.isNull() || bitmapIsTooBig(src)) { - SK_PLACEMENT_NEW(shader, SkEmptyShader, storage, storageSize); + if (NULL == allocator) { + shader = SkNEW(SkEmptyShader); + } else { + shader = allocator->createT(); + } } else if (canUseColorShader(src, &color)) { - SK_PLACEMENT_NEW_ARGS(shader, SkColorShader, storage, storageSize, - (color)); + if (NULL == allocator) { + shader = SkNEW_ARGS(SkColorShader, (color)); + } else { + shader = allocator->createT(color); + } } else { - SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, - storageSize, (src, tmx, tmy)); + if (NULL == allocator) { + shader = SkNEW_ARGS(SkBitmapProcShader, (src, tmx, tmy)); + } else { + shader = allocator->createT(src, tmx, tmy); + } } return shader; } /////////////////////////////////////////////////////////////////////////////// -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkBitmapProcShader::toString(SkString* str) const { static const char* gTileModeName[SkShader::kTileModeCount] = { "clamp", "repeat", "mirror" diff --git a/gfx/skia/trunk/src/core/SkBitmapProcShader.h b/gfx/skia/trunk/src/core/SkBitmapProcShader.h index b7e60f1ca107..8e225a5e9865 100644 --- a/gfx/skia/trunk/src/core/SkBitmapProcShader.h +++ b/gfx/skia/trunk/src/core/SkBitmapProcShader.h @@ -12,6 +12,7 @@ #include "SkShader.h" #include "SkBitmapProcState.h" +#include "SkSmallAllocator.h" class SkBitmapProcShader : public SkShader { public: @@ -29,7 +30,7 @@ public: static bool CanDo(const SkBitmap&, TileMode tx, TileMode ty); - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader) #if SK_SUPPORT_GPU @@ -48,4 +49,14 @@ private: typedef SkShader INHERITED; }; +// Commonly used allocator. It currently is only used to allocate up to 2 objects. The total +// bytes requested is calculated using one of our large shaders plus the size of an Sk3DBlitter +// in SkDraw.cpp +typedef SkSmallAllocator<2, sizeof(SkBitmapProcShader) + sizeof(void*) * 2> SkTBlitterAllocator; + +// If alloc is non-NULL, it will be used to allocate the returned SkShader, and MUST outlive +// the SkShader. +SkShader* CreateBitmapShader(const SkBitmap& src, SkShader::TileMode, SkShader::TileMode, + SkTBlitterAllocator* alloc); + #endif diff --git a/gfx/skia/trunk/src/core/SkBitmapScaler.cpp b/gfx/skia/trunk/src/core/SkBitmapScaler.cpp index 67a9508ee982..9e8c5feef039 100644 --- a/gfx/skia/trunk/src/core/SkBitmapScaler.cpp +++ b/gfx/skia/trunk/src/core/SkBitmapScaler.cpp @@ -89,8 +89,15 @@ SkResizeFilter::SkResizeFilter(SkBitmapScaler::ResizeMethod method, this->computeFilters(srcFullWidth, destSubset.fLeft, destSubset.width(), scaleX, &fXFilter, convolveProcs); - this->computeFilters(srcFullHeight, destSubset.fTop, destSubset.height(), - scaleY, &fYFilter, convolveProcs); + if (srcFullWidth == srcFullHeight && + destSubset.fLeft == destSubset.fTop && + destSubset.width() == destSubset.height()&& + scaleX == scaleY) { + fYFilter = fXFilter; + } else { + this->computeFilters(srcFullHeight, destSubset.fTop, destSubset.height(), + scaleY, &fYFilter, convolveProcs); + } } // TODO(egouriou): Take advantage of periods in the convolution. @@ -228,7 +235,11 @@ static SkBitmapScaler::ResizeMethod ResizeMethodToAlgorithmMethod( case SkBitmapScaler::RESIZE_BETTER: return SkBitmapScaler::RESIZE_HAMMING; default: +#ifdef SK_HIGH_QUALITY_IS_LANCZOS + return SkBitmapScaler::RESIZE_LANCZOS3; +#else return SkBitmapScaler::RESIZE_MITCHELL; +#endif } } @@ -271,7 +282,7 @@ bool SkBitmapScaler::Resize(SkBitmap* resultPtr, SkAutoLockPixels locker(source); if (!source.readyToDraw() || - source.config() != SkBitmap::kARGB_8888_Config) { + source.colorType() != kPMColor_SkColorType) { return false; } @@ -286,9 +297,9 @@ bool SkBitmapScaler::Resize(SkBitmap* resultPtr, // Convolve into the result. SkBitmap result; - result.setConfig(SkBitmap::kARGB_8888_Config, - destSubset.width(), destSubset.height(), 0, - source.alphaType()); + result.setConfig(SkImageInfo::MakeN32(destSubset.width(), + destSubset.height(), + source.alphaType())); result.allocPixels(allocator, NULL); if (!result.readyToDraw()) { return false; diff --git a/gfx/skia/trunk/src/core/SkBitmap_scroll.cpp b/gfx/skia/trunk/src/core/SkBitmap_scroll.cpp index e9c886f4a0e7..00a72aa1cab9 100644 --- a/gfx/skia/trunk/src/core/SkBitmap_scroll.cpp +++ b/gfx/skia/trunk/src/core/SkBitmap_scroll.cpp @@ -11,7 +11,7 @@ bool SkBitmap::scrollRect(const SkIRect* subset, int dx, int dy, SkRegion* inval) const { - if (this->isImmutable()) { + if (this->isImmutable() || kUnknown_SkColorType == this->colorType()) { return false; } @@ -23,25 +23,7 @@ bool SkBitmap::scrollRect(const SkIRect* subset, int dx, int dy, tmp.scrollRect(NULL, dx, dy, inval); } - int shift; - - switch (this->config()) { - case kIndex8_Config: - case kA8_Config: - shift = 0; - break; - case kARGB_4444_Config: - case kRGB_565_Config: - shift = 1; - break; - case kARGB_8888_Config: - shift = 2; - break; - default: - // can't scroll this config - return false; - } - + int shift = this->bytesPerPixel() >> 1; int width = this->width(); int height = this->height(); diff --git a/gfx/skia/trunk/src/core/SkBlitter.cpp b/gfx/skia/trunk/src/core/SkBlitter.cpp index 31a3edea769a..4d70395e525d 100644 --- a/gfx/skia/trunk/src/core/SkBlitter.cpp +++ b/gfx/skia/trunk/src/core/SkBlitter.cpp @@ -11,16 +11,16 @@ #include "SkAntiRun.h" #include "SkColor.h" #include "SkColorFilter.h" +#include "SkCoreBlitters.h" #include "SkFilterShader.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" #include "SkMask.h" #include "SkMaskFilter.h" -#include "SkTemplatesPriv.h" +#include "SkString.h" #include "SkTLazy.h" #include "SkUtils.h" #include "SkXfermode.h" -#include "SkString.h" SkBlitter::~SkBlitter() {} @@ -665,7 +665,7 @@ public: } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING virtual void toString(SkString* str) const SK_OVERRIDE { str->append("Sk3DShader: ("); @@ -705,15 +705,10 @@ private: class Sk3DBlitter : public SkBlitter { public: - Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*)) - : fProxy(proxy), f3DShader(shader), fKillProc(killProc) { - shader->ref(); - } - - virtual ~Sk3DBlitter() { - f3DShader->unref(); - fKillProc(fProxy); - } + Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader) + : fProxy(proxy) + , f3DShader(SkRef(shader)) + {} virtual void blitH(int x, int y, int width) { fProxy->blitH(x, y, width); @@ -747,50 +742,15 @@ public: } private: - SkBlitter* fProxy; - Sk3DShader* f3DShader; - void (*fKillProc)(void*); + // fProxy is unowned. It will be deleted by SkSmallAllocator. + SkBlitter* fProxy; + SkAutoTUnref f3DShader; }; /////////////////////////////////////////////////////////////////////////////// #include "SkCoreBlitters.h" -class SkAutoCallProc { -public: - typedef void (*Proc)(void*); - - SkAutoCallProc(void* obj, Proc proc) - : fObj(obj), fProc(proc) {} - - ~SkAutoCallProc() { - if (fObj && fProc) { - fProc(fObj); - } - } - - void* get() const { return fObj; } - - void* detach() { - void* obj = fObj; - fObj = NULL; - return obj; - } - -private: - void* fObj; - Proc fProc; -}; -#define SkAutoCallProc(...) SK_REQUIRE_LOCAL_VAR(SkAutoCallProc) - -static void destroy_blitter(void* blitter) { - ((SkBlitter*)blitter)->~SkBlitter(); -} - -static void delete_blitter(void* blitter) { - SkDELETE((SkBlitter*)blitter); -} - static bool just_solid_color(const SkPaint& paint) { if (paint.getAlpha() == 0xFF && paint.getColorFilter() == NULL) { SkShader* shader = paint.getShader(); @@ -812,7 +772,7 @@ enum XferInterp { }; static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer, - SkBitmap::Config deviceConfig) { + SkColorType deviceCT) { SkXfermode::Mode mode; if (SkXfermode::AsMode(xfer, &mode)) { @@ -827,12 +787,12 @@ static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer, case SkXfermode::kSrcOver_Mode: return kSrcOver_XferInterp; case SkXfermode::kDstOver_Mode: - if (SkBitmap::kRGB_565_Config == deviceConfig) { + if (kRGB_565_SkColorType == deviceCT) { return kSkipDrawing_XferInterp; } break; case SkXfermode::kSrcIn_Mode: - if (SkBitmap::kRGB_565_Config == deviceConfig && + if (kRGB_565_SkColorType == deviceCT && just_solid_color(paint)) { return kSrcOver_XferInterp; } @@ -852,17 +812,17 @@ static XferInterp interpret_xfermode(const SkPaint& paint, SkXfermode* xfer, SkBlitter* SkBlitter::Choose(const SkBitmap& device, const SkMatrix& matrix, const SkPaint& origPaint, - void* storage, size_t storageSize, + SkTBlitterAllocator* allocator, bool drawCoverage) { - SkASSERT(storageSize == 0 || storage != NULL); + SkASSERT(allocator != NULL); SkBlitter* blitter = NULL; // which check, in case we're being called by a client with a dummy device // (e.g. they have a bounder that always aborts the draw) - if (SkBitmap::kNo_Config == device.config() || - (drawCoverage && (SkBitmap::kA8_Config != device.config()))) { - SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); + if (kUnknown_SkColorType == device.colorType() || + (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) { + blitter = allocator->createT(); return blitter; } @@ -882,14 +842,15 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device, } if (NULL != mode) { - switch (interpret_xfermode(*paint, mode, device.config())) { + switch (interpret_xfermode(*paint, mode, device.colorType())) { case kSrcOver_XferInterp: mode = NULL; paint.writable()->setXfermode(NULL); break; - case kSkipDrawing_XferInterp: - SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); + case kSkipDrawing_XferInterp:{ + blitter = allocator->createT(); return blitter; + } default: break; } @@ -940,59 +901,50 @@ SkBlitter* SkBlitter::Choose(const SkBitmap& device, * not fail) in its destructor. */ if (shader && !shader->setContext(device, *paint, matrix)) { - SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); + blitter = allocator->createT(); return blitter; } - switch (device.config()) { - case SkBitmap::kA8_Config: + switch (device.colorType()) { + case kAlpha_8_SkColorType: if (drawCoverage) { SkASSERT(NULL == shader); SkASSERT(NULL == paint->getXfermode()); - SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Coverage_Blitter, - storage, storageSize, (device, *paint)); + blitter = allocator->createT(device, *paint); } else if (shader) { - SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter, - storage, storageSize, (device, *paint)); + blitter = allocator->createT(device, *paint); } else { - SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter, - storage, storageSize, (device, *paint)); + blitter = allocator->createT(device, *paint); } break; - case SkBitmap::kRGB_565_Config: - blitter = SkBlitter_ChooseD565(device, *paint, storage, storageSize); + case kRGB_565_SkColorType: + blitter = SkBlitter_ChooseD565(device, *paint, allocator); break; - case SkBitmap::kARGB_8888_Config: + case kPMColor_SkColorType: if (shader) { - SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter, - storage, storageSize, (device, *paint)); + blitter = allocator->createT(device, *paint); } else if (paint->getColor() == SK_ColorBLACK) { - SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter, - storage, storageSize, (device, *paint)); + blitter = allocator->createT(device, *paint); } else if (paint->getAlpha() == 0xFF) { - SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter, - storage, storageSize, (device, *paint)); + blitter = allocator->createT(device, *paint); } else { - SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter, - storage, storageSize, (device, *paint)); + blitter = allocator->createT(device, *paint); } break; default: SkDEBUGFAIL("unsupported device config"); - SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); + blitter = allocator->createT(); break; } if (shader3D) { - void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitter : delete_blitter; - SkAutoCallProc tmp(blitter, proc); - - blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc)); - (void)tmp.detach(); + SkBlitter* innerBlitter = blitter; + // innerBlitter was allocated by allocator, which will delete it. + blitter = allocator->createT(innerBlitter, shader3D); } return blitter; } diff --git a/gfx/skia/trunk/src/core/SkBlitter.h b/gfx/skia/trunk/src/core/SkBlitter.h index b659fe473581..d19a34badcd4 100644 --- a/gfx/skia/trunk/src/core/SkBlitter.h +++ b/gfx/skia/trunk/src/core/SkBlitter.h @@ -11,11 +11,14 @@ #define SkBlitter_DEFINED #include "SkBitmap.h" +#include "SkBitmapProcShader.h" +#include "SkMask.h" #include "SkMatrix.h" #include "SkPaint.h" #include "SkRefCnt.h" #include "SkRegion.h" -#include "SkMask.h" +#include "SkShader.h" +#include "SkSmallAllocator.h" /** SkBlitter and its subclasses are responsible for actually writing pixels into memory. Besides efficiency, they handle clipping and antialiasing. @@ -67,23 +70,17 @@ public: /** @name Factories Return the correct blitter to use given the specified context. */ - static SkBlitter* Choose(const SkBitmap& device, - const SkMatrix& matrix, - const SkPaint& paint) { - return Choose(device, matrix, paint, NULL, 0); - } - static SkBlitter* Choose(const SkBitmap& device, const SkMatrix& matrix, const SkPaint& paint, - void* storage, size_t storageSize, + SkTBlitterAllocator*, bool drawCoverage = false); static SkBlitter* ChooseSprite(const SkBitmap& device, const SkPaint&, const SkBitmap& src, int left, int top, - void* storage, size_t storageSize); + SkTBlitterAllocator*); ///@} private: diff --git a/gfx/skia/trunk/src/core/SkBlitter_RGB16.cpp b/gfx/skia/trunk/src/core/SkBlitter_RGB16.cpp index 256cbc6936f6..b01800b51f52 100644 --- a/gfx/skia/trunk/src/core/SkBlitter_RGB16.cpp +++ b/gfx/skia/trunk/src/core/SkBlitter_RGB16.cpp @@ -12,7 +12,6 @@ #include "SkColorPriv.h" #include "SkDither.h" #include "SkShader.h" -#include "SkTemplatesPriv.h" #include "SkUtils.h" #include "SkXfermode.h" @@ -1013,7 +1012,9 @@ void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, /////////////////////////////////////////////////////////////////////////////// SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, - void* storage, size_t storageSize) { + SkTBlitterAllocator* allocator) { + SkASSERT(allocator != NULL); + SkBlitter* blitter; SkShader* shader = paint.getShader(); SkXfermode* mode = paint.getXfermode(); @@ -1023,31 +1024,25 @@ SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, if (shader) { if (mode) { - SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter, - storage, storageSize, (device, paint)); + blitter = allocator->createT(device, paint); } else if (shader->canCallShadeSpan16()) { - SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, - storage, storageSize, (device, paint)); + blitter = allocator->createT(device, paint); } else { - SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, - storage, storageSize, (device, paint)); + blitter = allocator->createT(device, paint); } } else { // no shader, no xfermode, (and we always ignore colorfilter) SkColor color = paint.getColor(); if (0 == SkColorGetA(color)) { - SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize); + blitter = allocator->createT(); #ifdef USE_BLACK_BLITTER } else if (SK_ColorBLACK == color) { - SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage, - storageSize, (device, paint)); + blitter = allocator->createT(device, paint); #endif } else if (0xFF == SkColorGetA(color)) { - SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Opaque_Blitter, storage, - storageSize, (device, paint)); + blitter = allocator->createT(device, paint); } else { - SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage, - storageSize, (device, paint)); + blitter = allocator->createT(device, paint); } } diff --git a/gfx/skia/trunk/src/core/SkBlitter_Sprite.cpp b/gfx/skia/trunk/src/core/SkBlitter_Sprite.cpp index 9322e2039673..e15e2fcde4bd 100644 --- a/gfx/skia/trunk/src/core/SkBlitter_Sprite.cpp +++ b/gfx/skia/trunk/src/core/SkBlitter_Sprite.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2006 The Android Open Source Project * @@ -6,7 +5,7 @@ * found in the LICENSE file. */ - +#include "SkSmallAllocator.h" #include "SkSpriteBlitter.h" SkSpriteBlitter::SkSpriteBlitter(const SkBitmap& source) @@ -49,11 +48,8 @@ void SkSpriteBlitter::blitMask(const SkMask&, const SkIRect& clip) { // returning null means the caller will call SkBlitter::Choose() and // have wrapped the source bitmap inside a shader -SkBlitter* SkBlitter::ChooseSprite( const SkBitmap& device, - const SkPaint& paint, - const SkBitmap& source, - int left, int top, - void* storage, size_t storageSize) { +SkBlitter* SkBlitter::ChooseSprite(const SkBitmap& device, const SkPaint& paint, + const SkBitmap& source, int left, int top, SkTBlitterAllocator* allocator) { /* We currently ignore antialiasing and filtertype, meaning we will take our special blitters regardless of these settings. Ignoring filtertype seems fine since by definition there is no scale in the matrix. Ignoring antialiasing is @@ -63,17 +59,16 @@ SkBlitter* SkBlitter::ChooseSprite( const SkBitmap& device, paint and return null if it is set, forcing the client to take the slow shader case (which does respect soft edges). */ + SkASSERT(allocator != NULL); SkSpriteBlitter* blitter; - switch (device.config()) { - case SkBitmap::kRGB_565_Config: - blitter = SkSpriteBlitter::ChooseD16(source, paint, storage, - storageSize); + switch (device.colorType()) { + case kRGB_565_SkColorType: + blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator); break; - case SkBitmap::kARGB_8888_Config: - blitter = SkSpriteBlitter::ChooseD32(source, paint, storage, - storageSize); + case kPMColor_SkColorType: + blitter = SkSpriteBlitter::ChooseD32(source, paint, allocator); break; default: blitter = NULL; diff --git a/gfx/skia/trunk/src/core/SkCanvas.cpp b/gfx/skia/trunk/src/core/SkCanvas.cpp index ed8274dc5d3b..d637405445df 100644 --- a/gfx/skia/trunk/src/core/SkCanvas.cpp +++ b/gfx/skia/trunk/src/core/SkCanvas.cpp @@ -19,6 +19,7 @@ #include "SkPicture.h" #include "SkRasterClip.h" #include "SkRRect.h" +#include "SkSmallAllocator.h" #include "SkSurface_Base.h" #include "SkTemplates.h" #include "SkTextFormatParams.h" @@ -212,7 +213,6 @@ private: */ class SkCanvas::MCRec { public: - MCRec* fNext; int fFlags; SkMatrix* fMatrix; // points to either fMatrixStorage or prev MCRec SkRasterClip* fRasterClip; // points to either fRegionStorage or prev MCRec @@ -338,7 +338,6 @@ public: bool skipLayerForImageFilter = false, const SkRect* bounds = NULL) : fOrigPaint(paint) { fCanvas = canvas; - fLooper = paint.getLooper(); fFilter = canvas->getDrawFilter(); fPaint = NULL; fSaveCount = canvas->getSaveCount(); @@ -348,17 +347,20 @@ public: if (!skipLayerForImageFilter && fOrigPaint.getImageFilter()) { SkPaint tmp; tmp.setImageFilter(fOrigPaint.getImageFilter()); - (void)canvas->internalSaveLayer(bounds, &tmp, - SkCanvas::kARGB_ClipLayer_SaveFlag, true); + (void)canvas->internalSaveLayer(bounds, &tmp, SkCanvas::kARGB_ClipLayer_SaveFlag, + true, SkCanvas::kFullLayer_SaveLayerStrategy); // we'll clear the imageFilter for the actual draws in next(), so // it will only be applied during the restore(). fDoClearImageFilter = true; } - if (fLooper) { - fLooper->init(canvas); + if (SkDrawLooper* looper = paint.getLooper()) { + void* buffer = fLooperContextAllocator.reserveT( + looper->contextSize()); + fLooperContext = looper->createContext(canvas, buffer); fIsSimple = false; } else { + fLooperContext = NULL; // can we be marked as simple? fIsSimple = !fFilter && !fDoClearImageFilter; } @@ -392,13 +394,14 @@ private: SkLazyPaint fLazyPaint; SkCanvas* fCanvas; const SkPaint& fOrigPaint; - SkDrawLooper* fLooper; SkDrawFilter* fFilter; const SkPaint* fPaint; int fSaveCount; bool fDoClearImageFilter; bool fDone; bool fIsSimple; + SkDrawLooper::Context* fLooperContext; + SkSmallAllocator<1, 32> fLooperContextAllocator; bool doNext(SkDrawFilter::Type drawType); }; @@ -406,7 +409,7 @@ private: bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { fPaint = NULL; SkASSERT(!fIsSimple); - SkASSERT(fLooper || fFilter || fDoClearImageFilter); + SkASSERT(fLooperContext || fFilter || fDoClearImageFilter); SkPaint* paint = fLazyPaint.set(fOrigPaint); @@ -414,7 +417,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { paint->setImageFilter(NULL); } - if (fLooper && !fLooper->next(fCanvas, paint)) { + if (fLooperContext && !fLooperContext->next(fCanvas, paint)) { fDone = true; return false; } @@ -423,7 +426,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { fDone = true; return false; } - if (NULL == fLooper) { + if (NULL == fLooperContext) { // no looper means we only draw once fDone = true; } @@ -431,7 +434,7 @@ bool AutoDrawLooper::doNext(SkDrawFilter::Type drawType) { fPaint = paint; // if we only came in here for the imagefilter, mark us as done - if (!fLooper && !fFilter) { + if (!fLooperContext && !fFilter) { fDone = true; } @@ -490,6 +493,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device) { fAllowSimplifyClip = false; fDeviceCMDirty = false; fSaveLayerCount = 0; + fCullCount = 0; fMetaData = NULL; fMCRec = (MCRec*)fMCStack.push_back(); @@ -497,11 +501,10 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device) { fMCRec->fLayer = SkNEW_ARGS(DeviceCM, (NULL, 0, 0, NULL, NULL)); fMCRec->fTopLayer = fMCRec->fLayer; - fMCRec->fNext = NULL; fSurfaceBase = NULL; - return this->setDevice(device); + return this->setRootDevice(device); } SkCanvas::SkCanvas() @@ -518,7 +521,7 @@ SkCanvas::SkCanvas(int width, int height) inc_canvas(); SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kNo_Config, width, height); + bitmap.setConfig(SkImageInfo::MakeUnknown(width, height)); this->init(SkNEW_ARGS(SkBitmapDevice, (bitmap)))->unref(); } @@ -583,7 +586,17 @@ void SkCanvas::flush() { } } -SkISize SkCanvas::getDeviceSize() const { +SkISize SkCanvas::getTopLayerSize() const { + SkBaseDevice* d = this->getTopDevice(); + return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); +} + +SkIPoint SkCanvas::getTopLayerOrigin() const { + SkBaseDevice* d = this->getTopDevice(); + return d ? d->getOrigin() : SkIPoint::Make(0, 0); +} + +SkISize SkCanvas::getBaseLayerSize() const { SkBaseDevice* d = this->getDevice(); return d ? SkISize::Make(d->width(), d->height()) : SkISize::Make(0, 0); } @@ -602,7 +615,7 @@ SkBaseDevice* SkCanvas::getTopDevice(bool updateMatrixClip) const { return fMCRec->fTopLayer->fDevice; } -SkBaseDevice* SkCanvas::setDevice(SkBaseDevice* device) { +SkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) { // return root device SkDeque::F2BIter iter(fMCStack); MCRec* rec = (MCRec*)iter.next(); @@ -687,6 +700,7 @@ bool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) { } } +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG void SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y, Config8888 config8888) { SkBaseDevice* device = this->getDevice(); @@ -698,6 +712,62 @@ void SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y, } } } +#endif + +bool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) { + if (bitmap.getTexture()) { + return false; + } + SkBitmap bm(bitmap); + bm.lockPixels(); + if (bm.getPixels()) { + return this->writePixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y); + } + return false; +} + +bool SkCanvas::writePixels(const SkImageInfo& origInfo, const void* pixels, size_t rowBytes, + int x, int y) { + switch (origInfo.colorType()) { + case kUnknown_SkColorType: + case kIndex_8_SkColorType: + return false; + default: + break; + } + if (NULL == pixels || rowBytes < origInfo.minRowBytes()) { + return false; + } + + const SkISize size = this->getBaseLayerSize(); + SkIRect target = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height()); + if (!target.intersect(0, 0, size.width(), size.height())) { + return false; + } + + SkBaseDevice* device = this->getDevice(); + if (!device) { + return false; + } + + SkImageInfo info = origInfo; + // the intersect may have shrunk info's logical size + info.fWidth = target.width(); + info.fHeight = target.height(); + + // if x or y are negative, then we have to adjust pixels + if (x > 0) { + x = 0; + } + if (y > 0) { + y = 0; + } + // here x,y are either 0 or negative + pixels = ((const char*)pixels - y * rowBytes - x * info.bytesPerPixel()); + + // The device can assert that the requested area is always contained in its bounds + return device->writePixelsDirect(info, pixels, rowBytes, target.x(), target.y()); +} SkCanvas* SkCanvas::canvasForDrawIter() { return this; @@ -731,7 +801,6 @@ int SkCanvas::internalSave(SaveFlags flags) { MCRec* newTop = (MCRec*)fMCStack.push_back(); new (newTop) MCRec(fMCRec, flags); // balanced in restore() - newTop->fNext = fMCRec; fMCRec = newTop; if (SkCanvas::kClip_SaveFlag & flags) { @@ -741,53 +810,22 @@ int SkCanvas::internalSave(SaveFlags flags) { return saveCount; } +void SkCanvas::willSave(SaveFlags) { + // Do nothing. Subclasses may do something. +} + int SkCanvas::save(SaveFlags flags) { + this->willSave(flags); // call shared impl return this->internalSave(flags); } -#define C32MASK (1 << SkBitmap::kARGB_8888_Config) -#define C16MASK (1 << SkBitmap::kRGB_565_Config) -#define C8MASK (1 << SkBitmap::kA8_Config) - -static SkBitmap::Config resolve_config(SkCanvas* canvas, - const SkIRect& bounds, - SkCanvas::SaveFlags flags, - bool* isOpaque) { - *isOpaque = (flags & SkCanvas::kHasAlphaLayer_SaveFlag) == 0; - -#if 0 - // loop through and union all the configs we may draw into - uint32_t configMask = 0; - for (int i = canvas->countLayerDevices() - 1; i >= 0; --i) - { - SkBaseDevice* device = canvas->getLayerDevice(i); - if (device->intersects(bounds)) - configMask |= 1 << device->config(); - } - - // if the caller wants alpha or fullcolor, we can't return 565 - if (flags & (SkCanvas::kFullColorLayer_SaveFlag | - SkCanvas::kHasAlphaLayer_SaveFlag)) - configMask &= ~C16MASK; - - switch (configMask) { - case C8MASK: // if we only have A8, return that - return SkBitmap::kA8_Config; - - case C16MASK: // if we only have 565, return that - return SkBitmap::kRGB_565_Config; - - default: - return SkBitmap::kARGB_8888_Config; // default answer - } -#else - return SkBitmap::kARGB_8888_Config; // default answer -#endif -} - static bool bounds_affects_clip(SkCanvas::SaveFlags flags) { +#ifdef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG return (flags & SkCanvas::kClipToLayer_SaveFlag) != 0; +#else + return true; +#endif } bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, @@ -820,12 +858,12 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, ir = clipBounds; } - fClipStack.clipDevRect(ir, op); - - // early exit if the clip is now empty - if (bounds_affects_clip(flags) && - !fMCRec->fRasterClip->op(ir, op)) { - return false; + if (bounds_affects_clip(flags)) { + fClipStack.clipDevRect(ir, op); + // early exit if the clip is now empty + if (!fMCRec->fRasterClip->op(ir, op)) { + return false; + } } if (intersection) { @@ -834,25 +872,31 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveFlags flags, return true; } +SkCanvas::SaveLayerStrategy SkCanvas::willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) { + + // Do nothing. Subclasses may do something. + return kFullLayer_SaveLayerStrategy; +} + int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags) { - return this->internalSaveLayer(bounds, paint, flags, false); + // Overriding classes may return false to signal that we don't need to create a layer. + SaveLayerStrategy strategy = this->willSaveLayer(bounds, paint, flags); + return this->internalSaveLayer(bounds, paint, flags, false, strategy); } static SkBaseDevice* createCompatibleDevice(SkCanvas* canvas, - SkBitmap::Config config, - int width, int height, - bool isOpaque) { + const SkImageInfo& info) { SkBaseDevice* device = canvas->getDevice(); - if (device) { - return device->createCompatibleDevice(config, width, height, isOpaque); - } else { - return NULL; - } + return device ? device->createCompatibleDevice(info) : NULL; } -int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags, bool justForImageFilter) { +int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags, + bool justForImageFilter, SaveLayerStrategy strategy) { +#ifndef SK_SUPPORT_LEGACY_CLIPTOLAYERFLAG + flags = (SaveFlags)(flags | kClipToLayer_SaveFlag); +#endif + // do this before we create the layer. We don't call the public save() since // that would invoke a possibly overridden virtual int count = this->internalSave(flags); @@ -864,6 +908,12 @@ int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, return count; } + // FIXME: do willSaveLayer() overriders returning kNoLayer_SaveLayerStrategy really care about + // the clipRectBounds() call above? + if (kNoLayer_SaveLayerStrategy == strategy) { + return count; + } + // Kill the imagefilter if our device doesn't allow it SkLazyPaint lazyP; if (paint && paint->getImageFilter()) { @@ -878,16 +928,15 @@ int SkCanvas::internalSaveLayer(const SkRect* bounds, const SkPaint* paint, } } - bool isOpaque; - SkBitmap::Config config = resolve_config(this, ir, flags, &isOpaque); + bool isOpaque = !SkToBool(flags & kHasAlphaLayer_SaveFlag); + SkImageInfo info = SkImageInfo::MakeN32(ir.width(), ir.height(), + isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); SkBaseDevice* device; if (paint && paint->getImageFilter()) { - device = createCompatibleDevice(this, config, ir.width(), ir.height(), - isOpaque); + device = createCompatibleDevice(this, info); } else { - device = this->createLayerDevice(config, ir.width(), ir.height(), - isOpaque); + device = this->createLayerDevice(info); } if (NULL == device) { SkDebugf("Unable to create device for layer."); @@ -917,9 +966,14 @@ int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha, } } +void SkCanvas::willRestore() { + // Do nothing. Subclasses may do something. +} + void SkCanvas::restore() { // check for underflow if (fMCStack.count() > 1) { + this->willRestore(); this->internalRestore(); } } @@ -992,6 +1046,70 @@ SkSurface* SkCanvas::onNewSurface(const SkImageInfo& info) { return dev ? dev->newSurface(info) : NULL; } +SkImageInfo SkCanvas::imageInfo() const { + SkBaseDevice* dev = this->getDevice(); + if (dev) { + return dev->imageInfo(); + } else { + return SkImageInfo::MakeUnknown(0, 0); + } +} + +const void* SkCanvas::peekPixels(SkImageInfo* info, size_t* rowBytes) { + return this->onPeekPixels(info, rowBytes); +} + +const void* SkCanvas::onPeekPixels(SkImageInfo* info, size_t* rowBytes) { + SkBaseDevice* dev = this->getDevice(); + return dev ? dev->peekPixels(info, rowBytes) : NULL; +} + +void* SkCanvas::accessTopLayerPixels(SkImageInfo* info, size_t* rowBytes) { + return this->onAccessTopLayerPixels(info, rowBytes); +} + +void* SkCanvas::onAccessTopLayerPixels(SkImageInfo* info, size_t* rowBytes) { + SkBaseDevice* dev = this->getTopDevice(); + return dev ? dev->accessPixels(info, rowBytes) : NULL; +} + +SkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) { + fAddr = canvas->peekPixels(&fInfo, &fRowBytes); + if (NULL == fAddr) { + fInfo = canvas->imageInfo(); + if (kUnknown_SkColorType == fInfo.colorType() || + !fBitmap.allocPixels(fInfo)) + { + return; // failure, fAddr is NULL + } + fBitmap.lockPixels(); + if (!canvas->readPixels(&fBitmap, 0, 0)) { + return; // failure, fAddr is NULL + } + fAddr = fBitmap.getPixels(); + fRowBytes = fBitmap.rowBytes(); + } + SkASSERT(fAddr); // success +} + +bool SkAutoROCanvasPixels::asROBitmap(SkBitmap* bitmap) const { + if (fAddr) { + return bitmap->installPixels(fInfo, const_cast(fAddr), fRowBytes, + NULL, NULL); + } else { + bitmap->reset(); + return false; + } +} + +void SkCanvas::onPushCull(const SkRect& cullRect) { + // do nothing. Subclasses may do something +} + +void SkCanvas::onPopCull() { + // do nothing. Subclasses may do something +} + ///////////////////////////////////////////////////////////////////////////// void SkCanvas::internalDrawBitmap(const SkBitmap& bitmap, @@ -1046,7 +1164,9 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkBitmap& src = srcDev->accessBitmap(false); SkMatrix matrix = *iter.fMatrix; matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); - if (filter->filterImage(&proxy, src, matrix, &dst, &offset)) { + SkIRect clipBounds = SkIRect::MakeWH(srcDev->width(), srcDev->height()); + SkImageFilter::Context ctx(matrix, clipBounds); + if (filter->filterImage(&proxy, src, ctx, &dst, &offset)) { SkPaint tmpUnfiltered(*paint); tmpUnfiltered.setImageFilter(NULL); dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), @@ -1084,7 +1204,9 @@ void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, SkIPoint offset = SkIPoint::Make(0, 0); SkMatrix matrix = *iter.fMatrix; matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); - if (filter->filterImage(&proxy, bitmap, matrix, &dst, &offset)) { + SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); + SkImageFilter::Context ctx(matrix, clipBounds); + if (filter->filterImage(&proxy, bitmap, ctx, &dst, &offset)) { SkPaint tmpUnfiltered(*paint); tmpUnfiltered.setImageFilter(NULL); iter.fDevice->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(), @@ -1098,45 +1220,82 @@ void SkCanvas::drawSprite(const SkBitmap& bitmap, int x, int y, } ///////////////////////////////////////////////////////////////////////////// +void SkCanvas::didTranslate(SkScalar, SkScalar) { + // Do nothing. Subclasses may do something. +} bool SkCanvas::translate(SkScalar dx, SkScalar dy) { fDeviceCMDirty = true; fCachedLocalClipBoundsDirty = true; - return fMCRec->fMatrix->preTranslate(dx, dy); + bool res = fMCRec->fMatrix->preTranslate(dx, dy); + + this->didTranslate(dx, dy); + return res; +} + +void SkCanvas::didScale(SkScalar, SkScalar) { + // Do nothing. Subclasses may do something. } bool SkCanvas::scale(SkScalar sx, SkScalar sy) { fDeviceCMDirty = true; fCachedLocalClipBoundsDirty = true; - return fMCRec->fMatrix->preScale(sx, sy); + bool res = fMCRec->fMatrix->preScale(sx, sy); + + this->didScale(sx, sy); + return res; +} + +void SkCanvas::didRotate(SkScalar) { + // Do nothing. Subclasses may do something. } bool SkCanvas::rotate(SkScalar degrees) { fDeviceCMDirty = true; fCachedLocalClipBoundsDirty = true; - return fMCRec->fMatrix->preRotate(degrees); + bool res = fMCRec->fMatrix->preRotate(degrees); + + this->didRotate(degrees); + return res; +} + +void SkCanvas::didSkew(SkScalar, SkScalar) { + // Do nothing. Subclasses may do something. } bool SkCanvas::skew(SkScalar sx, SkScalar sy) { fDeviceCMDirty = true; fCachedLocalClipBoundsDirty = true; - return fMCRec->fMatrix->preSkew(sx, sy); + bool res = fMCRec->fMatrix->preSkew(sx, sy); + + this->didSkew(sx, sy); + return res; +} + +void SkCanvas::didConcat(const SkMatrix&) { + // Do nothing. Subclasses may do something. } bool SkCanvas::concat(const SkMatrix& matrix) { fDeviceCMDirty = true; fCachedLocalClipBoundsDirty = true; - return fMCRec->fMatrix->preConcat(matrix); + bool res = fMCRec->fMatrix->preConcat(matrix); + + this->didConcat(matrix); + return res; +} + +void SkCanvas::didSetMatrix(const SkMatrix&) { + // Do nothing. Subclasses may do something. } void SkCanvas::setMatrix(const SkMatrix& matrix) { fDeviceCMDirty = true; fCachedLocalClipBoundsDirty = true; *fMCRec->fMatrix = matrix; + this->didSetMatrix(matrix); } -// this is not virtual, so it must call a virtual method so that subclasses -// will see its action void SkCanvas::resetMatrix() { SkMatrix matrix; @@ -1146,7 +1305,12 @@ void SkCanvas::resetMatrix() { ////////////////////////////////////////////////////////////////////////////// -bool SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { +void SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { + ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; + this->onClipRect(rect, op, edgeStyle); +} + +void SkCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { #ifdef SK_ENABLE_CLIP_QUICKREJECT if (SkRegion::kIntersect_Op == op) { if (fMCRec->fRasterClip->isEmpty()) { @@ -1167,7 +1331,9 @@ bool SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { fDeviceCMDirty = true; fCachedLocalClipBoundsDirty = true; - doAA &= fAllowSoftClip; + if (!fAllowSoftClip) { + edgeStyle = kHard_ClipEdgeStyle; + } if (fMCRec->fMatrix->rectStaysRect()) { // for these simpler matrices, we can stay a rect even after applying @@ -1177,8 +1343,8 @@ bool SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { SkRect r; fMCRec->fMatrix->mapRect(&r, rect); - fClipStack.clipDevRect(r, op, doAA); - return fMCRec->fRasterClip->op(r, op, doAA); + fClipStack.clipDevRect(r, op, kSoft_ClipEdgeStyle == edgeStyle); + fMCRec->fRasterClip->op(r, op, kSoft_ClipEdgeStyle == edgeStyle); } else { // since we're rotated or some such thing, we convert the rect to a path // and clip against that, since it can handle any matrix. However, to @@ -1187,12 +1353,12 @@ bool SkCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { SkPath path; path.addRect(rect); - return this->SkCanvas::clipPath(path, op, doAA); + this->SkCanvas::onClipPath(path, op, edgeStyle); } } -static bool clipPathHelper(const SkCanvas* canvas, SkRasterClip* currClip, - const SkPath& devPath, SkRegion::Op op, bool doAA) { +static void clip_path_helper(const SkCanvas* canvas, SkRasterClip* currClip, + const SkPath& devPath, SkRegion::Op op, bool doAA) { // base is used to limit the size (and therefore memory allocation) of the // region that results from scan converting devPath. SkRegion base; @@ -1205,44 +1371,78 @@ static bool clipPathHelper(const SkCanvas* canvas, SkRasterClip* currClip, // FIXME: we should also be able to do this when currClip->isBW(), // but relaxing the test above triggers GM asserts in // SkRgnBuilder::blitH(). We need to investigate what's going on. - return currClip->setPath(devPath, currClip->bwRgn(), doAA); + currClip->setPath(devPath, currClip->bwRgn(), doAA); } else { base.setRect(currClip->getBounds()); SkRasterClip clip; clip.setPath(devPath, base, doAA); - return currClip->op(clip, op); + currClip->op(clip, op); } } else { const SkBaseDevice* device = canvas->getDevice(); if (!device) { - return currClip->setEmpty(); + currClip->setEmpty(); + return; } base.setRect(0, 0, device->width(), device->height()); if (SkRegion::kReplace_Op == op) { - return currClip->setPath(devPath, base, doAA); + currClip->setPath(devPath, base, doAA); } else { SkRasterClip clip; clip.setPath(devPath, base, doAA); - return currClip->op(clip, op); + currClip->op(clip, op); } } } -bool SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { +void SkCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { + ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; if (rrect.isRect()) { - // call the non-virtual version - return this->SkCanvas::clipRect(rrect.getBounds(), op, doAA); + this->onClipRect(rrect.getBounds(), op, edgeStyle); } else { - SkPath path; - path.addRRect(rrect); - // call the non-virtual version - return this->SkCanvas::clipPath(path, op, doAA); + this->onClipRRect(rrect, op, edgeStyle); } } -bool SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { +void SkCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + SkRRect transformedRRect; + if (rrect.transform(*fMCRec->fMatrix, &transformedRRect)) { + AutoValidateClip avc(this); + + fDeviceCMDirty = true; + fCachedLocalClipBoundsDirty = true; + if (!fAllowSoftClip) { + edgeStyle = kHard_ClipEdgeStyle; + } + + fClipStack.clipDevRRect(transformedRRect, op, kSoft_ClipEdgeStyle == edgeStyle); + + SkPath devPath; + devPath.addRRect(transformedRRect); + + clip_path_helper(this, fMCRec->fRasterClip, devPath, op, kSoft_ClipEdgeStyle == edgeStyle); + return; + } + + SkPath path; + path.addRRect(rrect); + // call the non-virtual version + this->SkCanvas::onClipPath(path, op, edgeStyle); +} + +void SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { + ClipEdgeStyle edgeStyle = doAA ? kSoft_ClipEdgeStyle : kHard_ClipEdgeStyle; + SkRect r; + if (!path.isInverseFillType() && path.isRect(&r)) { + this->onClipRect(r, op, edgeStyle); + } else { + this->onClipPath(path, op, edgeStyle); + } +} + +void SkCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { #ifdef SK_ENABLE_CLIP_QUICKREJECT if (SkRegion::kIntersect_Op == op && !path.isInverseFillType()) { if (fMCRec->fRasterClip->isEmpty()) { @@ -1263,7 +1463,9 @@ bool SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { fDeviceCMDirty = true; fCachedLocalClipBoundsDirty = true; - doAA &= fAllowSoftClip; + if (!fAllowSoftClip) { + edgeStyle = kHard_ClipEdgeStyle; + } SkPath devPath; path.transform(*fMCRec->fMatrix, &devPath); @@ -1279,7 +1481,7 @@ bool SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { } // if we called path.swap() we could avoid a deep copy of this path - fClipStack.clipDevPath(devPath, op, doAA); + fClipStack.clipDevPath(devPath, op, kSoft_ClipEdgeStyle == edgeStyle); if (fAllowSimplifyClip) { devPath.reset(); @@ -1293,13 +1495,7 @@ bool SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { continue; } SkPath operand; - if (type == SkClipStack::Element::kRect_Type) { - operand.addRect(element->getRect()); - } else if (type == SkClipStack::Element::kPath_Type) { - operand = element->getPath(); - } else { - SkDEBUGFAIL("Unexpected type."); - } + element->asPath(&operand); SkRegion::Op elementOp = element->getOp(); if (elementOp == SkRegion::kReplace_Op) { devPath = operand; @@ -1309,15 +1505,17 @@ bool SkCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { // if the prev and curr clips disagree about aa -vs- not, favor the aa request. // perhaps we need an API change to avoid this sort of mixed-signals about // clipping. - doAA |= element->isAA(); + if (element->isAA()) { + edgeStyle = kSoft_ClipEdgeStyle; + } } op = SkRegion::kReplace_Op; } - return clipPathHelper(this, fMCRec->fRasterClip, devPath, op, doAA); + clip_path_helper(this, fMCRec->fRasterClip, devPath, op, edgeStyle); } -bool SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegion::Op op, +void SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegion::Op op, bool inverseFilled) { // This is for updating the clip conservatively using only bounds // information. @@ -1340,13 +1538,12 @@ bool SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio case SkRegion::kIntersect_Op: case SkRegion::kDifference_Op: // These ops can only shrink the current clip. So leaving - // the clip unchanges conservatively respects the contract. - return this->getClipDeviceBounds(NULL); + // the clip unchanged conservatively respects the contract. + break; case SkRegion::kUnion_Op: case SkRegion::kReplace_Op: case SkRegion::kReverseDifference_Op: - case SkRegion::kXOR_Op: - { + case SkRegion::kXOR_Op: { // These ops can grow the current clip up to the extents of // the input clip, which is inverse filled, so we just set // the current clip to the device bounds. @@ -1357,11 +1554,11 @@ bool SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio this->SkCanvas::save(SkCanvas::kMatrix_SaveFlag); // set the clip in device space this->SkCanvas::setMatrix(SkMatrix::I()); - bool result = this->SkCanvas::clipRect(deviceBounds, - SkRegion::kReplace_Op, false); + this->SkCanvas::onClipRect(deviceBounds, SkRegion::kReplace_Op, + kHard_ClipEdgeStyle); this->SkCanvas::restore(); //pop the matrix, but keep the clip - return result; - } + break; + } default: SkASSERT(0); // unhandled op? } @@ -1371,27 +1568,33 @@ bool SkCanvas::updateClipConservativelyUsingBounds(const SkRect& bounds, SkRegio case SkRegion::kIntersect_Op: case SkRegion::kUnion_Op: case SkRegion::kReplace_Op: - return this->SkCanvas::clipRect(bounds, op, false); + this->SkCanvas::onClipRect(bounds, op, kHard_ClipEdgeStyle); + break; case SkRegion::kDifference_Op: // Difference can only shrink the current clip. // Leaving clip unchanged conservatively fullfills the contract. - return this->getClipDeviceBounds(NULL); + break; case SkRegion::kReverseDifference_Op: // To reverse, we swap in the bounds with a replace op. // As with difference, leave it unchanged. - return this->SkCanvas::clipRect(bounds, SkRegion::kReplace_Op, false); + this->SkCanvas::onClipRect(bounds, SkRegion::kReplace_Op, kHard_ClipEdgeStyle); + break; case SkRegion::kXOR_Op: // Be conservative, based on (A XOR B) always included in (A union B), // which is always included in (bounds(A) union bounds(B)) - return this->SkCanvas::clipRect(bounds, SkRegion::kUnion_Op, false); + this->SkCanvas::onClipRect(bounds, SkRegion::kUnion_Op, kHard_ClipEdgeStyle); + break; default: SkASSERT(0); // unhandled op? } } - return true; } -bool SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { +void SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { + this->onClipRegion(rgn, op); +} + +void SkCanvas::onClipRegion(const SkRegion& rgn, SkRegion::Op op) { AutoValidateClip avc(this); fDeviceCMDirty = true; @@ -1401,7 +1604,7 @@ bool SkCanvas::clipRegion(const SkRegion& rgn, SkRegion::Op op) { // we have to ignore it, and use the region directly? fClipStack.clipDevRect(rgn.getBounds(), op); - return fMCRec->fRasterClip->op(rgn, op); + fMCRec->fRasterClip->op(rgn, op); } #ifdef SK_DEBUG @@ -1409,7 +1612,7 @@ void SkCanvas::validateClip() const { // construct clipRgn from the clipstack const SkBaseDevice* device = this->getDevice(); if (!device) { - SkASSERT(this->getTotalClip().isEmpty()); + SkASSERT(this->isClipEmpty()); return; } @@ -1421,13 +1624,6 @@ void SkCanvas::validateClip() const { const SkClipStack::Element* element; while ((element = iter.next()) != NULL) { switch (element->getType()) { - case SkClipStack::Element::kPath_Type: - clipPathHelper(this, - &tmpClip, - element->getPath(), - element->getOp(), - element->isAA()); - break; case SkClipStack::Element::kRect_Type: element->getRect().round(&ir); tmpClip.op(ir, element->getOp()); @@ -1435,14 +1631,14 @@ void SkCanvas::validateClip() const { case SkClipStack::Element::kEmpty_Type: tmpClip.setEmpty(); break; + default: { + SkPath path; + element->asPath(&path); + clip_path_helper(this, &tmpClip, path, element->getOp(), element->isAA()); + break; + } } } - -#if 0 // enable this locally for testing - // now compare against the current rgn - const SkRegion& rgn = this->getTotalClip(); - SkASSERT(rgn == tmpClip); -#endif } #endif @@ -1456,6 +1652,9 @@ void SkCanvas::replayClips(ClipVisitor* visitor) const { case SkClipStack::Element::kPath_Type: visitor->clipPath(element->getPath(), element->getOp(), element->isAA()); break; + case SkClipStack::Element::kRRect_Type: + visitor->clipRRect(element->getRRect(), element->getOp(), element->isAA()); + break; case SkClipStack::Element::kRect_Type: visitor->clipRect(element->getRect(), element->getOp(), element->isAA()); break; @@ -1468,6 +1667,14 @@ void SkCanvas::replayClips(ClipVisitor* visitor) const { /////////////////////////////////////////////////////////////////////////////// +bool SkCanvas::isClipEmpty() const { + return fMCRec->fRasterClip->isEmpty(); +} + +bool SkCanvas::isClipRect() const { + return fMCRec->fRasterClip->isRect(); +} + bool SkCanvas::quickReject(const SkRect& rect) const { if (!rect.isFinite()) @@ -1504,7 +1711,7 @@ bool SkCanvas::quickReject(const SkPath& path) const { bool SkCanvas::getClipBounds(SkRect* bounds) const { SkIRect ibounds; - if (!getClipDeviceBounds(&ibounds)) { + if (!this->getClipDeviceBounds(&ibounds)) { return false; } @@ -1548,26 +1755,46 @@ const SkMatrix& SkCanvas::getTotalMatrix() const { return *fMCRec->fMatrix; } +#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE SkCanvas::ClipType SkCanvas::getClipType() const { - if (fMCRec->fRasterClip->isEmpty()) return kEmpty_ClipType; - if (fMCRec->fRasterClip->isRect()) return kRect_ClipType; + if (fMCRec->fRasterClip->isEmpty()) { + return kEmpty_ClipType; + } + if (fMCRec->fRasterClip->isRect()) { + return kRect_ClipType; + } return kComplex_ClipType; } +#endif +#ifdef SK_SUPPORT_LEGACY_GETTOTALCLIP const SkRegion& SkCanvas::getTotalClip() const { return fMCRec->fRasterClip->forceGetBW(); } +#endif -SkBaseDevice* SkCanvas::createLayerDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque) { - SkBaseDevice* device = this->getTopDevice(); - if (device) { - return device->createCompatibleDeviceForSaveLayer(config, width, height, - isOpaque); - } else { - return NULL; +const SkRegion& SkCanvas::internal_private_getTotalClip() const { + return fMCRec->fRasterClip->forceGetBW(); +} + +void SkCanvas::internal_private_getTotalClipAsPath(SkPath* path) const { + path->reset(); + + const SkRegion& rgn = fMCRec->fRasterClip->forceGetBW(); + if (rgn.isEmpty()) { + return; } + (void)rgn.getBoundaryPath(path); +} + +GrRenderTarget* SkCanvas::internal_private_accessTopLayerRenderTarget() { + SkBaseDevice* dev = this->getTopDevice(); + return dev ? dev->accessRenderTarget() : NULL; +} + +SkBaseDevice* SkCanvas::createLayerDevice(const SkImageInfo& info) { + SkBaseDevice* device = this->getTopDevice(); + return device ? device->createCompatibleDeviceForSaveLayer(info) : NULL; } GrContext* SkCanvas::getGrContext() { @@ -1585,6 +1812,26 @@ GrContext* SkCanvas::getGrContext() { } +void SkCanvas::drawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + if (outer.isEmpty()) { + return; + } + if (inner.isEmpty()) { + this->drawRRect(outer, paint); + return; + } + + // We don't have this method (yet), but technically this is what we should + // be able to assert... + // SkASSERT(outer.contains(inner)); + // + // For now at least check for containment of bounds + SkASSERT(outer.getBounds().contains(inner.getBounds())); + + this->onDrawDRRect(outer, inner, paint); +} + ////////////////////////////////////////////////////////////////////////////// // These are the virtual drawing methods ////////////////////////////////////////////////////////////////////////////// @@ -1720,6 +1967,27 @@ void SkCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { LOOPER_END } +void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + CHECK_SHADER_NOSETCONTEXT(paint); + + SkRect storage; + const SkRect* bounds = NULL; + if (paint.canComputeFastBounds()) { + bounds = &paint.computeFastBounds(outer.getBounds(), &storage); + if (this->quickReject(*bounds)) { + return; + } + } + + LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, bounds) + + while (iter.next()) { + iter.fDevice->drawDRRect(iter, outer, inner, looper.paint()); + } + + LOOPER_END +} void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { CHECK_SHADER_NOSETCONTEXT(paint); @@ -1737,7 +2005,9 @@ void SkCanvas::drawPath(const SkPath& path, const SkPaint& paint) { return; } } - if (path.isEmpty()) { + + const SkRect& r = path.getBounds(); + if (r.width() <= 0 && r.height() <= 0) { if (path.isInverseFillType()) { this->internalDrawPaint(paint); } @@ -2191,8 +2461,23 @@ void SkCanvas::drawTextOnPathHV(const void* text, size_t byteLength, } /////////////////////////////////////////////////////////////////////////////// +void SkCanvas::EXPERIMENTAL_optimize(SkPicture* picture) { + SkBaseDevice* device = this->getDevice(); + if (NULL != device) { + device->EXPERIMENTAL_optimize(picture); + } +} void SkCanvas::drawPicture(SkPicture& picture) { + SkBaseDevice* device = this->getTopDevice(); + if (NULL != device) { + // Canvas has to first give the device the opportunity to render + // the picture itself. + if (device->EXPERIMENTAL_drawPicture(picture)) { + return; // the device has rendered the entire picture + } + } + picture.draw(this); } @@ -2239,3 +2524,60 @@ int SkCanvas::LayerIter::y() const { return fImpl->getY(); } /////////////////////////////////////////////////////////////////////////////// SkCanvas::ClipVisitor::~ClipVisitor() { } + +/////////////////////////////////////////////////////////////////////////////// + +static bool supported_for_raster_canvas(const SkImageInfo& info) { + switch (info.alphaType()) { + case kPremul_SkAlphaType: + case kOpaque_SkAlphaType: + break; + default: + return false; + } + + switch (info.colorType()) { + case kAlpha_8_SkColorType: + case kRGB_565_SkColorType: + case kPMColor_SkColorType: + break; + default: + return false; + } + + return true; +} + +SkCanvas* SkCanvas::NewRaster(const SkImageInfo& info) { + if (!supported_for_raster_canvas(info)) { + return NULL; + } + + SkBitmap bitmap; + if (!bitmap.allocPixels(info)) { + return NULL; + } + + // should this functionality be moved into allocPixels()? + if (!bitmap.info().isOpaque()) { + bitmap.eraseColor(0); + } + return SkNEW_ARGS(SkCanvas, (bitmap)); +} + +SkCanvas* SkCanvas::NewRasterDirect(const SkImageInfo& info, void* pixels, size_t rowBytes) { + if (!supported_for_raster_canvas(info)) { + return NULL; + } + + SkBitmap bitmap; + if (!bitmap.installPixels(info, pixels, rowBytes)) { + return NULL; + } + + // should this functionality be moved into allocPixels()? + if (!bitmap.info().isOpaque()) { + bitmap.eraseColor(0); + } + return SkNEW_ARGS(SkCanvas, (bitmap)); +} diff --git a/gfx/skia/trunk/src/core/SkClipStack.cpp b/gfx/skia/trunk/src/core/SkClipStack.cpp index c66a219b629b..b60a6c961d24 100644 --- a/gfx/skia/trunk/src/core/SkClipStack.cpp +++ b/gfx/skia/trunk/src/core/SkClipStack.cpp @@ -16,27 +16,135 @@ static const int32_t kFirstUnreservedGenID = 3; int32_t SkClipStack::gGenID = kFirstUnreservedGenID; +SkClipStack::Element::Element(const Element& that) { + switch (that.getType()) { + case kEmpty_Type: + fPath.reset(); + break; + case kRect_Type: // Rect uses rrect + case kRRect_Type: + fPath.reset(); + fRRect = that.fRRect; + break; + case kPath_Type: + fPath.set(that.getPath()); + break; + } + + fSaveCount = that.fSaveCount; + fOp = that.fOp; + fType = that.fType; + fDoAA = that.fDoAA; + fFiniteBoundType = that.fFiniteBoundType; + fFiniteBound = that.fFiniteBound; + fIsIntersectionOfRects = that.fIsIntersectionOfRects; + fGenID = that.fGenID; +} + +bool SkClipStack::Element::operator== (const Element& element) const { + if (this == &element) { + return true; + } + if (fOp != element.fOp || + fType != element.fType || + fDoAA != element.fDoAA || + fSaveCount != element.fSaveCount) { + return false; + } + switch (fType) { + case kPath_Type: + return this->getPath() == element.getPath(); + case kRRect_Type: + return fRRect == element.fRRect; + case kRect_Type: + return this->getRect() == element.getRect(); + case kEmpty_Type: + return true; + default: + SkDEBUGFAIL("Unexpected type."); + return false; + } +} + void SkClipStack::Element::invertShapeFillType() { switch (fType) { case kRect_Type: - fPath.reset(); - fPath.addRect(fRect); - fPath.setFillType(SkPath::kInverseWinding_FillType); + fPath.init(); + fPath.get()->addRect(this->getRect()); + fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); + fType = kPath_Type; + break; + case kRRect_Type: + fPath.init(); + fPath.get()->addRRect(fRRect); + fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); fType = kPath_Type; break; case kPath_Type: - fPath.toggleInverseFillType(); + fPath.get()->toggleInverseFillType(); + break; case kEmpty_Type: + // Should this set to an empty, inverse filled path? break; } } +void SkClipStack::Element::initPath(int saveCount, const SkPath& path, SkRegion::Op op, + bool doAA) { + if (!path.isInverseFillType()) { + if (SkPath::kNone_PathAsRect != path.asRect()) { + this->initRect(saveCount, path.getBounds(), op, doAA); + return; + } + SkRect ovalRect; + if (path.isOval(&ovalRect)) { + SkRRect rrect; + rrect.setOval(ovalRect); + this->initRRect(saveCount, rrect, op, doAA); + return; + } + } + fPath.set(path); + fType = kPath_Type; + this->initCommon(saveCount, op, doAA); +} + +void SkClipStack::Element::asPath(SkPath* path) const { + switch (fType) { + case kEmpty_Type: + path->reset(); + break; + case kRect_Type: + path->reset(); + path->addRect(this->getRect()); + break; + case kRRect_Type: + path->reset(); + path->addRRect(fRRect); + break; + case kPath_Type: + *path = *fPath.get(); + break; + } +} + +void SkClipStack::Element::setEmpty() { + fType = kEmpty_Type; + fFiniteBound.setEmpty(); + fFiniteBoundType = kNormal_BoundsType; + fIsIntersectionOfRects = false; + fRRect.setEmpty(); + fPath.reset(); + fGenID = kEmptyGenID; + SkDEBUGCODE(this->checkEmpty();) +} + void SkClipStack::Element::checkEmpty() const { SkASSERT(fFiniteBound.isEmpty()); SkASSERT(kNormal_BoundsType == fFiniteBoundType); SkASSERT(!fIsIntersectionOfRects); SkASSERT(kEmptyGenID == fGenID); - SkASSERT(fPath.isEmpty()); + SkASSERT(!fPath.isValid()); } bool SkClipStack::Element::canBeIntersectedInPlace(int saveCount, SkRegion::Op op) const { @@ -59,12 +167,12 @@ bool SkClipStack::Element::rectRectIntersectAllowed(const SkRect& newR, bool new return true; } - if (!SkRect::Intersects(fRect, newR)) { + if (!SkRect::Intersects(this->getRect(), newR)) { // The calling code will correctly set the result to the empty clip return true; } - if (fRect.contains(newR)) { + if (this->getRect().contains(newR)) { // if the new rect carves out a portion of the old one there is no // issue return true; @@ -100,10 +208,10 @@ void SkClipStack::Element::combineBoundsDiff(FillCombo combination, const SkRect // is erased, so the only pixels that can remain set // occur w/in the intersection of the two finite bounds if (!fFiniteBound.intersect(prevFinite)) { - fFiniteBound.setEmpty(); - fGenID = kEmptyGenID; + this->setEmpty(); + } else { + fFiniteBoundType = kNormal_BoundsType; } - fFiniteBoundType = kNormal_BoundsType; break; case kPrev_Cur_FillCombo: // The most conservative result bound is that of the @@ -205,8 +313,7 @@ void SkClipStack::Element::combineBoundsIntersection(int combination, const SkRe break; case kPrev_Cur_FillCombo: if (!fFiniteBound.intersect(prevFinite)) { - fFiniteBound.setEmpty(); - fGenID = kEmptyGenID; + this->setEmpty(); } break; default: @@ -228,10 +335,10 @@ void SkClipStack::Element::combineBoundsRevDiff(int combination, const SkRect& p break; case kInvPrev_Cur_FillCombo: if (!fFiniteBound.intersect(prevFinite)) { - fFiniteBound.setEmpty(); - fGenID = kEmptyGenID; + this->setEmpty(); + } else { + fFiniteBoundType = kNormal_BoundsType; } - fFiniteBoundType = kNormal_BoundsType; break; case kPrev_InvCur_FillCombo: fFiniteBound.join(prevFinite); @@ -258,27 +365,34 @@ void SkClipStack::Element::updateBoundAndGenID(const Element* prior) { // First, optimistically update the current Element's bound information // with the current clip's bound fIsIntersectionOfRects = false; - if (kRect_Type == fType) { - fFiniteBound = fRect; - fFiniteBoundType = kNormal_BoundsType; - - if (SkRegion::kReplace_Op == fOp || - (SkRegion::kIntersect_Op == fOp && NULL == prior) || - (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects && - prior->rectRectIntersectAllowed(fRect, fDoAA))) { - fIsIntersectionOfRects = true; - } - - } else { - SkASSERT(kPath_Type == fType); - - fFiniteBound = fPath.getBounds(); - - if (fPath.isInverseFillType()) { - fFiniteBoundType = kInsideOut_BoundsType; - } else { + switch (fType) { + case kRect_Type: + fFiniteBound = this->getRect(); fFiniteBoundType = kNormal_BoundsType; - } + + if (SkRegion::kReplace_Op == fOp || + (SkRegion::kIntersect_Op == fOp && NULL == prior) || + (SkRegion::kIntersect_Op == fOp && prior->fIsIntersectionOfRects && + prior->rectRectIntersectAllowed(this->getRect(), fDoAA))) { + fIsIntersectionOfRects = true; + } + break; + case kRRect_Type: + fFiniteBound = fRRect.getBounds(); + fFiniteBoundType = kNormal_BoundsType; + break; + case kPath_Type: + fFiniteBound = fPath.get()->getBounds(); + + if (fPath.get()->isInverseFillType()) { + fFiniteBoundType = kInsideOut_BoundsType; + } else { + fFiniteBoundType = kNormal_BoundsType; + } + break; + case kEmpty_Type: + SkDEBUGFAIL("We shouldn't get here with an empty element."); + break; } if (!fDoAA) { @@ -344,7 +458,7 @@ void SkClipStack::Element::updateBoundAndGenID(const Element* prior) { // so nothing to do break; default: - SkDebugf("SkRegion::Op error/n"); + SkDebugf("SkRegion::Op error\n"); SkASSERT(0); break; } @@ -528,97 +642,71 @@ bool SkClipStack::quickContains(const SkRect& rect) const { return true; } -void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { - +void SkClipStack::pushElement(const Element& element) { // Use reverse iterator instead of back because Rect path may need previous SkDeque::Iter iter(fDeque, SkDeque::Iter::kBack_IterStart); - Element* element = (Element*) iter.prev(); + Element* prior = (Element*) iter.prev(); - if (NULL != element) { - if (element->canBeIntersectedInPlace(fSaveCount, op)) { - switch (element->fType) { + if (NULL != prior) { + if (prior->canBeIntersectedInPlace(fSaveCount, element.getOp())) { + switch (prior->fType) { case Element::kEmpty_Type: - element->checkEmpty(); + SkDEBUGCODE(prior->checkEmpty();) return; case Element::kRect_Type: - if (element->rectRectIntersectAllowed(rect, doAA)) { - if (!element->fRect.intersect(rect)) { - element->setEmpty(); + if (Element::kRect_Type == element.getType()) { + if (prior->rectRectIntersectAllowed(element.getRect(), element.isAA())) { + SkRect isectRect; + if (!isectRect.intersect(prior->getRect(), element.getRect())) { + prior->setEmpty(); + return; + } + + prior->fRRect.setRect(isectRect); + prior->fDoAA = element.isAA(); + Element* priorPrior = (Element*) iter.prev(); + prior->updateBoundAndGenID(priorPrior); return; } - - element->fDoAA = doAA; - Element* prev = (Element*) iter.prev(); - element->updateBoundAndGenID(prev); - return; + break; } - break; - case Element::kPath_Type: - if (!SkRect::Intersects(element->fPath.getBounds(), rect)) { - element->setEmpty(); + // fallthrough + default: + if (!SkRect::Intersects(prior->getBounds(), element.getBounds())) { + prior->setEmpty(); return; } break; } - } else if (SkRegion::kReplace_Op == op) { + } else if (SkRegion::kReplace_Op == element.getOp()) { this->restoreTo(fSaveCount - 1); - element = (Element*) fDeque.back(); + prior = (Element*) fDeque.back(); } } - new (fDeque.push_back()) Element(fSaveCount, rect, op, doAA); - ((Element*) fDeque.back())->updateBoundAndGenID(element); + Element* newElement = SkNEW_PLACEMENT_ARGS(fDeque.push_back(), Element, (element)); + newElement->updateBoundAndGenID(prior); +} + +void SkClipStack::clipDevRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { + Element element(fSaveCount, rrect, op, doAA); + this->pushElement(element); +} + +void SkClipStack::clipDevRect(const SkRect& rect, SkRegion::Op op, bool doAA) { + Element element(fSaveCount, rect, op, doAA); + this->pushElement(element); } void SkClipStack::clipDevPath(const SkPath& path, SkRegion::Op op, bool doAA) { - SkRect alt; - if (path.isRect(&alt) && !path.isInverseFillType()) { - return this->clipDevRect(alt, op, doAA); - } - - Element* element = (Element*)fDeque.back(); - if (NULL != element) { - if (element->canBeIntersectedInPlace(fSaveCount, op)) { - const SkRect& pathBounds = path.getBounds(); - switch (element->fType) { - case Element::kEmpty_Type: - element->checkEmpty(); - return; - case Element::kRect_Type: - if (!SkRect::Intersects(element->fRect, pathBounds)) { - element->setEmpty(); - return; - } - break; - case Element::kPath_Type: - if (!SkRect::Intersects(element->fPath.getBounds(), pathBounds)) { - element->setEmpty(); - return; - } - break; - } - } else if (SkRegion::kReplace_Op == op) { - this->restoreTo(fSaveCount - 1); - element = (Element*) fDeque.back(); - } - } - new (fDeque.push_back()) Element(fSaveCount, path, op, doAA); - ((Element*) fDeque.back())->updateBoundAndGenID(element); + Element element(fSaveCount, path, op, doAA); + this->pushElement(element); } void SkClipStack::clipEmpty() { - Element* element = (Element*) fDeque.back(); if (element && element->canBeIntersectedInPlace(fSaveCount, SkRegion::kIntersect_Op)) { - switch (element->fType) { - case Element::kEmpty_Type: - element->checkEmpty(); - return; - case Element::kRect_Type: - case Element::kPath_Type: - element->setEmpty(); - return; - } + element->setEmpty(); } new (fDeque.push_back()) Element(fSaveCount); diff --git a/gfx/skia/trunk/src/core/SkComposeShader.cpp b/gfx/skia/trunk/src/core/SkComposeShader.cpp index b5ea63c24c5e..f53eedf8764d 100644 --- a/gfx/skia/trunk/src/core/SkComposeShader.cpp +++ b/gfx/skia/trunk/src/core/SkComposeShader.cpp @@ -176,7 +176,7 @@ void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) { } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkComposeShader::toString(SkString* str) const { str->append("SkComposeShader: ("); diff --git a/gfx/skia/trunk/src/core/SkConfig8888.h b/gfx/skia/trunk/src/core/SkConfig8888.h index 96eaef2447f5..041773e6df43 100644 --- a/gfx/skia/trunk/src/core/SkConfig8888.h +++ b/gfx/skia/trunk/src/core/SkConfig8888.h @@ -1,4 +1,3 @@ - /* * Copyright 2011 Google Inc. * @@ -6,6 +5,8 @@ * found in the LICENSE file. */ +#ifndef SkConfig8888_DEFINED +#define SkConfig8888_DEFINED #include "SkCanvas.h" #include "SkColorPriv.h" @@ -74,3 +75,5 @@ static inline void SkCopyConfig8888ToBitmap(const SkBitmap& dstBmp, } } + +#endif diff --git a/gfx/skia/trunk/src/core/SkCordic.cpp b/gfx/skia/trunk/src/core/SkCordic.cpp deleted file mode 100644 index 3adc92faa108..000000000000 --- a/gfx/skia/trunk/src/core/SkCordic.cpp +++ /dev/null @@ -1,289 +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. - */ - -#include "SkCordic.h" -#include "SkMathPriv.h" -#include "Sk64.h" - -// 0x20000000 equals pi / 4 -const int32_t kATanDegrees[] = { 0x20000000, - 0x12E4051D, 0x9FB385B, 0x51111D4, 0x28B0D43, 0x145D7E1, 0xA2F61E, 0x517C55, - 0x28BE53, 0x145F2E, 0xA2F98, 0x517CC, 0x28BE6, 0x145F3, 0xA2F9, 0x517C, - 0x28BE, 0x145F, 0xA2F, 0x517, 0x28B, 0x145, 0xA2, 0x51, 0x28, 0x14, - 0xA, 0x5, 0x2, 0x1 }; - -const int32_t kFixedInvGain1 = 0x18bde0bb; // 0.607252935 - -static void SkCircularRotation(int32_t* x0, int32_t* y0, int32_t* z0) -{ - int32_t t = 0; - int32_t x = *x0; - int32_t y = *y0; - int32_t z = *z0; - const int32_t* tanPtr = kATanDegrees; - do { - int32_t x1 = y >> t; - int32_t y1 = x >> t; - int32_t tan = *tanPtr++; - if (z >= 0) { - x -= x1; - y += y1; - z -= tan; - } else { - x += x1; - y -= y1; - z += tan; - } - } while (++t < 16); // 30); - *x0 = x; - *y0 = y; - *z0 = z; -} - -SkFixed SkCordicSinCos(SkFixed radians, SkFixed* cosp) -{ - int32_t scaledRadians = radians * 0x28be; // scale radians to 65536 / PI() - int quadrant = scaledRadians >> 30; - quadrant += 1; - if (quadrant & 2) - scaledRadians = -scaledRadians + 0x80000000; - /* |a| <= 90 degrees as a 1.31 number */ - SkFixed sin = 0; - SkFixed cos = kFixedInvGain1; - SkCircularRotation(&cos, &sin, &scaledRadians); - Sk64 scaled; - scaled.setMul(sin, 0x6488d); - sin = scaled.fHi; - scaled.setMul(cos, 0x6488d); - if (quadrant & 2) - scaled.fHi = - scaled.fHi; - *cosp = scaled.fHi; - return sin; -} - -SkFixed SkCordicTan(SkFixed a) -{ - int32_t cos; - int32_t sin = SkCordicSinCos(a, &cos); - return SkFixedDiv(sin, cos); -} - -static int32_t SkCircularVector(int32_t* y0, int32_t* x0, int32_t vecMode) -{ - int32_t x = *x0; - int32_t y = *y0; - int32_t z = 0; - int32_t t = 0; - const int32_t* tanPtr = kATanDegrees; - do { - int32_t x1 = y >> t; - int32_t y1 = x >> t; - int32_t tan = *tanPtr++; - if (y < vecMode) { - x -= x1; - y += y1; - z -= tan; - } else { - x += x1; - y -= y1; - z += tan; - } - } while (++t < 16); // 30 - Sk64 scaled; - scaled.setMul(z, 0x6488d); // scale back into the SkScalar space (0x100000000/0x28be) - return scaled.fHi; -} - -SkFixed SkCordicASin(SkFixed a) { - int32_t sign = SkExtractSign(a); - int32_t z = SkFixedAbs(a); - if (z >= SK_Fixed1) - return SkApplySign(SK_FixedPI>>1, sign); - int32_t x = kFixedInvGain1; - int32_t y = 0; - z *= 0x28be; - z = SkCircularVector(&y, &x, z); - z = SkApplySign(z, ~sign); - return z; -} - -SkFixed SkCordicACos(SkFixed a) { - int32_t z = SkCordicASin(a); - z = (SK_FixedPI>>1) - z; - return z; -} - -SkFixed SkCordicATan2(SkFixed y, SkFixed x) { - if ((x | y) == 0) - return 0; - int32_t xsign = SkExtractSign(x); - x = SkFixedAbs(x); - int32_t result = SkCircularVector(&y, &x, 0); - if (xsign) { - int32_t rsign = SkExtractSign(result); - if (y == 0) - rsign = 0; - SkFixed pi = SkApplySign(SK_FixedPI, rsign); - result = pi - result; - } - return result; -} - -const int32_t kATanHDegrees[] = { - 0x1661788D, 0xA680D61, 0x51EA6FC, 0x28CBFDD, 0x1460E34, - 0xA2FCE8, 0x517D2E, 0x28BE6E, 0x145F32, - 0xA2F98, 0x517CC, 0x28BE6, 0x145F3, 0xA2F9, 0x517C, - 0x28BE, 0x145F, 0xA2F, 0x517, 0x28B, 0x145, 0xA2, 0x51, 0x28, 0x14, - 0xA, 0x5, 0x2, 0x1 }; - -const int32_t kFixedInvGain2 = 0x31330AAA; // 1.207534495 - -static void SkHyperbolic(int32_t* x0, int32_t* y0, int32_t* z0, int mode) -{ - int32_t t = 1; - int32_t x = *x0; - int32_t y = *y0; - int32_t z = *z0; - const int32_t* tanPtr = kATanHDegrees; - int k = -3; - do { - int32_t x1 = y >> t; - int32_t y1 = x >> t; - int32_t tan = *tanPtr++; - int count = 2 + (k >> 31); - if (++k == 1) - k = -2; - do { - if (((y >> 31) & mode) | ~((z >> 31) | mode)) { - x += x1; - y += y1; - z -= tan; - } else { - x -= x1; - y -= y1; - z += tan; - } - } while (--count); - } while (++t < 30); - *x0 = x; - *y0 = y; - *z0 = z; -} - -SkFixed SkCordicLog(SkFixed a) { - a *= 0x28be; - int32_t x = a + 0x28BE60DB; // 1.0 - int32_t y = a - 0x28BE60DB; - int32_t z = 0; - SkHyperbolic(&x, &y, &z, -1); - Sk64 scaled; - scaled.setMul(z, 0x6488d); - z = scaled.fHi; - return z << 1; -} - -SkFixed SkCordicExp(SkFixed a) { - int32_t cosh = kFixedInvGain2; - int32_t sinh = 0; - SkHyperbolic(&cosh, &sinh, &a, 0); - return cosh + sinh; -} - -#ifdef SK_DEBUG - -#include "SkFloatingPoint.h" - -void SkCordic_UnitTest() -{ -#if defined(SK_SUPPORT_UNITTEST) - float val; - for (float angle = -720; angle < 720; angle += 30) { - float radian = angle * 3.1415925358f / 180.0f; - SkFixed f_angle = SkFloatToFixed(radian); - // sincos - float sine = sinf(radian); - float cosine = cosf(radian); - SkFixed f_cosine; - SkFixed f_sine = SkCordicSinCos(f_angle, &f_cosine); - float sine2 = (float) f_sine / 65536.0f; - float cosine2 = (float) f_cosine / 65536.0f; - float error = fabsf(sine - sine2); - if (error > 0.001) - SkDebugf("sin error : angle = %g ; sin = %g ; cordic = %g\n", angle, sine, sine2); - error = fabsf(cosine - cosine2); - if (error > 0.001) - SkDebugf("cos error : angle = %g ; cos = %g ; cordic = %g\n", angle, cosine, cosine2); - // tan - float _tan = tanf(radian); - SkFixed f_tan = SkCordicTan(f_angle); - float tan2 = (float) f_tan / 65536.0f; - error = fabsf(_tan - tan2); - if (error > 0.05 && fabsf(_tan) < 1e6) - SkDebugf("tan error : angle = %g ; tan = %g ; cordic = %g\n", angle, _tan, tan2); - } - for (val = -1; val <= 1; val += .1f) { - SkFixed f_val = SkFloatToFixed(val); - // asin - float arcsine = asinf(val); - SkFixed f_arcsine = SkCordicASin(f_val); - float arcsine2 = (float) f_arcsine / 65536.0f; - float error = fabsf(arcsine - arcsine2); - if (error > 0.001) - SkDebugf("asin error : val = %g ; asin = %g ; cordic = %g\n", val, arcsine, arcsine2); - } -#if 1 - for (val = -1; val <= 1; val += .1f) { -#else - val = .5; { -#endif - SkFixed f_val = SkFloatToFixed(val); - // acos - float arccos = acosf(val); - SkFixed f_arccos = SkCordicACos(f_val); - float arccos2 = (float) f_arccos / 65536.0f; - float error = fabsf(arccos - arccos2); - if (error > 0.001) - SkDebugf("acos error : val = %g ; acos = %g ; cordic = %g\n", val, arccos, arccos2); - } - // atan2 -#if 1 - for (val = -1000; val <= 1000; val += 500.f) { - for (float val2 = -1000; val2 <= 1000; val2 += 500.f) { -#else - val = 0; { - float val2 = -1000; { -#endif - SkFixed f_val = SkFloatToFixed(val); - SkFixed f_val2 = SkFloatToFixed(val2); - float arctan = atan2f(val, val2); - SkFixed f_arctan = SkCordicATan2(f_val, f_val2); - float arctan2 = (float) f_arctan / 65536.0f; - float error = fabsf(arctan - arctan2); - if (error > 0.001) - SkDebugf("atan2 error : val = %g ; val2 = %g ; atan2 = %g ; cordic = %g\n", val, val2, arctan, arctan2); - } - } - // log -#if 1 - for (val = 0.125f; val <= 8.f; val *= 2.0f) { -#else - val = .5; { -#endif - SkFixed f_val = SkFloatToFixed(val); - // acos - float log = logf(val); - SkFixed f_log = SkCordicLog(f_val); - float log2 = (float) f_log / 65536.0f; - float error = fabsf(log - log2); - if (error > 0.001) - SkDebugf("log error : val = %g ; log = %g ; cordic = %g\n", val, log, log2); - } - // exp -#endif -} - -#endif diff --git a/gfx/skia/trunk/src/core/SkCordic.h b/gfx/skia/trunk/src/core/SkCordic.h deleted file mode 100644 index fecf6456430f..000000000000 --- a/gfx/skia/trunk/src/core/SkCordic.h +++ /dev/null @@ -1,28 +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 SkCordic_DEFINED -#define SkCordic_DEFINED - -#include "SkTypes.h" -#include "SkFixed.h" - -SkFixed SkCordicACos(SkFixed a); -SkFixed SkCordicASin(SkFixed a); -SkFixed SkCordicATan2(SkFixed y, SkFixed x); -SkFixed SkCordicExp(SkFixed a); -SkFixed SkCordicLog(SkFixed a); -SkFixed SkCordicSinCos(SkFixed radians, SkFixed* cosp); -SkFixed SkCordicTan(SkFixed a); - -#ifdef SK_DEBUG - void SkCordic_UnitTest(); -#endif - -#endif // SkCordic diff --git a/gfx/skia/trunk/src/core/SkCoreBlitters.h b/gfx/skia/trunk/src/core/SkCoreBlitters.h index 1605a5273dcd..285184050ba8 100644 --- a/gfx/skia/trunk/src/core/SkCoreBlitters.h +++ b/gfx/skia/trunk/src/core/SkCoreBlitters.h @@ -8,8 +8,11 @@ #ifndef SkCoreBlitters_DEFINED #define SkCoreBlitters_DEFINED +#include "SkBitmapProcShader.h" #include "SkBlitter.h" #include "SkBlitRow.h" +#include "SkShader.h" +#include "SkSmallAllocator.h" class SkRasterBlitter : public SkBlitter { public: @@ -175,8 +178,7 @@ private: SkBlitter::Choose(...) */ -extern SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, - const SkPaint& paint, - void* storage, size_t storageSize); +SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint, + SkTBlitterAllocator* allocator); #endif diff --git a/gfx/skia/trunk/src/core/SkDebug.cpp b/gfx/skia/trunk/src/core/SkDebug.cpp index d484f5eaffe2..b705a650ea2c 100644 --- a/gfx/skia/trunk/src/core/SkDebug.cpp +++ b/gfx/skia/trunk/src/core/SkDebug.cpp @@ -51,4 +51,9 @@ unsigned SkToUInt(uintmax_t x) { return (unsigned)x; } +size_t SkToSizeT(uintmax_t x) { + SkASSERT((size_t)x == x); + return (size_t)x; +} + #endif diff --git a/gfx/skia/trunk/src/core/SkDevice.cpp b/gfx/skia/trunk/src/core/SkDevice.cpp index 9ce8b6b5df2e..3cfe89cfeca9 100644 --- a/gfx/skia/trunk/src/core/SkDevice.cpp +++ b/gfx/skia/trunk/src/core/SkDevice.cpp @@ -42,19 +42,53 @@ SkBaseDevice::~SkBaseDevice() { delete fMetaData; } +SkBaseDevice* SkBaseDevice::createCompatibleDevice(const SkImageInfo& info) { +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG + // We call the old method to support older subclasses. + // If they have, we return their device, else we use the new impl. + SkBitmap::Config config = SkColorTypeToBitmapConfig(info.colorType()); + SkBaseDevice* dev = this->onCreateCompatibleDevice(config, + info.width(), + info.height(), + info.isOpaque(), + kGeneral_Usage); + if (dev) { + return dev; + } + // fall through to new impl +#endif + return this->onCreateDevice(info, kGeneral_Usage); +} + +SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(const SkImageInfo& info) { +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG + // We call the old method to support older subclasses. + // If they have, we return their device, else we use the new impl. + SkBitmap::Config config = SkColorTypeToBitmapConfig(info.colorType()); + SkBaseDevice* dev = this->onCreateCompatibleDevice(config, + info.width(), + info.height(), + info.isOpaque(), + kSaveLayer_Usage); + if (dev) { + return dev; + } + // fall through to new impl +#endif + return this->onCreateDevice(info, kSaveLayer_Usage); +} + +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG SkBaseDevice* SkBaseDevice::createCompatibleDevice(SkBitmap::Config config, int width, int height, bool isOpaque) { - return this->onCreateCompatibleDevice(config, width, height, - isOpaque, kGeneral_Usage); -} - -SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(SkBitmap::Config config, - int width, int height, - bool isOpaque) { - return this->onCreateCompatibleDevice(config, width, height, - isOpaque, kSaveLayer_Usage); + SkImageInfo info = SkImageInfo::Make(width, height, + SkBitmapConfigToColorType(config), + isOpaque ? kOpaque_SkAlphaType + : kPremul_SkAlphaType); + return this->createCompatibleDevice(info); } +#endif SkMetaData& SkBaseDevice::getMetaData() { // metadata users are rare, so we lazily allocate it. If that changes we @@ -65,6 +99,11 @@ SkMetaData& SkBaseDevice::getMetaData() { return *fMetaData; } +// TODO: should make this guy pure-virtual. +SkImageInfo SkBaseDevice::imageInfo() const { + return SkImageInfo::MakeUnknown(this->width(), this->height()); +} + const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) { const SkBitmap& bitmap = this->onAccessBitmap(); if (changePixels) { @@ -117,3 +156,69 @@ bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y, } SkSurface* SkBaseDevice::newSurface(const SkImageInfo&) { return NULL; } + +const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; } + +void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer, + const SkRRect& inner, const SkPaint& paint) { + SkPath path; + path.addRRect(outer); + path.addRRect(inner); + path.setFillType(SkPath::kEvenOdd_FillType); + + const SkMatrix* preMatrix = NULL; + const bool pathIsMutable = true; + this->drawPath(draw, path, paint, preMatrix, pathIsMutable); +} + +bool SkBaseDevice::writePixelsDirect(const SkImageInfo& info, const void* pixels, size_t rowBytes, + int x, int y) { +#ifdef SK_DEBUG + SkASSERT(info.width() > 0 && info.height() > 0); + SkASSERT(pixels); + SkASSERT(rowBytes >= info.minRowBytes()); + SkASSERT(x >= 0 && y >= 0); + + const SkImageInfo& dstInfo = this->imageInfo(); + SkASSERT(x + info.width() <= dstInfo.width()); + SkASSERT(y + info.height() <= dstInfo.height()); +#endif + return this->onWritePixels(info, pixels, rowBytes, x, y); +} + +bool SkBaseDevice::onWritePixels(const SkImageInfo&, const void*, size_t, int, int) { + return false; +} + +bool SkBaseDevice::onReadPixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) { + return false; +} + +void* SkBaseDevice::accessPixels(SkImageInfo* info, size_t* rowBytes) { + SkImageInfo tmpInfo; + size_t tmpRowBytes; + if (NULL == info) { + info = &tmpInfo; + } + if (NULL == rowBytes) { + rowBytes = &tmpRowBytes; + } + return this->onAccessPixels(info, rowBytes); +} + +void* SkBaseDevice::onAccessPixels(SkImageInfo* info, size_t* rowBytes) { + return NULL; +} + +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG +void SkBaseDevice::writePixels(const SkBitmap&, int x, int y, SkCanvas::Config8888) {} +#endif + +void SkBaseDevice::EXPERIMENTAL_optimize(SkPicture* picture) { + // The base class doesn't perform any analysis but derived classes may +} + +bool SkBaseDevice::EXPERIMENTAL_drawPicture(const SkPicture& picture) { + // The base class doesn't perform any accelerated picture rendering + return false; +} diff --git a/gfx/skia/trunk/src/core/SkDeviceImageFilterProxy.h b/gfx/skia/trunk/src/core/SkDeviceImageFilterProxy.h index 800e42c1f62d..5ee563484ee3 100644 --- a/gfx/skia/trunk/src/core/SkDeviceImageFilterProxy.h +++ b/gfx/skia/trunk/src/core/SkDeviceImageFilterProxy.h @@ -15,16 +15,15 @@ public: SkDeviceImageFilterProxy(SkBaseDevice* device) : fDevice(device) {} virtual SkBaseDevice* createDevice(int w, int h) SK_OVERRIDE { - return fDevice->createCompatibleDevice(SkBitmap::kARGB_8888_Config, - w, h, false); + return fDevice->createCompatibleDevice(SkImageInfo::MakeN32Premul(w, h)); } virtual bool canHandleImageFilter(const SkImageFilter* filter) SK_OVERRIDE { return fDevice->canHandleImageFilter(filter); } virtual bool filterImage(const SkImageFilter* filter, const SkBitmap& src, - const SkMatrix& ctm, + const SkImageFilter::Context& ctx, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { - return fDevice->filterImage(filter, src, ctm, result, offset); + return fDevice->filterImage(filter, src, ctx, result, offset); } private: diff --git a/gfx/skia/trunk/src/core/SkDistanceFieldGen.cpp b/gfx/skia/trunk/src/core/SkDistanceFieldGen.cpp new file mode 100755 index 000000000000..f453afe56f65 --- /dev/null +++ b/gfx/skia/trunk/src/core/SkDistanceFieldGen.cpp @@ -0,0 +1,451 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkDistanceFieldGen.h" +#include "SkPoint.h" + +struct DFData { + float fAlpha; // alpha value of source texel + float fDistSq; // distance squared to nearest (so far) edge texel + SkPoint fDistVector; // distance vector to nearest (so far) edge texel +}; + +enum NeighborFlags { + kLeft_NeighborFlag = 0x01, + kRight_NeighborFlag = 0x02, + kTopLeft_NeighborFlag = 0x04, + kTop_NeighborFlag = 0x08, + kTopRight_NeighborFlag = 0x10, + kBottomLeft_NeighborFlag = 0x20, + kBottom_NeighborFlag = 0x40, + kBottomRight_NeighborFlag = 0x80, + kAll_NeighborFlags = 0xff, + + kNeighborFlagCount = 8 +}; + +// We treat an "edge" as a place where we cross from black to non-black, or vice versa. +// 'neighborFlags' is used to limit the directions in which we test to avoid indexing +// outside of the image +static bool found_edge(const unsigned char* imagePtr, int width, int neighborFlags) { + // the order of these should match the neighbor flags above + const int kNum8ConnectedNeighbors = 8; + const int offsets[8] = {-1, 1, -width-1, -width, -width+1, width-1, width, width+1 }; + SkASSERT(kNum8ConnectedNeighbors == kNeighborFlagCount); + + // search for an edge + bool currVal = (*imagePtr != 0); + for (int i = 0; i < kNum8ConnectedNeighbors; ++i) { + bool checkVal; + if ((1 << i) & neighborFlags) { + const unsigned char* checkPtr = imagePtr + offsets[i]; + checkVal = (*checkPtr != 0); + } else { + checkVal = false; + } + SkASSERT(checkVal == 0 || checkVal == 1); + SkASSERT(currVal == 0 || currVal == 1); + if (checkVal != currVal) { + return true; + } + } + + return false; +} + +static void init_glyph_data(DFData* data, unsigned char* edges, const unsigned char* image, + int dataWidth, int dataHeight, + int imageWidth, int imageHeight, + int pad) { + data += pad*dataWidth; + data += pad; + edges += (pad*dataWidth + pad); + + for (int j = 0; j < imageHeight; ++j) { + for (int i = 0; i < imageWidth; ++i) { + if (255 == *image) { + data->fAlpha = 1.0f; + } else { + data->fAlpha = (*image)*0.00392156862f; // 1/255 + } + int checkMask = kAll_NeighborFlags; + if (i == 0) { + checkMask &= ~(kLeft_NeighborFlag|kTopLeft_NeighborFlag|kBottomLeft_NeighborFlag); + } + if (i == imageWidth-1) { + checkMask &= ~(kRight_NeighborFlag|kTopRight_NeighborFlag|kBottomRight_NeighborFlag); + } + if (j == 0) { + checkMask &= ~(kTopLeft_NeighborFlag|kTop_NeighborFlag|kTopRight_NeighborFlag); + } + if (j == imageHeight-1) { + checkMask &= ~(kBottomLeft_NeighborFlag|kBottom_NeighborFlag|kBottomRight_NeighborFlag); + } + if (found_edge(image, imageWidth, checkMask)) { + *edges = 255; // using 255 makes for convenient debug rendering + } + ++data; + ++image; + ++edges; + } + data += 2*pad; + edges += 2*pad; + } +} + +// from Gustavson (2011) +// computes the distance to an edge given an edge normal vector and a pixel's alpha value +// assumes that direction has been pre-normalized +static float edge_distance(const SkPoint& direction, float alpha) { + float dx = direction.fX; + float dy = direction.fY; + float distance; + if (SkScalarNearlyZero(dx) || SkScalarNearlyZero(dy)) { + distance = 0.5f - alpha; + } else { + // this is easier if we treat the direction as being in the first octant + // (other octants are symmetrical) + dx = SkScalarAbs(dx); + dy = SkScalarAbs(dy); + if (dx < dy) { + SkTSwap(dx, dy); + } + + // a1 = 0.5*dy/dx is the smaller fractional area chopped off by the edge + // to avoid the divide, we just consider the numerator + float a1num = 0.5f*dy; + + // we now compute the approximate distance, depending where the alpha falls + // relative to the edge fractional area + + // if 0 <= alpha < a1 + if (alpha*dx < a1num) { + // TODO: find a way to do this without square roots? + distance = 0.5f*(dx + dy) - SkScalarSqrt(2.0f*dx*dy*alpha); + // if a1 <= alpha <= 1 - a1 + } else if (alpha*dx < (dx - a1num)) { + distance = (0.5f - alpha)*dx; + // if 1 - a1 < alpha <= 1 + } else { + // TODO: find a way to do this without square roots? + distance = -0.5f*(dx + dy) + SkScalarSqrt(2.0f*dx*dy*(1.0f - alpha)); + } + } + + return distance; +} + +static void init_distances(DFData* data, unsigned char* edges, int width, int height) { + // skip one pixel border + DFData* currData = data; + DFData* prevData = data - width; + DFData* nextData = data + width; + + for (int j = 0; j < height; ++j) { + for (int i = 0; i < width; ++i) { + if (*edges) { + // we should not be in the one-pixel outside band + SkASSERT(i > 0 && i < width-1 && j > 0 && j < height-1); + // gradient will point from low to high + // +y is down in this case + // i.e., if you're outside, gradient points towards edge + // if you're inside, gradient points away from edge + SkPoint currGrad; + currGrad.fX = (prevData+1)->fAlpha - (prevData-1)->fAlpha + + SK_ScalarSqrt2*(currData+1)->fAlpha + - SK_ScalarSqrt2*(currData-1)->fAlpha + + (nextData+1)->fAlpha - (nextData-1)->fAlpha; + currGrad.fY = (nextData-1)->fAlpha - (prevData-1)->fAlpha + + SK_ScalarSqrt2*nextData->fAlpha + - SK_ScalarSqrt2*prevData->fAlpha + + (nextData+1)->fAlpha - (prevData+1)->fAlpha; + currGrad.setLengthFast(1.0f); + + // init squared distance to edge and distance vector + float dist = edge_distance(currGrad, currData->fAlpha); + currGrad.scale(dist, &currData->fDistVector); + currData->fDistSq = dist*dist; + } else { + // init distance to "far away" + currData->fDistSq = 2000000.f; + currData->fDistVector.fX = 1000.f; + currData->fDistVector.fY = 1000.f; + } + ++currData; + ++prevData; + ++nextData; + ++edges; + } + } +} + +// Danielsson's 8SSEDT + +// first stage forward pass +// (forward in Y, forward in X) +static void F1(DFData* curr, int width) { + // upper left + DFData* check = curr - width-1; + SkPoint distVec = check->fDistVector; + float distSq = check->fDistSq - 2.0f*(distVec.fX + distVec.fY - 1.0f); + if (distSq < curr->fDistSq) { + distVec.fX -= 1.0f; + distVec.fY -= 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } + + // up + check = curr - width; + distVec = check->fDistVector; + distSq = check->fDistSq - 2.0f*distVec.fY + 1.0f; + if (distSq < curr->fDistSq) { + distVec.fY -= 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } + + // upper right + check = curr - width+1; + distVec = check->fDistVector; + distSq = check->fDistSq + 2.0f*(distVec.fX - distVec.fY + 1.0f); + if (distSq < curr->fDistSq) { + distVec.fX += 1.0f; + distVec.fY -= 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } + + // left + check = curr - 1; + distVec = check->fDistVector; + distSq = check->fDistSq - 2.0f*distVec.fX + 1.0f; + if (distSq < curr->fDistSq) { + distVec.fX -= 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } +} + +// second stage forward pass +// (forward in Y, backward in X) +static void F2(DFData* curr, int width) { + // right + DFData* check = curr + 1; + float distSq = check->fDistSq; + SkPoint distVec = check->fDistVector; + distSq = check->fDistSq + 2.0f*distVec.fX + 1.0f; + if (distSq < curr->fDistSq) { + distVec.fX += 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } +} + +// first stage backward pass +// (backward in Y, forward in X) +static void B1(DFData* curr, int width) { + // left + DFData* check = curr - 1; + SkPoint distVec = check->fDistVector; + float distSq = check->fDistSq - 2.0f*distVec.fX + 1.0f; + if (distSq < curr->fDistSq) { + distVec.fX -= 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } +} + +// second stage backward pass +// (backward in Y, backwards in X) +static void B2(DFData* curr, int width) { + // right + DFData* check = curr + 1; + SkPoint distVec = check->fDistVector; + float distSq = check->fDistSq + 2.0f*distVec.fX + 1.0f; + if (distSq < curr->fDistSq) { + distVec.fX += 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } + + // bottom left + check = curr + width-1; + distVec = check->fDistVector; + distSq = check->fDistSq - 2.0f*(distVec.fX - distVec.fY - 1.0f); + if (distSq < curr->fDistSq) { + distVec.fX -= 1.0f; + distVec.fY += 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } + + // bottom + check = curr + width; + distVec = check->fDistVector; + distSq = check->fDistSq + 2.0f*distVec.fY + 1.0f; + if (distSq < curr->fDistSq) { + distVec.fY += 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } + + // bottom right + check = curr + width+1; + distVec = check->fDistVector; + distSq = check->fDistSq + 2.0f*(distVec.fX + distVec.fY + 1.0f); + if (distSq < curr->fDistSq) { + distVec.fX += 1.0f; + distVec.fY += 1.0f; + curr->fDistSq = distSq; + curr->fDistVector = distVec; + } +} + +// enable this to output edge data rather than the distance field +#define DUMP_EDGE 0 + +#if !DUMP_EDGE +static unsigned char pack_distance_field_val(float dist, float distanceMagnitude) { + if (dist <= -distanceMagnitude) { + return 255; + } else if (dist > distanceMagnitude) { + return 0; + } else { + return (unsigned char)((distanceMagnitude-dist)*128.0f/distanceMagnitude); + } +} +#endif + +// assumes an 8-bit image and distance field +bool SkGenerateDistanceFieldFromImage(unsigned char* distanceField, + const unsigned char* image, + int width, int height, + int distanceMagnitude) { + SkASSERT(NULL != distanceField); + SkASSERT(NULL != image); + + // the final distance field will have additional texels on each side to handle + // the maximum distance + // we expand our temp data by one more on each side to simplify + // the scanning code -- will always be treated as infinitely far away + int pad = distanceMagnitude+1; + + // set params for distance field data + int dataWidth = width + 2*pad; + int dataHeight = height + 2*pad; + + // create temp data + size_t dataSize = dataWidth*dataHeight*sizeof(DFData); + SkAutoSMalloc<1024> dfStorage(dataSize); + DFData* dataPtr = (DFData*) dfStorage.get(); + sk_bzero(dataPtr, dataSize); + + SkAutoSMalloc<1024> edgeStorage(dataWidth*dataHeight*sizeof(char)); + unsigned char* edgePtr = (unsigned char*) edgeStorage.get(); + sk_bzero(edgePtr, dataWidth*dataHeight*sizeof(char)); + + // copy glyph into distance field storage + init_glyph_data(dataPtr, edgePtr, image, + dataWidth, dataHeight, + width, height, pad); + + // create initial distance data, particularly at edges + init_distances(dataPtr, edgePtr, dataWidth, dataHeight); + + // now perform Euclidean distance transform to propagate distances + + // forwards in y + DFData* currData = dataPtr+dataWidth+1; // skip outer buffer + unsigned char* currEdge = edgePtr+dataWidth+1; + for (int j = 1; j < dataHeight-1; ++j) { + // forwards in x + for (int i = 1; i < dataWidth-1; ++i) { + // don't need to calculate distance for edge pixels + if (!*currEdge) { + F1(currData, dataWidth); + } + ++currData; + ++currEdge; + } + + // backwards in x + --currData; // reset to end + --currEdge; + for (int i = 1; i < dataWidth-1; ++i) { + // don't need to calculate distance for edge pixels + if (!*currEdge) { + F2(currData, dataWidth); + } + --currData; + --currEdge; + } + + currData += dataWidth+1; + currEdge += dataWidth+1; + } + + // backwards in y + currData = dataPtr+dataWidth*(dataHeight-2) - 1; // skip outer buffer + currEdge = edgePtr+dataWidth*(dataHeight-2) - 1; + for (int j = 1; j < dataHeight-1; ++j) { + // forwards in x + for (int i = 1; i < dataWidth-1; ++i) { + // don't need to calculate distance for edge pixels + if (!*currEdge) { + B1(currData, dataWidth); + } + ++currData; + ++currEdge; + } + + // backwards in x + --currData; // reset to end + --currEdge; + for (int i = 1; i < dataWidth-1; ++i) { + // don't need to calculate distance for edge pixels + if (!*currEdge) { + B2(currData, dataWidth); + } + --currData; + --currEdge; + } + + currData -= dataWidth-1; + currEdge -= dataWidth-1; + } + + // copy results to final distance field data + currData = dataPtr + dataWidth+1; + currEdge = edgePtr + dataWidth+1; + unsigned char *dfPtr = distanceField; + for (int j = 1; j < dataHeight-1; ++j) { + for (int i = 1; i < dataWidth-1; ++i) { +#if DUMP_EDGE + unsigned char val = sk_float_round2int(255*currData->fAlpha); + if (*currEdge) { + val = 128; + } + *dfPtr++ = val; +#else + float dist; + if (currData->fAlpha > 0.5f) { + dist = -SkScalarSqrt(currData->fDistSq); + } else { + dist = SkScalarSqrt(currData->fDistSq); + } + *dfPtr++ = pack_distance_field_val(dist, (float)distanceMagnitude); +#endif + ++currData; + ++currEdge; + } + currData += 2; + currEdge += 2; + } + + return true; +} diff --git a/gfx/skia/trunk/src/core/SkDistanceFieldGen.h b/gfx/skia/trunk/src/core/SkDistanceFieldGen.h new file mode 100644 index 000000000000..3d2ec23b75de --- /dev/null +++ b/gfx/skia/trunk/src/core/SkDistanceFieldGen.h @@ -0,0 +1,25 @@ +/* + * 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 SkDistanceFieldGen_DEFINED +#define SkDistanceFieldGen_DEFINED + +/** Given 8-bit mask data, generate the associated distance field + + * @param distanceField The distance field to be generated. Should already be allocated + * by the client with the padding below. + * @param image 8-bit mask we're using to generate the distance field. + * @param w Width of the image. + * @param h Height of the image. + * @param distanceMagnitude Largest possible absolute value for the distance. The distance field + * will be padded to w + 2*distanceMagnitude, h + 2*distanceMagnitude. + */ +bool SkGenerateDistanceFieldFromImage(unsigned char* distanceField, + const unsigned char* image, + int w, int h, + int distanceMagnitude); + +#endif diff --git a/gfx/skia/trunk/src/core/SkDraw.cpp b/gfx/skia/trunk/src/core/SkDraw.cpp index 5f81073068b9..024fa1bc6a0a 100644 --- a/gfx/skia/trunk/src/core/SkDraw.cpp +++ b/gfx/skia/trunk/src/core/SkDraw.cpp @@ -21,9 +21,9 @@ #include "SkRRect.h" #include "SkScan.h" #include "SkShader.h" +#include "SkSmallAllocator.h" #include "SkString.h" #include "SkStroke.h" -#include "SkTemplatesPriv.h" #include "SkTLazy.h" #include "SkUtils.h" @@ -32,9 +32,9 @@ #include "SkDrawProcs.h" #include "SkMatrixUtils.h" + //#define TRACE_BITMAP_DRAWS -#define kBlitterStorageLongCount (sizeof(SkBitmapProcShader) >> 2) /** Helper for allocating small blitters on the stack. */ @@ -45,16 +45,8 @@ public: } SkAutoBlitterChoose(const SkBitmap& device, const SkMatrix& matrix, const SkPaint& paint, bool drawCoverage = false) { - fBlitter = SkBlitter::Choose(device, matrix, paint, - fStorage, sizeof(fStorage), drawCoverage); - } - - ~SkAutoBlitterChoose() { - if ((void*)fBlitter == (void*)fStorage) { - fBlitter->~SkBlitter(); - } else { - SkDELETE(fBlitter); - } + fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator, + drawCoverage); } SkBlitter* operator->() { return fBlitter; } @@ -63,13 +55,13 @@ public: void choose(const SkBitmap& device, const SkMatrix& matrix, const SkPaint& paint) { SkASSERT(!fBlitter); - fBlitter = SkBlitter::Choose(device, matrix, paint, - fStorage, sizeof(fStorage)); + fBlitter = SkBlitter::Choose(device, matrix, paint, &fAllocator); } private: - SkBlitter* fBlitter; - uint32_t fStorage[kBlitterStorageLongCount]; + // Owned by fAllocator, which will handle the delete. + SkBlitter* fBlitter; + SkTBlitterAllocator fAllocator; }; #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose) @@ -82,34 +74,29 @@ class SkAutoBitmapShaderInstall : SkNoncopyable { public: SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint& paint) : fPaint(paint) /* makes a copy of the paint */ { - fPaint.setShader(SkShader::CreateBitmapShader(src, - SkShader::kClamp_TileMode, SkShader::kClamp_TileMode, - fStorage, sizeof(fStorage))); + fPaint.setShader(CreateBitmapShader(src, SkShader::kClamp_TileMode, + SkShader::kClamp_TileMode, + &fAllocator)); // we deliberately left the shader with an owner-count of 2 SkASSERT(2 == fPaint.getShader()->getRefCnt()); } ~SkAutoBitmapShaderInstall() { - SkShader* shader = fPaint.getShader(); - // since we manually destroy shader, we insist that owners == 2 - SkASSERT(2 == shader->getRefCnt()); + // since fAllocator will destroy shader, we insist that owners == 2 + SkASSERT(2 == fPaint.getShader()->getRefCnt()); fPaint.setShader(NULL); // unref the shader by 1 - // now destroy to take care of the 2nd owner-count - if ((void*)shader == (void*)fStorage) { - shader->~SkShader(); - } else { - SkDELETE(shader); - } } // return the new paint that has the shader applied const SkPaint& paintWithShader() const { return fPaint; } private: - SkPaint fPaint; // copy of caller's paint (which we then modify) - uint32_t fStorage[kBlitterStorageLongCount]; + // copy of caller's paint (which we then modify) + SkPaint fPaint; + // Stores the shader. + SkTBlitterAllocator fAllocator; }; #define SkAutoBitmapShaderInstall(...) SK_REQUIRE_LOCAL_VAR(SkAutoBitmapShaderInstall) @@ -200,20 +187,20 @@ static BitmapXferProc ChooseBitmapXferProc(const SkBitmap& bitmap, should I worry about dithering for the lower depths? */ SkPMColor pmc = SkPreMultiplyColor(color); - switch (bitmap.config()) { - case SkBitmap::kARGB_8888_Config: + switch (bitmap.colorType()) { + case kPMColor_SkColorType: if (data) { *data = pmc; } // SkDebugf("--- D32_Src_BitmapXferProc\n"); return D32_Src_BitmapXferProc; - case SkBitmap::kRGB_565_Config: + case kRGB_565_SkColorType: if (data) { *data = SkPixel32ToPixel16(pmc); } // SkDebugf("--- D16_Src_BitmapXferProc\n"); return D16_Src_BitmapXferProc; - case SkBitmap::kA8_Config: + case kAlpha_8_SkColorType: if (data) { *data = SkGetPackedA32(pmc); } @@ -233,14 +220,14 @@ static BitmapXferProc ChooseBitmapXferProc(const SkBitmap& bitmap, static void CallBitmapXferProc(const SkBitmap& bitmap, const SkIRect& rect, BitmapXferProc proc, uint32_t procData) { int shiftPerPixel; - switch (bitmap.config()) { - case SkBitmap::kARGB_8888_Config: + switch (bitmap.colorType()) { + case kPMColor_SkColorType: shiftPerPixel = 2; break; - case SkBitmap::kRGB_565_Config: + case kRGB_565_SkColorType: shiftPerPixel = 1; break; - case SkBitmap::kA8_Config: + case kAlpha_8_SkColorType: shiftPerPixel = 0; break; default: @@ -526,9 +513,9 @@ PtProcRec::Proc PtProcRec::chooseProc(SkBlitter** blitterPtr) { if (SkCanvas::kPoints_PointMode == fMode && fClip->isRect()) { uint32_t value; const SkBitmap* bm = blitter->justAnOpaqueColor(&value); - if (bm && SkBitmap::kRGB_565_Config == bm->config()) { + if (bm && kRGB_565_SkColorType == bm->colorType()) { proc = bw_pt_rect_16_hair_proc; - } else if (bm && SkBitmap::kARGB_8888_Config == bm->config()) { + } else if (bm && kPMColor_SkColorType == bm->colorType()) { proc = bw_pt_rect_32_hair_proc; } else { proc = bw_pt_rect_hair_proc; @@ -1176,7 +1163,7 @@ static bool just_translate(const SkMatrix& matrix, const SkBitmap& bitmap) { void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, const SkPaint& paint) const { - SkASSERT(bitmap.config() == SkBitmap::kA8_Config); + SkASSERT(bitmap.colorType() == kAlpha_8_SkColorType); if (just_translate(*fMatrix, bitmap)) { int ix = SkScalarRoundToInt(fMatrix->getTranslateX()); @@ -1284,7 +1271,7 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, // nothing to draw if (fRC->isEmpty() || bitmap.width() == 0 || bitmap.height() == 0 || - bitmap.config() == SkBitmap::kNo_Config) { + bitmap.colorType() == kUnknown_SkColorType) { return; } @@ -1310,7 +1297,7 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, } } - if (bitmap.config() != SkBitmap::kA8_Config && + if (bitmap.colorType() != kAlpha_8_SkColorType && just_translate(matrix, bitmap)) { // // It is safe to call lock pixels now, since we know the matrix is @@ -1323,12 +1310,11 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, int ix = SkScalarRoundToInt(matrix.getTranslateX()); int iy = SkScalarRoundToInt(matrix.getTranslateY()); if (clipHandlesSprite(*fRC, ix, iy, bitmap)) { - uint32_t storage[kBlitterStorageLongCount]; - SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap, - ix, iy, storage, sizeof(storage)); + SkTBlitterAllocator allocator; + // blitter will be owned by the allocator. + SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap, + ix, iy, &allocator); if (blitter) { - SkAutoTPlacementDelete ad(blitter, storage); - SkIRect ir; ir.set(ix, iy, ix + bitmap.width(), iy + bitmap.height()); @@ -1343,7 +1329,7 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix, SkDraw draw(*this); draw.fMatrix = &matrix; - if (bitmap.config() == SkBitmap::kA8_Config) { + if (bitmap.colorType() == kAlpha_8_SkColorType) { draw.drawBitmapAsMask(bitmap, paint); } else { SkAutoBitmapShaderInstall install(bitmap, paint); @@ -1363,7 +1349,7 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, // nothing to draw if (fRC->isEmpty() || bitmap.width() == 0 || bitmap.height() == 0 || - bitmap.config() == SkBitmap::kNo_Config) { + bitmap.colorType() == kUnknown_SkColorType) { return; } @@ -1378,13 +1364,12 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, paint.setStyle(SkPaint::kFill_Style); if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, bitmap)) { - uint32_t storage[kBlitterStorageLongCount]; - SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap, - x, y, storage, sizeof(storage)); + SkTBlitterAllocator allocator; + // blitter will be owned by the allocator. + SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, bitmap, + x, y, &allocator); if (blitter) { - SkAutoTPlacementDelete ad(blitter, storage); - if (fBounder && !fBounder->doIRect(bounds)) { return; } @@ -2378,7 +2363,7 @@ public: virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader) protected: @@ -2451,7 +2436,7 @@ void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkTriColorShader::toString(SkString* str) const { str->append("SkTriColorShader: ("); diff --git a/gfx/skia/trunk/src/core/SkDrawLooper.cpp b/gfx/skia/trunk/src/core/SkDrawLooper.cpp index bac2d969c050..c620cd08da5b 100644 --- a/gfx/skia/trunk/src/core/SkDrawLooper.cpp +++ b/gfx/skia/trunk/src/core/SkDrawLooper.cpp @@ -10,14 +10,17 @@ #include "SkMatrix.h" #include "SkPaint.h" #include "SkRect.h" +#include "SkSmallAllocator.h" -bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) { +bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const { SkCanvas canvas; + SkSmallAllocator<1, 32> allocator; + void* buffer = allocator.reserveT(this->contextSize()); - this->init(&canvas); + SkDrawLooper::Context* context = this->createContext(&canvas, buffer); for (;;) { SkPaint p(paint); - if (this->next(&canvas, &p)) { + if (context->next(&canvas, &p)) { p.setLooper(NULL); if (!p.canComputeFastBounds()) { return false; @@ -30,14 +33,16 @@ bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) { } void SkDrawLooper::computeFastBounds(const SkPaint& paint, const SkRect& src, - SkRect* dst) { + SkRect* dst) const { SkCanvas canvas; + SkSmallAllocator<1, 32> allocator; + void* buffer = allocator.reserveT(this->contextSize()); *dst = src; // catch case where there are no loops - this->init(&canvas); + SkDrawLooper::Context* context = this->createContext(&canvas, buffer); for (bool firstTime = true;; firstTime = false) { SkPaint p(paint); - if (this->next(&canvas, &p)) { + if (context->next(&canvas, &p)) { SkRect r(src); p.setLooper(NULL); diff --git a/gfx/skia/trunk/src/core/SkFP.h b/gfx/skia/trunk/src/core/SkFP.h deleted file mode 100644 index 1d1507a3697a..000000000000 --- a/gfx/skia/trunk/src/core/SkFP.h +++ /dev/null @@ -1,79 +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 SkFP_DEFINED -#define SkFP_DEFINED - -#include "SkMath.h" - -#ifdef SK_SCALAR_IS_FLOAT - - typedef float SkFP; - - #define SkScalarToFP(n) (n) - #define SkFPToScalar(n) (n) - #define SkIntToFP(n) SkIntToScalar(n) - #define SkFPRound(x) SkScalarRound(n) - #define SkFPCeil(x) SkScalarCeil(n) - #define SkFPFloor(x) SkScalarFloor(n) - - #define SkFPNeg(x) (-(x)) - #define SkFPAbs(x) SkScalarAbs(x) - #define SkFPAdd(a, b) ((a) + (b)) - #define SkFPSub(a, b) ((a) - (b)) - #define SkFPMul(a, b) ((a) * (b)) - #define SkFPMulInt(a, n) ((a) * (n)) - #define SkFPDiv(a, b) ((a) / (b)) - #define SkFPDivInt(a, n) ((a) / (n)) - #define SkFPInvert(x) SkScalarInvert(x) - #define SkFPSqrt(x) SkScalarSqrt(x) - #define SkFPCubeRoot(x) sk_float_pow(x, 0.3333333f) - - #define SkFPLT(a, b) ((a) < (b)) - #define SkFPLE(a, b) ((a) <= (b)) - #define SkFPGT(a, b) ((a) > (b)) - #define SkFPGE(a, b) ((a) >= (b)) - -#else // scalar is fixed - - #include "SkFloat.h" - - typedef int32_t SkFP; - - #define SkScalarToFP(n) SkFloat::SetShift(n, -16) - #define SkFPToScalar(n) SkFloat::GetShift(n, -16) - #define SkIntToFP(n) SkFloat::SetShift(n, 0) - #define SkFPRound(x) SkFloat::Round(x); - #define SkFPCeil(x) SkFloat::Ceil(); - #define SkFPFloor(x) SkFloat::Floor(); - - #define SkFPNeg(x) SkFloat::Neg(x) - #define SkFPAbs(x) SkFloat::Abs(x) - #define SkFPAdd(a, b) SkFloat::Add(a, b) - #define SkFPSub(a, b) SkFloat::Add(a, SkFloat::Neg(b)) - #define SkFPMul(a, b) SkFloat::Mul(a, b) - #define SkFPMulInt(a, n) SkFloat::MulInt(a, n) - #define SkFPDiv(a, b) SkFloat::Div(a, b) - #define SkFPDivInt(a, n) SkFloat::DivInt(a, n) - #define SkFPInvert(x) SkFloat::Invert(x) - #define SkFPSqrt(x) SkFloat::Sqrt(x) - #define SkFPCubeRoot(x) SkFloat::CubeRoot(x) - - #define SkFPLT(a, b) (SkFloat::Cmp(a, b) < 0) - #define SkFPLE(a, b) (SkFloat::Cmp(a, b) <= 0) - #define SkFPGT(a, b) (SkFloat::Cmp(a, b) > 0) - #define SkFPGE(a, b) (SkFloat::Cmp(a, b) >= 0) - -#endif - -#ifdef SK_DEBUG - void SkFP_UnitTest(); -#endif - -#endif diff --git a/gfx/skia/trunk/src/core/SkFilterShader.cpp b/gfx/skia/trunk/src/core/SkFilterShader.cpp index feea75b48b18..58961913c8e4 100644 --- a/gfx/skia/trunk/src/core/SkFilterShader.cpp +++ b/gfx/skia/trunk/src/core/SkFilterShader.cpp @@ -87,7 +87,7 @@ void SkFilterShader::shadeSpan16(int x, int y, uint16_t result[], int count) { fFilter->filterSpan16(result, count, result); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkFilterShader::toString(SkString* str) const { str->append("SkFilterShader: ("); diff --git a/gfx/skia/trunk/src/core/SkFilterShader.h b/gfx/skia/trunk/src/core/SkFilterShader.h index abb516557889..11add0cf17c6 100644 --- a/gfx/skia/trunk/src/core/SkFilterShader.h +++ b/gfx/skia/trunk/src/core/SkFilterShader.h @@ -24,7 +24,7 @@ public: virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkFilterShader) protected: diff --git a/gfx/skia/trunk/src/core/SkFlattenableBuffers.cpp b/gfx/skia/trunk/src/core/SkFlattenableBuffers.cpp deleted file mode 100644 index 9da4dd9ee486..000000000000 --- a/gfx/skia/trunk/src/core/SkFlattenableBuffers.cpp +++ /dev/null @@ -1,116 +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. - */ -#include "SkFlattenableBuffers.h" -#include "SkPaint.h" -#include "SkTypeface.h" - -#include "SkColorFilter.h" -#include "SkDrawLooper.h" -#include "SkImageFilter.h" -#include "SkMaskFilter.h" -#include "SkPathEffect.h" -#include "SkPixelRef.h" -#include "SkRasterizer.h" -#include "SkShader.h" -#include "SkUnitMapper.h" -#include "SkXfermode.h" - -SkFlattenableReadBuffer::SkFlattenableReadBuffer() { - // Set default values. These should be explicitly set by our client - // via setFlags() if the buffer came from serialization. - fFlags = 0; -#ifdef SK_SCALAR_IS_FLOAT - fFlags |= kScalarIsFloat_Flag; -#endif - if (8 == sizeof(void*)) { - fFlags |= kPtrIs64Bit_Flag; - } -} - -SkFlattenableReadBuffer::~SkFlattenableReadBuffer() { } - -void* SkFlattenableReadBuffer::readFunctionPtr() { - void* proc; - SkASSERT(sizeof(void*) == this->getArrayCount()); - this->readByteArray(&proc, sizeof(void*)); - return proc; -} - -void SkFlattenableReadBuffer::readPaint(SkPaint* paint) { - paint->unflatten(*this); -} - -template T* SkFlattenableReadBuffer::readFlattenableT() { - return static_cast(this->readFlattenable(T::GetFlattenableType())); -} - -SkColorFilter* SkFlattenableReadBuffer::readColorFilter() { - return this->readFlattenableT(); -} - -SkDrawLooper* SkFlattenableReadBuffer::readDrawLooper() { - return this->readFlattenableT(); -} - -SkImageFilter* SkFlattenableReadBuffer::readImageFilter() { - return this->readFlattenableT(); -} - -SkMaskFilter* SkFlattenableReadBuffer::readMaskFilter() { - return this->readFlattenableT(); -} - -SkPathEffect* SkFlattenableReadBuffer::readPathEffect() { - return this->readFlattenableT(); -} - -SkPixelRef* SkFlattenableReadBuffer::readPixelRef() { - return this->readFlattenableT(); -} - -SkRasterizer* SkFlattenableReadBuffer::readRasterizer() { - return this->readFlattenableT(); -} - -SkShader* SkFlattenableReadBuffer::readShader() { - return this->readFlattenableT(); -} - -SkUnitMapper* SkFlattenableReadBuffer::readUnitMapper() { - return this->readFlattenableT(); -} - -SkXfermode* SkFlattenableReadBuffer::readXfermode() { - return this->readFlattenableT(); -} - -bool SkFlattenableReadBuffer::validate(bool isValid) { - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -SkFlattenableWriteBuffer::SkFlattenableWriteBuffer() { - fFlags = (Flags)0; -} - -SkFlattenableWriteBuffer::~SkFlattenableWriteBuffer() { } - -void SkFlattenableWriteBuffer::writeFunctionPtr(void* ptr) { - void* ptrStorage[] = { ptr }; - this->writeByteArray(ptrStorage, sizeof(void*)); -} - -void SkFlattenableWriteBuffer::writePaint(const SkPaint& paint) { - paint.flatten(*this); -} - -void SkFlattenableWriteBuffer::flattenObject(const SkFlattenable* obj, - SkFlattenableWriteBuffer& buffer) { - obj->flatten(buffer); -} diff --git a/gfx/skia/trunk/src/core/SkGeometry.cpp b/gfx/skia/trunk/src/core/SkGeometry.cpp index 574954019eb8..646dfb05b9d4 100644 --- a/gfx/skia/trunk/src/core/SkGeometry.cpp +++ b/gfx/skia/trunk/src/core/SkGeometry.cpp @@ -8,7 +8,9 @@ #include "SkGeometry.h" #include "SkMatrix.h" -bool SkXRayCrossesLine(const SkXRay& pt, const SkPoint pts[2], bool* ambiguous) { +bool SkXRayCrossesLine(const SkXRay& pt, + const SkPoint pts[2], + bool* ambiguous) { if (ambiguous) { *ambiguous = false; } @@ -69,9 +71,9 @@ bool SkXRayCrossesLine(const SkXRay& pt, const SkPoint pts[2], bool* ambiguous) //////////////////////////////////////////////////////////////////////// -static int is_not_monotonic(float a, float b, float c) { - float ab = a - b; - float bc = b - c; +static int is_not_monotonic(SkScalar a, SkScalar b, SkScalar c) { + SkScalar ab = a - b; + SkScalar bc = b - c; if (ab < 0) { bc = -bc; } @@ -80,31 +82,30 @@ static int is_not_monotonic(float a, float b, float c) { //////////////////////////////////////////////////////////////////////// -static bool is_unit_interval(SkScalar x) -{ +static bool is_unit_interval(SkScalar x) { return x > 0 && x < SK_Scalar1; } -static int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio) -{ +static int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio) { SkASSERT(ratio); - if (numer < 0) - { + if (numer < 0) { numer = -numer; denom = -denom; } - if (denom == 0 || numer == 0 || numer >= denom) + if (denom == 0 || numer == 0 || numer >= denom) { return 0; + } SkScalar r = SkScalarDiv(numer, denom); if (SkScalarIsNaN(r)) { return 0; } SkASSERT(r >= 0 && r < SK_Scalar1); - if (r == 0) // catch underflow if numer <<<< denom + if (r == 0) { // catch underflow if numer <<<< denom return 0; + } *ratio = r; return 1; } @@ -115,26 +116,25 @@ static int valid_unit_divide(SkScalar numer, SkScalar denom, SkScalar* ratio) x1 = Q / A x2 = C / Q */ -int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) -{ +int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) { SkASSERT(roots); - if (A == 0) + if (A == 0) { return valid_unit_divide(-C, B, roots); + } SkScalar* r = roots; - float R = B*B - 4*A*C; + SkScalar R = B*B - 4*A*C; if (R < 0 || SkScalarIsNaN(R)) { // complex roots return 0; } - R = sk_float_sqrt(R); + R = SkScalarSqrt(R); SkScalar Q = (B < 0) ? -(B-R)/2 : -(B+R)/2; r += valid_unit_divide(Q, A, r); r += valid_unit_divide(C, Q, r); - if (r - roots == 2) - { + if (r - roots == 2) { if (roots[0] > roots[1]) SkTSwap(roots[0], roots[1]); else if (roots[0] == roots[1]) // nearly-equal? @@ -146,8 +146,7 @@ int SkFindUnitQuadRoots(SkScalar A, SkScalar B, SkScalar C, SkScalar roots[2]) /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -static SkScalar eval_quad(const SkScalar src[], SkScalar t) -{ +static SkScalar eval_quad(const SkScalar src[], SkScalar t) { SkASSERT(src); SkASSERT(t >= 0 && t <= SK_Scalar1); @@ -163,52 +162,50 @@ static SkScalar eval_quad(const SkScalar src[], SkScalar t) #endif } -static SkScalar eval_quad_derivative(const SkScalar src[], SkScalar t) -{ +static SkScalar eval_quad_derivative(const SkScalar src[], SkScalar t) { SkScalar A = src[4] - 2 * src[2] + src[0]; SkScalar B = src[2] - src[0]; return 2 * SkScalarMulAdd(A, t, B); } -static SkScalar eval_quad_derivative_at_half(const SkScalar src[]) -{ +static SkScalar eval_quad_derivative_at_half(const SkScalar src[]) { SkScalar A = src[4] - 2 * src[2] + src[0]; SkScalar B = src[2] - src[0]; return A + 2 * B; } -void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, SkVector* tangent) -{ +void SkEvalQuadAt(const SkPoint src[3], SkScalar t, SkPoint* pt, + SkVector* tangent) { SkASSERT(src); SkASSERT(t >= 0 && t <= SK_Scalar1); - if (pt) + if (pt) { pt->set(eval_quad(&src[0].fX, t), eval_quad(&src[0].fY, t)); - if (tangent) + } + if (tangent) { tangent->set(eval_quad_derivative(&src[0].fX, t), eval_quad_derivative(&src[0].fY, t)); + } } -void SkEvalQuadAtHalf(const SkPoint src[3], SkPoint* pt, SkVector* tangent) -{ +void SkEvalQuadAtHalf(const SkPoint src[3], SkPoint* pt, SkVector* tangent) { SkASSERT(src); - if (pt) - { + if (pt) { SkScalar x01 = SkScalarAve(src[0].fX, src[1].fX); SkScalar y01 = SkScalarAve(src[0].fY, src[1].fY); SkScalar x12 = SkScalarAve(src[1].fX, src[2].fX); SkScalar y12 = SkScalarAve(src[1].fY, src[2].fY); pt->set(SkScalarAve(x01, x12), SkScalarAve(y01, y12)); } - if (tangent) + if (tangent) { tangent->set(eval_quad_derivative_at_half(&src[0].fX), eval_quad_derivative_at_half(&src[0].fY)); + } } -static void interp_quad_coords(const SkScalar* src, SkScalar* dst, SkScalar t) -{ +static void interp_quad_coords(const SkScalar* src, SkScalar* dst, SkScalar t) { SkScalar ab = SkScalarInterp(src[0], src[2], t); SkScalar bc = SkScalarInterp(src[2], src[4], t); @@ -219,16 +216,14 @@ static void interp_quad_coords(const SkScalar* src, SkScalar* dst, SkScalar t) dst[8] = src[4]; } -void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t) -{ +void SkChopQuadAt(const SkPoint src[3], SkPoint dst[5], SkScalar t) { SkASSERT(t > 0 && t < SK_Scalar1); interp_quad_coords(&src[0].fX, &dst[0].fX, t); interp_quad_coords(&src[0].fY, &dst[0].fY, t); } -void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) -{ +void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) { SkScalar x01 = SkScalarAve(src[0].fX, src[1].fX); SkScalar y01 = SkScalarAve(src[0].fY, src[1].fY); SkScalar x12 = SkScalarAve(src[1].fX, src[2].fX); @@ -246,49 +241,31 @@ void SkChopQuadAtHalf(const SkPoint src[3], SkPoint dst[5]) B = 2(b - a) Solve for t, only if it fits between 0 < t < 1 */ -int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValue[1]) -{ +int SkFindQuadExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar tValue[1]) { /* At + B == 0 t = -B / A */ return valid_unit_divide(a - b, a - b - b + c, tValue); } -static inline void flatten_double_quad_extrema(SkScalar coords[14]) -{ +static inline void flatten_double_quad_extrema(SkScalar coords[14]) { coords[2] = coords[6] = coords[4]; } /* Returns 0 for 1 quad, and 1 for two quads, either way the answer is stored in dst[]. Guarantees that the 1/2 quads will be monotonic. */ -int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5]) -{ +int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5]) { SkASSERT(src); SkASSERT(dst); -#if 0 - static bool once = true; - if (once) - { - once = false; - SkPoint s[3] = { 0, 26398, 0, 26331, 0, 20621428 }; - SkPoint d[6]; - - int n = SkChopQuadAtYExtrema(s, d); - SkDebugf("chop=%d, Y=[%x %x %x %x %x %x]\n", n, d[0].fY, d[1].fY, d[2].fY, d[3].fY, d[4].fY, d[5].fY); - } -#endif - SkScalar a = src[0].fY; SkScalar b = src[1].fY; SkScalar c = src[2].fY; - if (is_not_monotonic(a, b, c)) - { + if (is_not_monotonic(a, b, c)) { SkScalar tValue; - if (valid_unit_divide(a - b, a - b - b + c, &tValue)) - { + if (valid_unit_divide(a - b, a - b - b + c, &tValue)) { SkChopQuadAt(src, dst, tValue); flatten_double_quad_extrema(&dst[0].fY); return 1; @@ -306,8 +283,7 @@ int SkChopQuadAtYExtrema(const SkPoint src[3], SkPoint dst[5]) /* Returns 0 for 1 quad, and 1 for two quads, either way the answer is stored in dst[]. Guarantees that the 1/2 quads will be monotonic. */ -int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5]) -{ +int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5]) { SkASSERT(src); SkASSERT(dst); @@ -344,7 +320,7 @@ int SkChopQuadAtXExtrema(const SkPoint src[3], SkPoint dst[5]) // // t = - (Ax Bx + Ay By) / (Bx ^ 2 + By ^ 2) // -float SkFindQuadMaxCurvature(const SkPoint src[3]) { +SkScalar SkFindQuadMaxCurvature(const SkPoint src[3]) { SkScalar Ax = src[1].fX - src[0].fX; SkScalar Ay = src[1].fY - src[0].fY; SkScalar Bx = src[0].fX - src[1].fX - src[1].fX + src[2].fX; @@ -355,8 +331,7 @@ float SkFindQuadMaxCurvature(const SkPoint src[3]) { return t; } -int SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5]) -{ +int SkChopQuadAtMaxCurvature(const SkPoint src[3], SkPoint dst[5]) { SkScalar t = SkFindQuadMaxCurvature(src); if (t == 0) { memcpy(dst, src, 3 * sizeof(SkPoint)); @@ -379,35 +354,35 @@ void SkConvertQuadToCubic(const SkPoint src[3], SkPoint dst[4]) { dst[3] = src[2]; } -//////////////////////////////////////////////////////////////////////////////////////// -///// CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS ///// -//////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +///// CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS // CUBICS ///// +////////////////////////////////////////////////////////////////////////////// -static void get_cubic_coeff(const SkScalar pt[], SkScalar coeff[4]) -{ +static void get_cubic_coeff(const SkScalar pt[], SkScalar coeff[4]) { coeff[0] = pt[6] + 3*(pt[2] - pt[4]) - pt[0]; coeff[1] = 3*(pt[4] - pt[2] - pt[2] + pt[0]); coeff[2] = 3*(pt[2] - pt[0]); coeff[3] = pt[0]; } -void SkGetCubicCoeff(const SkPoint pts[4], SkScalar cx[4], SkScalar cy[4]) -{ +void SkGetCubicCoeff(const SkPoint pts[4], SkScalar cx[4], SkScalar cy[4]) { SkASSERT(pts); - if (cx) + if (cx) { get_cubic_coeff(&pts[0].fX, cx); - if (cy) + } + if (cy) { get_cubic_coeff(&pts[0].fY, cy); + } } -static SkScalar eval_cubic(const SkScalar src[], SkScalar t) -{ +static SkScalar eval_cubic(const SkScalar src[], SkScalar t) { SkASSERT(src); SkASSERT(t >= 0 && t <= SK_Scalar1); - if (t == 0) + if (t == 0) { return src[0]; + } #ifdef DIRECT_EVAL_OF_POLYNOMIALS SkScalar D = src[0]; @@ -428,15 +403,13 @@ static SkScalar eval_cubic(const SkScalar src[], SkScalar t) /** return At^2 + Bt + C */ -static SkScalar eval_quadratic(SkScalar A, SkScalar B, SkScalar C, SkScalar t) -{ +static SkScalar eval_quadratic(SkScalar A, SkScalar B, SkScalar C, SkScalar t) { SkASSERT(t >= 0 && t <= SK_Scalar1); return SkScalarMulAdd(SkScalarMulAdd(A, t, B), t, C); } -static SkScalar eval_cubic_derivative(const SkScalar src[], SkScalar t) -{ +static SkScalar eval_cubic_derivative(const SkScalar src[], SkScalar t) { SkScalar A = src[6] + 3*(src[2] - src[4]) - src[0]; SkScalar B = 2*(src[4] - 2 * src[2] + src[0]); SkScalar C = src[2] - src[0]; @@ -444,27 +417,29 @@ static SkScalar eval_cubic_derivative(const SkScalar src[], SkScalar t) return eval_quadratic(A, B, C, t); } -static SkScalar eval_cubic_2ndDerivative(const SkScalar src[], SkScalar t) -{ +static SkScalar eval_cubic_2ndDerivative(const SkScalar src[], SkScalar t) { SkScalar A = src[6] + 3*(src[2] - src[4]) - src[0]; SkScalar B = src[4] - 2 * src[2] + src[0]; return SkScalarMulAdd(A, t, B); } -void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* loc, SkVector* tangent, SkVector* curvature) -{ +void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* loc, + SkVector* tangent, SkVector* curvature) { SkASSERT(src); SkASSERT(t >= 0 && t <= SK_Scalar1); - if (loc) + if (loc) { loc->set(eval_cubic(&src[0].fX, t), eval_cubic(&src[0].fY, t)); - if (tangent) + } + if (tangent) { tangent->set(eval_cubic_derivative(&src[0].fX, t), eval_cubic_derivative(&src[0].fY, t)); - if (curvature) + } + if (curvature) { curvature->set(eval_cubic_2ndDerivative(&src[0].fX, t), eval_cubic_2ndDerivative(&src[0].fY, t)); + } } /** Cubic'(t) = At^2 + Bt + C, where @@ -473,8 +448,8 @@ void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint* loc, SkVector* tan C = 3(b - a) Solve for t, keeping only those that fit betwee 0 < t < 1 */ -int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, SkScalar tValues[2]) -{ +int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, + SkScalar tValues[2]) { // we divide A,B,C by 3 to simplify SkScalar A = d - a + 3*(b - c); SkScalar B = 2*(a - b - b + c); @@ -483,8 +458,8 @@ int SkFindCubicExtrema(SkScalar a, SkScalar b, SkScalar c, SkScalar d, SkScalar return SkFindUnitQuadRoots(A, B, C, tValues); } -static void interp_cubic_coords(const SkScalar* src, SkScalar* dst, SkScalar t) -{ +static void interp_cubic_coords(const SkScalar* src, SkScalar* dst, + SkScalar t) { SkScalar ab = SkScalarInterp(src[0], src[2], t); SkScalar bc = SkScalarInterp(src[2], src[4], t); SkScalar cd = SkScalarInterp(src[4], src[6], t); @@ -501,8 +476,7 @@ static void interp_cubic_coords(const SkScalar* src, SkScalar* dst, SkScalar t) dst[12] = src[6]; } -void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t) -{ +void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t) { SkASSERT(t > 0 && t < SK_Scalar1); interp_cubic_coords(&src[0].fX, &dst[0].fX, t); @@ -532,8 +506,8 @@ void SkChopCubicAt(const SkPoint src[4], SkPoint dst[7], SkScalar t) } */ -void SkChopCubicAt(const SkPoint src[4], SkPoint dst[], const SkScalar tValues[], int roots) -{ +void SkChopCubicAt(const SkPoint src[4], SkPoint dst[], + const SkScalar tValues[], int roots) { #ifdef SK_DEBUG { for (int i = 0; i < roots - 1; i++) @@ -545,20 +519,18 @@ void SkChopCubicAt(const SkPoint src[4], SkPoint dst[], const SkScalar tValues[] } #endif - if (dst) - { - if (roots == 0) // nothing to chop + if (dst) { + if (roots == 0) { // nothing to chop memcpy(dst, src, 4*sizeof(SkPoint)); - else - { + } else { SkScalar t = tValues[0]; SkPoint tmp[4]; - for (int i = 0; i < roots; i++) - { + for (int i = 0; i < roots; i++) { SkChopCubicAt(src, dst, t); - if (i == roots - 1) + if (i == roots - 1) { break; + } dst += 3; // have src point to the remaining cubic (after the chop) @@ -577,8 +549,7 @@ void SkChopCubicAt(const SkPoint src[4], SkPoint dst[], const SkScalar tValues[] } } -void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]) -{ +void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]) { SkScalar x01 = SkScalarAve(src[0].fX, src[1].fX); SkScalar y01 = SkScalarAve(src[0].fY, src[1].fY); SkScalar x12 = SkScalarAve(src[1].fX, src[2].fX); @@ -600,14 +571,13 @@ void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7]) dst[6] = src[3]; } -static void flatten_double_cubic_extrema(SkScalar coords[14]) -{ +static void flatten_double_cubic_extrema(SkScalar coords[14]) { coords[4] = coords[8] = coords[6]; } /** Given 4 points on a cubic bezier, chop it into 1, 2, 3 beziers such that - the resulting beziers are monotonic in Y. This is called by the scan converter. - Depending on what is returned, dst[] is treated as follows + the resulting beziers are monotonic in Y. This is called by the scan + converter. Depending on what is returned, dst[] is treated as follows: 0 dst[0..3] is the original cubic 1 dst[0..3] and dst[3..6] are the two new cubics 2 dst[0..3], dst[3..6], dst[6..9] are the three new cubics @@ -656,8 +626,7 @@ int SkChopCubicAtXExtrema(const SkPoint src[4], SkPoint dst[10]) { C = d - 3c + 3b - a (BxCy - ByCx)t^2 + (AxCy - AyCx)t + AxBy - AyBx == 0 */ -int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[]) -{ +int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[]) { SkScalar Ax = src[1].fX - src[0].fX; SkScalar Ay = src[1].fY - src[0].fY; SkScalar Bx = src[2].fX - 2 * src[1].fX + src[0].fX; @@ -665,26 +634,27 @@ int SkFindCubicInflections(const SkPoint src[4], SkScalar tValues[]) SkScalar Cx = src[3].fX + 3 * (src[1].fX - src[2].fX) - src[0].fX; SkScalar Cy = src[3].fY + 3 * (src[1].fY - src[2].fY) - src[0].fY; - return SkFindUnitQuadRoots(Bx*Cy - By*Cx, Ax*Cy - Ay*Cx, Ax*By - Ay*Bx, tValues); + return SkFindUnitQuadRoots(Bx*Cy - By*Cx, + Ax*Cy - Ay*Cx, + Ax*By - Ay*Bx, + tValues); } -int SkChopCubicAtInflections(const SkPoint src[], SkPoint dst[10]) -{ +int SkChopCubicAtInflections(const SkPoint src[], SkPoint dst[10]) { SkScalar tValues[2]; int count = SkFindCubicInflections(src, tValues); - if (dst) - { - if (count == 0) + if (dst) { + if (count == 0) { memcpy(dst, src, 4 * sizeof(SkPoint)); - else + } else { SkChopCubicAt(src, dst, tValues, count); + } } return count + 1; } -template void bubble_sort(T array[], int count) -{ +template void bubble_sort(T array[], int count) { for (int i = count - 1; i > 0; --i) for (int j = i; j > 0; --j) if (array[j] < array[j-1]) @@ -695,45 +665,11 @@ template void bubble_sort(T array[], int count) } } -// newton refinement -#if 0 -static SkScalar refine_cubic_root(const SkFP coeff[4], SkScalar root) -{ - // x1 = x0 - f(t) / f'(t) - - SkFP T = SkScalarToFloat(root); - SkFP N, D; - - // f' = 3*coeff[0]*T^2 + 2*coeff[1]*T + coeff[2] - D = SkFPMul(SkFPMul(coeff[0], SkFPMul(T,T)), 3); - D = SkFPAdd(D, SkFPMulInt(SkFPMul(coeff[1], T), 2)); - D = SkFPAdd(D, coeff[2]); - - if (D == 0) - return root; - - // f = coeff[0]*T^3 + coeff[1]*T^2 + coeff[2]*T + coeff[3] - N = SkFPMul(SkFPMul(SkFPMul(T, T), T), coeff[0]); - N = SkFPAdd(N, SkFPMul(SkFPMul(T, T), coeff[1])); - N = SkFPAdd(N, SkFPMul(T, coeff[2])); - N = SkFPAdd(N, coeff[3]); - - if (N) - { - SkScalar delta = SkFPToScalar(SkFPDiv(N, D)); - - if (delta) - root -= delta; - } - return root; -} -#endif - /** * Given an array and count, remove all pair-wise duplicates from the array, * keeping the existing sorting, and return the new count */ -static int collaps_duplicates(float array[], int count) { +static int collaps_duplicates(SkScalar array[], int count) { for (int n = count; n > 1; --n) { if (array[0] == array[1]) { for (int i = 1; i < n; ++i) { @@ -755,15 +691,15 @@ static void test_collaps_duplicates() { static bool gOnce; if (gOnce) { return; } gOnce = true; - const float src0[] = { 0 }; - const float src1[] = { 0, 0 }; - const float src2[] = { 0, 1 }; - const float src3[] = { 0, 0, 0 }; - const float src4[] = { 0, 0, 1 }; - const float src5[] = { 0, 1, 1 }; - const float src6[] = { 0, 1, 2 }; + const SkScalar src0[] = { 0 }; + const SkScalar src1[] = { 0, 0 }; + const SkScalar src2[] = { 0, 1 }; + const SkScalar src3[] = { 0, 0, 0 }; + const SkScalar src4[] = { 0, 0, 1 }; + const SkScalar src5[] = { 0, 1, 1 }; + const SkScalar src6[] = { 0, 1, 2 }; const struct { - const float* fData; + const SkScalar* fData; int fCount; int fCollapsedCount; } data[] = { @@ -776,7 +712,7 @@ static void test_collaps_duplicates() { { TEST_COLLAPS_ENTRY(src6), 3 }, }; for (size_t i = 0; i < SK_ARRAY_COUNT(data); ++i) { - float dst[3]; + SkScalar dst[3]; memcpy(dst, data[i].fData, data[i].fCount * sizeof(dst[0])); int count = collaps_duplicates(dst, data[i].fCount); SkASSERT(data[i].fCollapsedCount == count); @@ -788,7 +724,7 @@ static void test_collaps_duplicates() { #endif static SkScalar SkScalarCubeRoot(SkScalar x) { - return sk_float_pow(x, 0.3333333f); + return SkScalarPow(x, 0.3333333f); } /* Solve coeff(t) == 0, returning the number of roots that @@ -798,10 +734,8 @@ static SkScalar SkScalarCubeRoot(SkScalar x) { Eliminates repeated roots (so that all tValues are distinct, and are always in increasing order. */ -static int solve_cubic_polynomial(const SkScalar coeff[4], SkScalar tValues[3]) -{ - if (SkScalarNearlyZero(coeff[0])) // we're just a quadratic - { +static int solve_cubic_poly(const SkScalar coeff[4], SkScalar tValues[3]) { + if (SkScalarNearlyZero(coeff[0])) { // we're just a quadratic return SkFindUnitQuadRoots(coeff[1], coeff[2], coeff[3], tValues); } @@ -825,23 +759,22 @@ static int solve_cubic_polynomial(const SkScalar coeff[4], SkScalar tValues[3]) SkScalar* roots = tValues; SkScalar r; - if (R2MinusQ3 < 0) // we have 3 real roots - { - float theta = sk_float_acos(R / sk_float_sqrt(Q3)); - float neg2RootQ = -2 * sk_float_sqrt(Q); + if (R2MinusQ3 < 0) { // we have 3 real roots + SkScalar theta = SkScalarACos(R / SkScalarSqrt(Q3)); + SkScalar neg2RootQ = -2 * SkScalarSqrt(Q); - r = neg2RootQ * sk_float_cos(theta/3) - adiv3; - if (is_unit_interval(r)) + r = neg2RootQ * SkScalarCos(theta/3) - adiv3; + if (is_unit_interval(r)) { *roots++ = r; - - r = neg2RootQ * sk_float_cos((theta + 2*SK_ScalarPI)/3) - adiv3; - if (is_unit_interval(r)) + } + r = neg2RootQ * SkScalarCos((theta + 2*SK_ScalarPI)/3) - adiv3; + if (is_unit_interval(r)) { *roots++ = r; - - r = neg2RootQ * sk_float_cos((theta - 2*SK_ScalarPI)/3) - adiv3; - if (is_unit_interval(r)) + } + r = neg2RootQ * SkScalarCos((theta - 2*SK_ScalarPI)/3) - adiv3; + if (is_unit_interval(r)) { *roots++ = r; - + } SkDEBUGCODE(test_collaps_duplicates();) // now sort the roots @@ -850,19 +783,19 @@ static int solve_cubic_polynomial(const SkScalar coeff[4], SkScalar tValues[3]) bubble_sort(tValues, count); count = collaps_duplicates(tValues, count); roots = tValues + count; // so we compute the proper count below - } - else // we have 1 real root - { + } else { // we have 1 real root SkScalar A = SkScalarAbs(R) + SkScalarSqrt(R2MinusQ3); A = SkScalarCubeRoot(A); - if (R > 0) + if (R > 0) { A = -A; - - if (A != 0) + } + if (A != 0) { A += Q / A; + } r = A - adiv3; - if (is_unit_interval(r)) + if (is_unit_interval(r)) { *roots++ = r; + } } return (int)(roots - tValues); @@ -879,8 +812,7 @@ static int solve_cubic_polynomial(const SkScalar coeff[4], SkScalar tValues[3]) F' dot F'' -> CCt^3 + 3BCt^2 + (2BB + CA)t + AB */ -static void formulate_F1DotF2(const SkScalar src[], SkScalar coeff[4]) -{ +static void formulate_F1DotF2(const SkScalar src[], SkScalar coeff[4]) { SkScalar a = src[2] - src[0]; SkScalar b = src[4] - 2 * src[2] + src[0]; SkScalar c = src[6] + 3 * (src[2] - src[4]) - src[0]; @@ -891,10 +823,6 @@ static void formulate_F1DotF2(const SkScalar src[], SkScalar coeff[4]) coeff[3] = a * b; } -// EXPERIMENTAL: can set this to zero to accept all t-values 0 < t < 1 -//#define kMinTValueForChopping (SK_Scalar1 / 256) -#define kMinTValueForChopping 0 - /* Looking for F' dot F'' == 0 A = b - a @@ -906,51 +834,54 @@ static void formulate_F1DotF2(const SkScalar src[], SkScalar coeff[4]) F' dot F'' -> CCt^3 + 3BCt^2 + (2BB + CA)t + AB */ -int SkFindCubicMaxCurvature(const SkPoint src[4], SkScalar tValues[3]) -{ +int SkFindCubicMaxCurvature(const SkPoint src[4], SkScalar tValues[3]) { SkScalar coeffX[4], coeffY[4]; int i; formulate_F1DotF2(&src[0].fX, coeffX); formulate_F1DotF2(&src[0].fY, coeffY); - for (i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { coeffX[i] += coeffY[i]; + } SkScalar t[3]; - int count = solve_cubic_polynomial(coeffX, t); + int count = solve_cubic_poly(coeffX, t); int maxCount = 0; // now remove extrema where the curvature is zero (mins) // !!!! need a test for this !!!! - for (i = 0; i < count; i++) - { + for (i = 0; i < count; i++) { // if (not_min_curvature()) - if (t[i] > kMinTValueForChopping && t[i] < SK_Scalar1 - kMinTValueForChopping) + if (t[i] > 0 && t[i] < SK_Scalar1) { tValues[maxCount++] = t[i]; + } } return maxCount; } -int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13], SkScalar tValues[3]) -{ +int SkChopCubicAtMaxCurvature(const SkPoint src[4], SkPoint dst[13], + SkScalar tValues[3]) { SkScalar t_storage[3]; - if (tValues == NULL) + if (tValues == NULL) { tValues = t_storage; + } int count = SkFindCubicMaxCurvature(src, tValues); if (dst) { - if (count == 0) + if (count == 0) { memcpy(dst, src, 4 * sizeof(SkPoint)); - else + } else { SkChopCubicAt(src, dst, tValues, count); + } } return count + 1; } -bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4], bool* ambiguous) { +bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4], + bool* ambiguous) { if (ambiguous) { *ambiguous = false; } @@ -1037,7 +968,9 @@ bool SkXRayCrossesMonotonicCubic(const SkXRay& pt, const SkPoint cubic[4], bool* return false; } -int SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4], bool* ambiguous) { +int SkNumXRayCrossingsForCubic(const SkXRay& pt, + const SkPoint cubic[4], + bool* ambiguous) { int num_crossings = 0; SkPoint monotonic_cubics[10]; int num_monotonic_cubics = SkChopCubicAtYExtrema(cubic, monotonic_cubics); @@ -1045,32 +978,38 @@ int SkNumXRayCrossingsForCubic(const SkXRay& pt, const SkPoint cubic[4], bool* a *ambiguous = false; } bool locally_ambiguous; - if (SkXRayCrossesMonotonicCubic(pt, &monotonic_cubics[0], &locally_ambiguous)) + if (SkXRayCrossesMonotonicCubic(pt, + &monotonic_cubics[0], + &locally_ambiguous)) ++num_crossings; if (ambiguous) { *ambiguous |= locally_ambiguous; } if (num_monotonic_cubics > 0) - if (SkXRayCrossesMonotonicCubic(pt, &monotonic_cubics[3], &locally_ambiguous)) + if (SkXRayCrossesMonotonicCubic(pt, + &monotonic_cubics[3], + &locally_ambiguous)) ++num_crossings; if (ambiguous) { *ambiguous |= locally_ambiguous; } if (num_monotonic_cubics > 1) - if (SkXRayCrossesMonotonicCubic(pt, &monotonic_cubics[6], &locally_ambiguous)) + if (SkXRayCrossesMonotonicCubic(pt, + &monotonic_cubics[6], + &locally_ambiguous)) ++num_crossings; if (ambiguous) { *ambiguous |= locally_ambiguous; } return num_crossings; } -//////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// /* Find t value for quadratic [a, b, c] = d. Return 0 if there is no solution within [0, 1) */ -static SkScalar quad_solve(SkScalar a, SkScalar b, SkScalar c, SkScalar d) -{ +static SkScalar quad_solve(SkScalar a, SkScalar b, SkScalar c, SkScalar d) { // At^2 + Bt + C = d SkScalar A = a - 2 * b + c; SkScalar B = 2 * (b - a); @@ -1088,8 +1027,8 @@ static SkScalar quad_solve(SkScalar a, SkScalar b, SkScalar c, SkScalar d) Should only return false if the computed pos is the start of the curve (i.e. root == 0) */ -static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y, SkPoint* dest) -{ +static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y, + SkPoint* dest) { const SkScalar* base; SkScalar value; @@ -1105,8 +1044,7 @@ static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y, S // root might return something outside of [0, 1) SkScalar t = quad_solve(base[0], base[2], base[4], value); - if (t > 0) - { + if (t > 0) { SkPoint tmp[5]; SkChopQuadAt(quad, tmp, t); dest[0] = tmp[1]; @@ -1138,9 +1076,10 @@ static bool truncate_last_curve(const SkPoint quad[3], SkScalar x, SkScalar y, S static const SkPoint gQuadCirclePts[kSkBuildQuadArcStorage] = { // The mid point of the quadratic arc approximation is half way between the two // control points. The float epsilon adjustment moves the on curve point out by -// two bits, distributing the convex test error between the round rect approximation -// and the convex cross product sign equality test. -#define SK_MID_RRECT_OFFSET (SK_Scalar1 + SK_ScalarTanPIOver8 + FLT_EPSILON * 4) / 2 +// two bits, distributing the convex test error between the round rect +// approximation and the convex cross product sign equality test. +#define SK_MID_RRECT_OFFSET \ + (SK_Scalar1 + SK_ScalarTanPIOver8 + FLT_EPSILON * 4) / 2 { SK_Scalar1, 0 }, { SK_Scalar1, SK_ScalarTanPIOver8 }, { SK_MID_RRECT_OFFSET, SK_MID_RRECT_OFFSET }, @@ -1167,8 +1106,7 @@ static const SkPoint gQuadCirclePts[kSkBuildQuadArcStorage] = { int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop, SkRotationDirection dir, const SkMatrix* userMatrix, - SkPoint quadPoints[]) -{ + SkPoint quadPoints[]) { // rotate by x,y so that uStart is (1.0) SkScalar x = SkPoint::DotProduct(uStart, uStop); SkScalar y = SkPoint::CrossProduct(uStart, uStop); @@ -1189,45 +1127,37 @@ int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop, quadPoints[0].set(SK_Scalar1, 0); pointCount = 1; } else { - if (dir == kCCW_SkRotationDirection) + if (dir == kCCW_SkRotationDirection) { y = -y; - + } // what octant (quadratic curve) is [xy] in? int oct = 0; bool sameSign = true; - if (0 == y) - { + if (0 == y) { oct = 4; // 180 SkASSERT(SkScalarAbs(x + SK_Scalar1) <= SK_ScalarNearlyZero); - } - else if (0 == x) - { + } else if (0 == x) { SkASSERT(absY - SK_Scalar1 <= SK_ScalarNearlyZero); - if (y > 0) - oct = 2; // 90 - else - oct = 6; // 270 - } - else - { - if (y < 0) + oct = y > 0 ? 2 : 6; // 90 : 270 + } else { + if (y < 0) { oct += 4; - if ((x < 0) != (y < 0)) - { + } + if ((x < 0) != (y < 0)) { oct += 2; sameSign = false; } - if ((absX < absY) == sameSign) + if ((absX < absY) == sameSign) { oct += 1; + } } int wholeCount = oct << 1; memcpy(quadPoints, gQuadCirclePts, (wholeCount + 1) * sizeof(SkPoint)); const SkPoint* arc = &gQuadCirclePts[wholeCount]; - if (truncate_last_curve(arc, x, y, &quadPoints[wholeCount + 1])) - { + if (truncate_last_curve(arc, x, y, &quadPoints[wholeCount + 1])) { wholeCount += 2; } pointCount = wholeCount + 1; @@ -1246,8 +1176,16 @@ int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop, return pointCount; } -/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// +// NURB representation for conics. Helpful explanations at: +// +// http://citeseerx.ist.psu.edu/viewdoc/ +// download?doi=10.1.1.44.5740&rep=rep1&type=ps +// and +// http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/NURBS/RB-conics.html +// // F = (A (1 - t)^2 + C t^2 + 2 B (1 - t) t w) // ------------------------------------------ // ((1 - t)^2 + t^2 + 2 (1 - t) t w) @@ -1257,12 +1195,6 @@ int SkBuildQuadArc(const SkVector& uStart, const SkVector& uStop, // {t^2 (2 - 2 w), t (-2 + 2 w), 1} // -// Take the parametric specification for the conic (either X or Y) and return -// in coeff[] the coefficients for the simple quadratic polynomial -// coeff[0] for t^2 -// coeff[1] for t -// coeff[2] for constant term -// static SkScalar conic_eval_pos(const SkScalar src[], SkScalar w, SkScalar t) { SkASSERT(src); SkASSERT(t >= 0 && t <= SK_Scalar1); @@ -1294,7 +1226,9 @@ static SkScalar conic_eval_pos(const SkScalar src[], SkScalar w, SkScalar t) { // coeff[1] for t^1 // coeff[2] for t^0 // -static void conic_deriv_coeff(const SkScalar src[], SkScalar w, SkScalar coeff[3]) { +static void conic_deriv_coeff(const SkScalar src[], + SkScalar w, + SkScalar coeff[3]) { const SkScalar P20 = src[4] - src[0]; const SkScalar P10 = src[2] - src[0]; const SkScalar wP10 = w * P10; @@ -1384,7 +1318,8 @@ void SkConic::chopAt(SkScalar t, SkConic dst[2]) const { // or // w1 /= sqrt(w0*w2) // - // However, in our case, we know that for dst[0], w0 == 1, and for dst[1], w2 == 1 + // However, in our case, we know that for dst[0]: + // w0 == 1, and for dst[1], w2 == 1 // SkScalar root = SkScalarSqrt(tmp2[1].fZ); dst[0].fW = tmp2[0].fZ / root; @@ -1526,3 +1461,8 @@ void SkConic::computeTightBounds(SkRect* bounds) const { void SkConic::computeFastBounds(SkRect* bounds) const { bounds->set(fPts, 3); } + +bool SkConic::findMaxCurvature(SkScalar* t) const { + // TODO: Implement me + return false; +} diff --git a/gfx/skia/trunk/src/core/SkImageFilter.cpp b/gfx/skia/trunk/src/core/SkImageFilter.cpp index cd7c01b4e67e..2be66e787c5c 100644 --- a/gfx/skia/trunk/src/core/SkImageFilter.cpp +++ b/gfx/skia/trunk/src/core/SkImageFilter.cpp @@ -8,14 +8,15 @@ #include "SkImageFilter.h" #include "SkBitmap.h" +#include "SkDevice.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" #include "SkRect.h" #include "SkValidationUtils.h" #if SK_SUPPORT_GPU #include "GrContext.h" -#include "GrTexture.h" -#include "SkImageFilterUtils.h" +#include "SkGrPixelRef.h" +#include "SkGr.h" #endif SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropRect* cropRect) @@ -93,7 +94,7 @@ void SkImageFilter::flatten(SkWriteBuffer& buffer) const { } bool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& context, SkBitmap* result, SkIPoint* offset) const { SkASSERT(result); SkASSERT(offset); @@ -101,8 +102,8 @@ bool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src, * Give the proxy first shot at the filter. If it returns false, ask * the filter to do it. */ - return (proxy && proxy->filterImage(this, src, ctm, result, offset)) || - this->onFilterImage(proxy, src, ctm, result, offset); + return (proxy && proxy->filterImage(this, src, context, result, offset)) || + this->onFilterImage(proxy, src, context, result, offset); } bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, @@ -134,7 +135,7 @@ void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { } } -bool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&, +bool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const Context&, SkBitmap*, SkIPoint*) const { return false; } @@ -143,20 +144,19 @@ bool SkImageFilter::canFilterImageGPU() const { return this->asNewEffect(NULL, NULL, SkMatrix::I(), SkIRect()); } -bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, +bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { #if SK_SUPPORT_GPU - SkBitmap input; + SkBitmap input = src; SkASSERT(fInputCount == 1); SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (!SkImageFilterUtils::GetInputResultGPU(this->getInput(0), proxy, src, ctm, &input, &srcOffset)) { + if (this->getInput(0) && + !this->getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { return false; } GrTexture* srcTexture = input.getTexture(); SkIRect bounds; - src.getBounds(&bounds); - bounds.offset(srcOffset); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { return false; } SkRect srcRect = SkRect::Make(bounds); @@ -178,7 +178,7 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMa offset->fX = bounds.left(); offset->fY = bounds.top(); bounds.offset(-srcOffset); - SkMatrix matrix(ctm); + SkMatrix matrix(ctx.ctm()); matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); this->asNewEffect(&effect, srcTexture, matrix, bounds); SkASSERT(effect); @@ -188,25 +188,67 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMa context->drawRectToRect(paint, dstRect, srcRect); SkAutoTUnref resultTex(dst.detach()); - SkImageFilterUtils::WrapTexture(resultTex, bounds.width(), bounds.height(), result); + WrapTexture(resultTex, bounds.width(), bounds.height(), result); return true; #else return false; #endif } -bool SkImageFilter::applyCropRect(SkIRect* rect, const SkMatrix& matrix) const { +bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src, + const SkIPoint& srcOffset, SkIRect* bounds) const { + SkIRect srcBounds; + src.getBounds(&srcBounds); + srcBounds.offset(srcOffset); SkRect cropRect; - matrix.mapRect(&cropRect, fCropRect.rect()); + ctx.ctm().mapRect(&cropRect, fCropRect.rect()); SkIRect cropRectI; cropRect.roundOut(&cropRectI); uint32_t flags = fCropRect.flags(); - // If the original crop rect edges were unset, max out the new crop edges - if (!(flags & CropRect::kHasLeft_CropEdge)) cropRectI.fLeft = SK_MinS32; - if (!(flags & CropRect::kHasTop_CropEdge)) cropRectI.fTop = SK_MinS32; - if (!(flags & CropRect::kHasRight_CropEdge)) cropRectI.fRight = SK_MaxS32; - if (!(flags & CropRect::kHasBottom_CropEdge)) cropRectI.fBottom = SK_MaxS32; - return rect->intersect(cropRectI); + if (flags & CropRect::kHasLeft_CropEdge) srcBounds.fLeft = cropRectI.fLeft; + if (flags & CropRect::kHasTop_CropEdge) srcBounds.fTop = cropRectI.fTop; + if (flags & CropRect::kHasRight_CropEdge) srcBounds.fRight = cropRectI.fRight; + if (flags & CropRect::kHasBottom_CropEdge) srcBounds.fBottom = cropRectI.fBottom; + if (!srcBounds.intersect(ctx.clipBounds())) { + return false; + } + *bounds = srcBounds; + return true; +} + +bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src, + SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* dst) const { + SkIRect srcBounds; + src.getBounds(&srcBounds); + srcBounds.offset(*srcOffset); + SkRect cropRect; + ctx.ctm().mapRect(&cropRect, fCropRect.rect()); + SkIRect cropRectI; + cropRect.roundOut(&cropRectI); + uint32_t flags = fCropRect.flags(); + *bounds = srcBounds; + if (flags & CropRect::kHasLeft_CropEdge) bounds->fLeft = cropRectI.fLeft; + if (flags & CropRect::kHasTop_CropEdge) bounds->fTop = cropRectI.fTop; + if (flags & CropRect::kHasRight_CropEdge) bounds->fRight = cropRectI.fRight; + if (flags & CropRect::kHasBottom_CropEdge) bounds->fBottom = cropRectI.fBottom; + if (!bounds->intersect(ctx.clipBounds())) { + return false; + } + if (srcBounds.contains(*bounds)) { + *dst = src; + return true; + } else { + SkAutoTUnref device(proxy->createDevice(bounds->width(), bounds->height())); + if (!device) { + return false; + } + SkCanvas canvas(device); + canvas.clear(0x00000000); + canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y()); + *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); + *dst = device->accessBitmap(false); + return true; + } } bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, @@ -242,3 +284,40 @@ bool SkImageFilter::asNewEffect(GrEffectRef**, GrTexture*, const SkMatrix&, cons bool SkImageFilter::asColorFilter(SkColorFilter**) const { return false; } + +#if SK_SUPPORT_GPU + +void SkImageFilter::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) { + SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); + result->setConfig(info); + result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); +} + +bool SkImageFilter::getInputResultGPU(SkImageFilter::Proxy* proxy, + const SkBitmap& src, const Context& ctx, + SkBitmap* result, SkIPoint* offset) const { + // Ensure that GrContext calls under filterImage and filterImageGPU below will see an identity + // matrix with no clip and that the matrix, clip, and render target set before this function was + // called are restored before we return to the caller. + GrContext* context = src.getTexture()->getContext(); + GrContext::AutoWideOpenIdentityDraw awoid(context, NULL); + if (this->canFilterImageGPU()) { + return this->filterImageGPU(proxy, src, ctx, result, offset); + } else { + if (this->filterImage(proxy, src, ctx, result, offset)) { + if (!result->getTexture()) { + SkImageInfo info; + if (!result->asImageInfo(&info)) { + return false; + } + GrTexture* resultTex = GrLockAndRefCachedBitmapTexture(context, *result, NULL); + result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref(); + GrUnlockAndUnrefCachedBitmapTexture(resultTex); + } + return true; + } else { + return false; + } + } +} +#endif diff --git a/gfx/skia/trunk/src/core/SkImageFilterUtils.cpp b/gfx/skia/trunk/src/core/SkImageFilterUtils.cpp deleted file mode 100644 index c6c534e71dfc..000000000000 --- a/gfx/skia/trunk/src/core/SkImageFilterUtils.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2013 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. - */ - -#include "SkMatrix.h" - -#if SK_SUPPORT_GPU -#include "GrTexture.h" -#include "SkImageFilterUtils.h" -#include "SkBitmap.h" -#include "SkGrPixelRef.h" -#include "SkGr.h" - -bool SkImageFilterUtils::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) { - SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); - result->setConfig(info); - result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref(); - return true; -} - -bool SkImageFilterUtils::GetInputResultGPU(const SkImageFilter* filter, SkImageFilter::Proxy* proxy, - const SkBitmap& src, const SkMatrix& ctm, - SkBitmap* result, SkIPoint* offset) { - // Ensure that GrContext calls under filterImage and filterImageGPU below will see an identity - // matrix with no clip and that the matrix, clip, and render target set before this function was - // called are restored before we return to the caller. - GrContext* context = src.getTexture()->getContext(); - GrContext::AutoWideOpenIdentityDraw awoid(context, NULL); - if (!filter) { - offset->fX = offset->fY = 0; - *result = src; - return true; - } else if (filter->canFilterImageGPU()) { - return filter->filterImageGPU(proxy, src, ctm, result, offset); - } else { - if (filter->filterImage(proxy, src, ctm, result, offset)) { - if (!result->getTexture()) { - SkImageInfo info; - if (!result->asImageInfo(&info)) { - return false; - } - GrTexture* resultTex = GrLockAndRefCachedBitmapTexture(context, *result, NULL); - result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref(); - GrUnlockAndUnrefCachedBitmapTexture(resultTex); - } - return true; - } else { - return false; - } - } -} -#endif diff --git a/gfx/skia/trunk/src/core/SkMaskFilter.cpp b/gfx/skia/trunk/src/core/SkMaskFilter.cpp index b96743d12953..9b023d0d65cb 100644 --- a/gfx/skia/trunk/src/core/SkMaskFilter.cpp +++ b/gfx/skia/trunk/src/core/SkMaskFilter.cpp @@ -317,6 +317,13 @@ bool SkMaskFilter::canFilterMaskGPU(const SkRect& devBounds, } +bool SkMaskFilter::directFilterRRectMaskGPU(GrContext* context, + GrPaint* grp, + const SkStrokeRec& strokeRec, + const SkRRect& rrect) const { + return false; +} + bool SkMaskFilter::filterMaskGPU(GrTexture* src, const SkMatrix& ctm, const SkRect& maskRect, diff --git a/gfx/skia/trunk/src/core/SkMatrix.cpp b/gfx/skia/trunk/src/core/SkMatrix.cpp index 33af64a41fe9..a34866f003b6 100644 --- a/gfx/skia/trunk/src/core/SkMatrix.cpp +++ b/gfx/skia/trunk/src/core/SkMatrix.cpp @@ -1598,7 +1598,9 @@ void SkMatrix::dump() const { this->toString(&str); SkDebugf("%s\n", str.c_str()); } +#endif +#ifndef SK_IGNORE_TO_STRING void SkMatrix::toString(SkString* str) const { str->appendf("[%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f][%8.4f %8.4f %8.4f]", fMat[0], fMat[1], fMat[2], fMat[3], fMat[4], fMat[5], diff --git a/gfx/skia/trunk/src/core/SkMatrixClipStateMgr.cpp b/gfx/skia/trunk/src/core/SkMatrixClipStateMgr.cpp index 4cf99bca97cd..5f2103054ffd 100644 --- a/gfx/skia/trunk/src/core/SkMatrixClipStateMgr.cpp +++ b/gfx/skia/trunk/src/core/SkMatrixClipStateMgr.cpp @@ -21,7 +21,6 @@ bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipPath(SkPictureRecord* newClip->fOp = op; newClip->fDoAA = doAA; newClip->fMatrixID = matrixID; - newClip->fOffset = kInvalidJumpOffset; return false; } @@ -29,14 +28,12 @@ bool SkMatrixClipStateMgr::MatrixClipState::ClipInfo::clipRegion(SkPictureRecord int regionID, SkRegion::Op op, int matrixID) { - // TODO: add a region dictionary so we don't have to copy the region in here ClipOp* newClip = fClips.append(); newClip->fClipType = kRegion_ClipType; newClip->fGeom.fRegionID = regionID; newClip->fOp = op; newClip->fDoAA = true; // not necessary but sanity preserving newClip->fMatrixID = matrixID; - newClip->fOffset = kInvalidJumpOffset; return false; } @@ -55,17 +52,10 @@ void SkMatrixClipStateMgr::writeDeltaMat(int currentMatID, int desiredMatID) { // Note: this only writes out the clips for the current save state. To get the // entire clip stack requires iterating of the entire matrix/clip stack. void SkMatrixClipStateMgr::MatrixClipState::ClipInfo::writeClip(int* curMatID, - SkMatrixClipStateMgr* mgr, - bool* overrideFirstOp) { + SkMatrixClipStateMgr* mgr) { for (int i = 0; i < fClips.count(); ++i) { ClipOp& curClip = fClips[i]; - SkRegion::Op op = curClip.fOp; - if (*overrideFirstOp) { - op = SkRegion::kReplace_Op; - *overrideFirstOp = false; - } - // TODO: use the matrix ID to skip writing the identity matrix // over and over, i.e.: // if (*curMatID != curClip.fMatrixID) { @@ -79,43 +69,31 @@ void SkMatrixClipStateMgr::MatrixClipState::ClipInfo::writeClip(int* curMatID, mgr->writeDeltaMat(*curMatID, curClip.fMatrixID); *curMatID = curClip.fMatrixID; + int offset = 0; + switch (curClip.fClipType) { case kRect_ClipType: - curClip.fOffset = mgr->getPicRecord()->recordClipRect(curClip.fGeom.fRRect.rect(), - op, curClip.fDoAA); + offset = mgr->getPicRecord()->recordClipRect(curClip.fGeom.fRRect.rect(), + curClip.fOp, curClip.fDoAA); break; case kRRect_ClipType: - curClip.fOffset = mgr->getPicRecord()->recordClipRRect(curClip.fGeom.fRRect, op, - curClip.fDoAA); + offset = mgr->getPicRecord()->recordClipRRect(curClip.fGeom.fRRect, curClip.fOp, + curClip.fDoAA); break; case kPath_ClipType: - curClip.fOffset = mgr->getPicRecord()->recordClipPath(curClip.fGeom.fPathID, op, - curClip.fDoAA); + offset = mgr->getPicRecord()->recordClipPath(curClip.fGeom.fPathID, curClip.fOp, + curClip.fDoAA); break; case kRegion_ClipType: { const SkRegion* region = mgr->lookupRegion(curClip.fGeom.fRegionID); - curClip.fOffset = mgr->getPicRecord()->recordClipRegion(*region, op); + offset = mgr->getPicRecord()->recordClipRegion(*region, curClip.fOp); break; } default: SkASSERT(0); } - } -} -// Fill in the skip offsets for all the clips written in the current block -void SkMatrixClipStateMgr::MatrixClipState::ClipInfo::fillInSkips(SkWriter32* writer, - int32_t restoreOffset) { - for (int i = 0; i < fClips.count(); ++i) { - ClipOp& curClip = fClips[i]; - - if (-1 == curClip.fOffset) { - continue; - } -// SkDEBUGCODE(uint32_t peek = writer->read32At(curClip.fOffset);) -// SkASSERT(-1 == peek); - writer->overwriteTAt(curClip.fOffset, restoreOffset); - SkDEBUGCODE(curClip.fOffset = -1;) + mgr->addClipOffset(offset); } } @@ -126,23 +104,29 @@ SkMatrixClipStateMgr::SkMatrixClipStateMgr() sizeof(fMatrixClipStackStorage)) , fCurOpenStateID(kIdentityWideOpenStateID) { + fSkipOffsets = SkNEW(SkTDArray); + // The first slot in the matrix dictionary is reserved for the identity matrix fMatrixDict.append()->reset(); fCurMCState = (MatrixClipState*)fMatrixClipStack.push_back(); new (fCurMCState) MatrixClipState(NULL, 0); // balanced in restore() + +#ifdef SK_DEBUG + fActualDepth = 0; +#endif } SkMatrixClipStateMgr::~SkMatrixClipStateMgr() { for (int i = 0; i < fRegionDict.count(); ++i) { SkDELETE(fRegionDict[i]); } + + SkDELETE(fSkipOffsets); } -int SkMatrixClipStateMgr::save(SkCanvas::SaveFlags flags) { - SkDEBUGCODE(this->validate();) - +int SkMatrixClipStateMgr::MCStackPush(SkCanvas::SaveFlags flags) { MatrixClipState* newTop = (MatrixClipState*)fMatrixClipStack.push_back(); new (newTop) MatrixClipState(fCurMCState, flags); // balanced in restore() fCurMCState = newTop; @@ -152,16 +136,47 @@ int SkMatrixClipStateMgr::save(SkCanvas::SaveFlags flags) { return fMatrixClipStack.count(); } +int SkMatrixClipStateMgr::save(SkCanvas::SaveFlags flags) { + SkDEBUGCODE(this->validate();) + + return this->MCStackPush(flags); +} + int SkMatrixClipStateMgr::saveLayer(const SkRect* bounds, const SkPaint* paint, SkCanvas::SaveFlags flags) { - int result = this->save(flags); +#ifdef SK_DEBUG + if (fCurMCState->fIsSaveLayer) { + SkASSERT(0 == fSkipOffsets->count()); + } +#endif + + // Since the saveLayer call draws something we need to potentially dump + // out the MC state + SkDEBUGCODE(bool saved =) this->call(kOther_CallType); + + int result = this->MCStackPush(flags); ++fCurMCState->fLayerID; fCurMCState->fIsSaveLayer = true; - fCurMCState->fSaveLayerBracketed = this->call(kOther_CallType); - fCurMCState->fSaveLayerBaseStateID = fCurOpenStateID; +#ifdef SK_DEBUG + if (saved) { + fCurMCState->fExpectedDepth++; // 1 for nesting save + } + fCurMCState->fExpectedDepth++; // 1 for saveLayer +#endif + + *fStateIDStack.append() = fCurOpenStateID; + fCurMCState->fSavedSkipOffsets = fSkipOffsets; + + // TODO: recycle these rather then new & deleting them on every saveLayer/ + // restore + fSkipOffsets = SkNEW(SkTDArray); + fPicRecord->recordSaveLayer(bounds, paint, (SkCanvas::SaveFlags)(flags| SkCanvas::kMatrixClip_SaveFlag)); +#ifdef SK_DEBUG + fActualDepth++; +#endif return result; } @@ -169,28 +184,54 @@ void SkMatrixClipStateMgr::restore() { SkDEBUGCODE(this->validate();) if (fCurMCState->fIsSaveLayer) { - if (fCurMCState->fSaveLayerBaseStateID != fCurOpenStateID) { - fPicRecord->recordRestore(); // Close the open block + if (fCurMCState->fHasOpen) { + fCurMCState->fHasOpen = false; + fPicRecord->recordRestore(); // Close the open block inside the saveLayer +#ifdef SK_DEBUG + SkASSERT(fActualDepth > 0); + fActualDepth--; +#endif + } else { + SkASSERT(0 == fSkipOffsets->count()); } + // The saveLayer's don't carry any matrix or clip state in the // new scheme so make sure the saveLayer's recordRestore doesn't // try to finalize them (i.e., fill in their skip offsets). fPicRecord->recordRestore(false); // close of saveLayer +#ifdef SK_DEBUG + SkASSERT(fActualDepth > 0); + fActualDepth--; +#endif - // Close the Save that brackets the saveLayer. TODO: this doesn't handle - // the skip offsets correctly - if (fCurMCState->fSaveLayerBracketed) { - fPicRecord->recordRestore(false); - } + SkASSERT(fStateIDStack.count() >= 1); + fCurOpenStateID = fStateIDStack[fStateIDStack.count()-1]; + fStateIDStack.pop(); - // MC states can be allowed to fuse across saveLayer/restore boundaries - fCurOpenStateID = kIdentityWideOpenStateID; + SkASSERT(0 == fSkipOffsets->count()); + SkASSERT(NULL != fCurMCState->fSavedSkipOffsets); + + SkDELETE(fSkipOffsets); + fSkipOffsets = fCurMCState->fSavedSkipOffsets; } + bool prevHadOpen = fCurMCState->fHasOpen; + bool prevWasSaveLayer = fCurMCState->fIsSaveLayer; + fCurMCState->~MatrixClipState(); // balanced in save() fMatrixClipStack.pop_back(); fCurMCState = (MatrixClipState*)fMatrixClipStack.back(); + if (!prevWasSaveLayer) { + fCurMCState->fHasOpen = prevHadOpen; + } + + if (fCurMCState->fIsSaveLayer) { + if (0 != fSkipOffsets->count()) { + SkASSERT(fCurMCState->fHasOpen); + } + } + SkDEBUGCODE(this->validate();) } @@ -203,6 +244,10 @@ int32_t SkMatrixClipStateMgr::NewMCStateID() { return gMCStateID; } +bool SkMatrixClipStateMgr::isNestingMCState(int stateID) { + return fStateIDStack.count() > 0 && fStateIDStack[fStateIDStack.count()-1] == fCurOpenStateID; +} + bool SkMatrixClipStateMgr::call(CallType callType) { SkDEBUGCODE(this->validate();) @@ -220,27 +265,86 @@ bool SkMatrixClipStateMgr::call(CallType callType) { return false; } - if (kIdentityWideOpenStateID != fCurOpenStateID) { + if (kIdentityWideOpenStateID != fCurOpenStateID && + !this->isNestingMCState(fCurOpenStateID)) { + // Don't write a restore if the open state is one in which a saveLayer + // is nested. The save after the saveLayer's restore will close it. fPicRecord->recordRestore(); // Close the open block + fCurMCState->fHasOpen = false; +#ifdef SK_DEBUG + SkASSERT(fActualDepth > 0); + fActualDepth--; +#endif } // Install the required MC state as the active one fCurOpenStateID = fCurMCState->fMCStateID; + if (kIdentityWideOpenStateID == fCurOpenStateID) { + SkASSERT(0 == fActualDepth); + SkASSERT(!fCurMCState->fHasOpen); + SkASSERT(0 == fSkipOffsets->count()); + return false; + } + + SkASSERT(!fCurMCState->fHasOpen); + SkASSERT(0 == fSkipOffsets->count()); + fCurMCState->fHasOpen = true; fPicRecord->recordSave(SkCanvas::kMatrixClip_SaveFlag); +#ifdef SK_DEBUG + fActualDepth++; + SkASSERT(fActualDepth == fCurMCState->fExpectedDepth); +#endif // write out clips - SkDeque::F2BIter iter(fMatrixClipStack); - bool firstClip = true; - - int curMatID = kIdentityMatID; - for (const MatrixClipState* state = (const MatrixClipState*) iter.next(); + SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart); + const MatrixClipState* state; + // Loop back across the MC states until the last saveLayer. The MC + // state in front of the saveLayer has already been written out. + for (state = (const MatrixClipState*) iter.prev(); state != NULL; - state = (const MatrixClipState*) iter.next()) { - state->fClipInfo->writeClip(&curMatID, this, &firstClip); + state = (const MatrixClipState*) iter.prev()) { + if (state->fIsSaveLayer) { + break; + } + } + + int curMatID; + + if (NULL == state) { + // There was no saveLayer in the MC stack so we need to output them all + iter.reset(fMatrixClipStack, SkDeque::Iter::kFront_IterStart); + state = (const MatrixClipState*) iter.next(); + curMatID = kIdentityMatID; + } else { + // SkDeque's iterators actually return the previous location so we + // need to reverse and go forward one to get back on track. + iter.next(); + SkDEBUGCODE(const MatrixClipState* test = (const MatrixClipState*)) iter.next(); + SkASSERT(test == state); + + curMatID = state->fMatrixInfo->getID(this); + + // TODO: this assumes that, in the case of Save|SaveLayer when the SaveLayer + // doesn't save the clip, that the SaveLayer doesn't add any additional clip state. + // This assumption will be removed when we explicitly store the clip state in + // self-contained objects. It is valid for the small set of skps. + if (NULL != state->fPrev && state->fClipInfo == state->fPrev->fClipInfo) { + // By the above assumption the SaveLayer's MC state has already been + // written out by the prior Save so don't output it again. + state = (const MatrixClipState*) iter.next(); + } + } + + for ( ; state != NULL; state = (const MatrixClipState*) iter.next()) { + state->fClipInfo->writeClip(&curMatID, this); } // write out matrix + // TODO: this test isn't quite right. It should be: + // if (curMatID != fCurMCState->fMatrixInfo->getID(this)) { + // but right now the testing harness always expects a matrix if + // the matrices are non-I if (kIdentityMatID != fCurMCState->fMatrixInfo->getID(this)) { // TODO: writing out the delta matrix here is an artifact of the writing // out of the entire clip stack (with its matrices). Ultimately we will @@ -249,29 +353,53 @@ bool SkMatrixClipStateMgr::call(CallType callType) { } SkDEBUGCODE(this->validate();) - return true; } +// Fill in the skip offsets for all the clips written in the current block +void SkMatrixClipStateMgr::fillInSkips(SkWriter32* writer, int32_t restoreOffset) { + for (int i = 0; i < fSkipOffsets->count(); ++i) { + SkDEBUGCODE(int32_t peek = writer->readTAt((*fSkipOffsets)[i]);) + SkASSERT(-1 == peek); + writer->overwriteTAt((*fSkipOffsets)[i], restoreOffset); + } + + fSkipOffsets->rewind(); + SkASSERT(0 == fSkipOffsets->count()); +} + void SkMatrixClipStateMgr::finish() { if (kIdentityWideOpenStateID != fCurOpenStateID) { fPicRecord->recordRestore(); // Close the open block + fCurMCState->fHasOpen = false; +#ifdef SK_DEBUG + SkASSERT(fActualDepth > 0); + fActualDepth--; +#endif fCurOpenStateID = kIdentityWideOpenStateID; + SkASSERT(!fCurMCState->fHasOpen); } } #ifdef SK_DEBUG void SkMatrixClipStateMgr::validate() { - if (fCurOpenStateID == fCurMCState->fMCStateID) { - // The current state is the active one so all its skip offsets should - // still be -1 - SkDeque::F2BIter iter(fMatrixClipStack); - - for (const MatrixClipState* state = (const MatrixClipState*) iter.next(); + if (fCurOpenStateID == fCurMCState->fMCStateID && !this->isNestingMCState(fCurOpenStateID)) { + // The current state is the active one so it should have a skip + // offset for each clip + SkDeque::Iter iter(fMatrixClipStack, SkDeque::Iter::kBack_IterStart); + int clipCount = 0; + for (const MatrixClipState* state = (const MatrixClipState*) iter.prev(); state != NULL; - state = (const MatrixClipState*) iter.next()) { - state->fClipInfo->checkOffsetNotEqual(-1); + state = (const MatrixClipState*) iter.prev()) { + if (NULL == state->fPrev || state->fPrev->fClipInfo != state->fClipInfo) { + clipCount += state->fClipInfo->numClips(); + } + if (state->fIsSaveLayer) { + break; + } } + + SkASSERT(fSkipOffsets->count() == clipCount); } } #endif diff --git a/gfx/skia/trunk/src/core/SkMatrixClipStateMgr.h b/gfx/skia/trunk/src/core/SkMatrixClipStateMgr.h index 60f9fa001679..c4201f86edd5 100644 --- a/gfx/skia/trunk/src/core/SkMatrixClipStateMgr.h +++ b/gfx/skia/trunk/src/core/SkMatrixClipStateMgr.h @@ -53,7 +53,7 @@ public: static const int32_t kIdentityWideOpenStateID = 0; static const int kIdentityMatID = 0; - class MatrixClipState { + class MatrixClipState : public SkNoncopyable { public: class MatrixInfo { public: @@ -104,6 +104,8 @@ public: private: SkMatrix fMatrix; int fMatrixID; + + typedef SkNoncopyable INHERITED; }; class ClipInfo : public SkNoncopyable { @@ -120,7 +122,6 @@ public: newClip->fOp = op; newClip->fDoAA = doAA; newClip->fMatrixID = matrixID; - newClip->fOffset = kInvalidJumpOffset; return false; } @@ -134,7 +135,6 @@ public: newClip->fOp = op; newClip->fDoAA = doAA; newClip->fMatrixID = matrixID; - newClip->fOffset = kInvalidJumpOffset; return false; } @@ -147,19 +147,10 @@ public: int regionID, SkRegion::Op op, int matrixID); - void writeClip(int* curMatID, - SkMatrixClipStateMgr* mgr, - bool* overrideFirstOp); - void fillInSkips(SkWriter32* writer, int32_t restoreOffset); + void writeClip(int* curMatID, SkMatrixClipStateMgr* mgr); + + SkDEBUGCODE(int numClips() const { return fClips.count(); }) -#ifdef SK_DEBUG - void checkOffsetNotEqual(int32_t offset) { - for (int i = 0; i < fClips.count(); ++i) { - ClipOp& curClip = fClips[i]; - SkASSERT(offset != curClip.fOffset); - } - } -#endif private: enum ClipType { kRect_ClipType, @@ -168,14 +159,12 @@ public: kRegion_ClipType }; - static const int kInvalidJumpOffset = -1; - class ClipOp { public: ClipType fClipType; union { - SkRRect fRRect; // also stores clipRect + SkRRect fRRect; // also stores clip rect int fPathID; int fRegionID; } fGeom; @@ -185,10 +174,6 @@ public: // The CTM in effect when this clip call was issued int fMatrixID; - - // The offset of this clipOp's "jump-to-offset" location in the skp. - // -1 means the offset hasn't been written. - int32_t fOffset; }; SkTDArray fClips; @@ -197,10 +182,10 @@ public: }; MatrixClipState(MatrixClipState* prev, int flags) -#ifdef SK_DEBUG : fPrev(prev) -#endif { + fHasOpen = false; + if (NULL == prev) { fLayerID = 0; @@ -210,6 +195,9 @@ public: // The identity/wide-open-clip state is current by default fMCStateID = kIdentityWideOpenStateID; +#ifdef SK_DEBUG + fExpectedDepth = 1; +#endif } else { fLayerID = prev->fLayerID; @@ -231,6 +219,9 @@ public: // Initially a new save/saveLayer represents the same MC state // as its predecessor. fMCStateID = prev->fMCStateID; +#ifdef SK_DEBUG + fExpectedDepth = prev->fExpectedDepth; +#endif } fIsSaveLayer = false; @@ -247,12 +238,16 @@ public: // Does this MC state represent a saveLayer call? bool fIsSaveLayer; - // The next two fields are only valid when fIsSaveLayer is set. - int32_t fSaveLayerBaseStateID; - bool fSaveLayerBracketed; + // The next field is only valid when fIsSaveLayer is set. + SkTDArray* fSavedSkipOffsets; + + // Does the MC state have an open block in the skp? + bool fHasOpen; + + MatrixClipState* fPrev; #ifdef SK_DEBUG - MatrixClipState* fPrev; // debugging aid + int fExpectedDepth; // debugging aid #endif int32_t fMCStateID; @@ -347,17 +342,7 @@ public: bool call(CallType callType); - void fillInSkips(SkWriter32* writer, int32_t restoreOffset) { - // Since we write out the entire clip stack at each block start we - // need to update the skips for the entire stack each time too. - SkDeque::F2BIter iter(fMatrixClipStack); - - for (const MatrixClipState* state = (const MatrixClipState*) iter.next(); - state != NULL; - state = (const MatrixClipState*) iter.next()) { - state->fClipInfo->fillInSkips(writer, restoreOffset); - } - } + void fillInSkips(SkWriter32* writer, int32_t restoreOffset); void finish(); @@ -379,9 +364,25 @@ protected: // The MCStateID of the state currently in effect in the byte stream. 0 if none. int32_t fCurOpenStateID; + // The skip offsets for the current open state. These are the locations in the + // skp that must be filled in when the current open state is closed. These are + // here rather then distributed across the MatrixClipState's because saveLayers + // can cause MC states to be nested. + SkTDArray *fSkipOffsets; SkDEBUGCODE(void validate();) + int MCStackPush(SkCanvas::SaveFlags flags); + + void addClipOffset(int offset) { + SkASSERT(NULL != fSkipOffsets); + SkASSERT(kIdentityWideOpenStateID != fCurOpenStateID); + SkASSERT(fCurMCState->fHasOpen); + SkASSERT(!fCurMCState->fIsSaveLayer); + + *fSkipOffsets->append() = offset; + } + void writeDeltaMat(int currentMatID, int desiredMatID); static int32_t NewMCStateID(); @@ -398,6 +399,16 @@ protected: SkASSERT(index >= 0 && index < fMatrixDict.count()); return fMatrixDict[index]; } + + bool isNestingMCState(int stateID); + +#ifdef SK_DEBUG + int fActualDepth; +#endif + + // save layers are nested within a specific MC state. This stack tracks + // the nesting MC state's ID as save layers are pushed and popped. + SkTDArray fStateIDStack; }; #endif diff --git a/gfx/skia/trunk/src/core/SkOffsetTable.h b/gfx/skia/trunk/src/core/SkOffsetTable.h new file mode 100644 index 000000000000..0596c38f83b4 --- /dev/null +++ b/gfx/skia/trunk/src/core/SkOffsetTable.h @@ -0,0 +1,115 @@ +/* + * 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 SkOffsetTable_DEFINED +#define SkOffsetTable_DEFINED + +#include "SkRefCnt.h" +#include "SkTDArray.h" + +// A 2D table of skp offsets. Each row is indexed by an int. This is used +// to store the command offsets that reference a particular bitmap using +// the bitmap's index in the bitmap heap as the 'id' here. It has to be +// ref-countable so SkPicturePlayback can take ownership of it. +// Note that this class assumes that the ids are densely packed. + +// TODO: This needs to be sped up. We could replace the offset table with +// a hash table. +class SkOffsetTable : public SkRefCnt { +public: + SkOffsetTable() {} + ~SkOffsetTable() { + fOffsetArrays.deleteAll(); + } + + // Record that this 'id' is used by the command starting at this 'offset'. + // Offsets for a given 'id' should always be added in increasing order. + void add(int id, size_t offset) { + if (id >= fOffsetArrays.count()) { + int oldCount = fOffsetArrays.count(); + fOffsetArrays.setCount(id+1); + for (int i = oldCount; i <= id; ++i) { + fOffsetArrays[i] = NULL; + } + } + + if (NULL == fOffsetArrays[id]) { + fOffsetArrays[id] = SkNEW(OffsetArray); + } + fOffsetArrays[id]->add(offset); + } + + int numIDs() const { + return fOffsetArrays.count(); + } + + // Do the offsets of any commands referencing this ID fall in the + // range [min, max] (both inclusive) + bool overlap(int id, size_t min, size_t max) { + SkASSERT(id < fOffsetArrays.count()); + + if (NULL == fOffsetArrays[id]) { + return false; + } + + // If this id has an offset array it should have at least one use + SkASSERT(fOffsetArrays[id]->count() > 0); + if (max < fOffsetArrays[id]->min() || min > fOffsetArrays[id]->max()) { + return false; + } + + return true; + } + + bool includes(int id, size_t offset) { + SkASSERT(id < fOffsetArrays.count()); + + OffsetArray* array = fOffsetArrays[id]; + + for (int i = 0; i < array->fOffsets.count(); ++i) { + if (array->fOffsets[i] == offset) { + return true; + } else if (array->fOffsets[i] > offset) { + return false; + } + } + + // Calls to 'includes' should be gaurded by an overlap() call, so we + // should always find something. + SkASSERT(0); + return false; + } + +protected: + class OffsetArray { + public: + void add(size_t offset) { + SkASSERT(fOffsets.count() == 0 || offset > this->max()); + *fOffsets.append() = offset; + } + size_t min() const { + SkASSERT(fOffsets.count() > 0); + return fOffsets[0]; + } + size_t max() const { + SkASSERT(fOffsets.count() > 0); + return fOffsets[fOffsets.count()-1]; + } + int count() const { + return fOffsets.count(); + } + + SkTDArray fOffsets; + }; + + SkTDArray fOffsetArrays; + +private: + typedef SkRefCnt INHERITED; +}; + +#endif diff --git a/gfx/skia/trunk/src/core/SkOrderedReadBuffer.cpp b/gfx/skia/trunk/src/core/SkOrderedReadBuffer.cpp deleted file mode 100644 index 31841182b9c4..000000000000 --- a/gfx/skia/trunk/src/core/SkOrderedReadBuffer.cpp +++ /dev/null @@ -1,317 +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. - */ - -#include "SkBitmap.h" -#include "SkErrorInternals.h" -#include "SkOrderedReadBuffer.h" -#include "SkStream.h" -#include "SkTypeface.h" - -SkOrderedReadBuffer::SkOrderedReadBuffer() : INHERITED() { - fMemoryPtr = NULL; - - fBitmapStorage = NULL; - fTFArray = NULL; - fTFCount = 0; - - fFactoryTDArray = NULL; - fFactoryArray = NULL; - fFactoryCount = 0; - fBitmapDecoder = NULL; -#ifdef DEBUG_NON_DETERMINISTIC_ASSERT - fDecodedBitmapIndex = -1; -#endif // DEBUG_NON_DETERMINISTIC_ASSERT -} - -SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size) : INHERITED() { - fReader.setMemory(data, size); - fMemoryPtr = NULL; - - fBitmapStorage = NULL; - fTFArray = NULL; - fTFCount = 0; - - fFactoryTDArray = NULL; - fFactoryArray = NULL; - fFactoryCount = 0; - fBitmapDecoder = NULL; -#ifdef DEBUG_NON_DETERMINISTIC_ASSERT - fDecodedBitmapIndex = -1; -#endif // DEBUG_NON_DETERMINISTIC_ASSERT -} - -SkOrderedReadBuffer::SkOrderedReadBuffer(SkStream* stream) { - const size_t length = stream->getLength(); - fMemoryPtr = sk_malloc_throw(length); - stream->read(fMemoryPtr, length); - fReader.setMemory(fMemoryPtr, length); - - fBitmapStorage = NULL; - fTFArray = NULL; - fTFCount = 0; - - fFactoryTDArray = NULL; - fFactoryArray = NULL; - fFactoryCount = 0; - fBitmapDecoder = NULL; -#ifdef DEBUG_NON_DETERMINISTIC_ASSERT - fDecodedBitmapIndex = -1; -#endif // DEBUG_NON_DETERMINISTIC_ASSERT -} - -SkOrderedReadBuffer::~SkOrderedReadBuffer() { - sk_free(fMemoryPtr); - SkSafeUnref(fBitmapStorage); -} - -bool SkOrderedReadBuffer::readBool() { - return fReader.readBool(); -} - -SkColor SkOrderedReadBuffer::readColor() { - return fReader.readInt(); -} - -SkFixed SkOrderedReadBuffer::readFixed() { - return fReader.readS32(); -} - -int32_t SkOrderedReadBuffer::readInt() { - return fReader.readInt(); -} - -SkScalar SkOrderedReadBuffer::readScalar() { - return fReader.readScalar(); -} - -uint32_t SkOrderedReadBuffer::readUInt() { - return fReader.readU32(); -} - -int32_t SkOrderedReadBuffer::read32() { - return fReader.readInt(); -} - -void SkOrderedReadBuffer::readString(SkString* string) { - size_t len; - const char* strContents = fReader.readString(&len); - string->set(strContents, len); -} - -void* SkOrderedReadBuffer::readEncodedString(size_t* length, SkPaint::TextEncoding encoding) { - SkDEBUGCODE(int32_t encodingType = ) fReader.readInt(); - SkASSERT(encodingType == encoding); - *length = fReader.readInt(); - void* data = sk_malloc_throw(*length); - memcpy(data, fReader.skip(SkAlign4(*length)), *length); - return data; -} - -void SkOrderedReadBuffer::readPoint(SkPoint* point) { - point->fX = fReader.readScalar(); - point->fY = fReader.readScalar(); -} - -void SkOrderedReadBuffer::readMatrix(SkMatrix* matrix) { - fReader.readMatrix(matrix); -} - -void SkOrderedReadBuffer::readIRect(SkIRect* rect) { - memcpy(rect, fReader.skip(sizeof(SkIRect)), sizeof(SkIRect)); -} - -void SkOrderedReadBuffer::readRect(SkRect* rect) { - memcpy(rect, fReader.skip(sizeof(SkRect)), sizeof(SkRect)); -} - -void SkOrderedReadBuffer::readRegion(SkRegion* region) { - fReader.readRegion(region); -} - -void SkOrderedReadBuffer::readPath(SkPath* path) { - fReader.readPath(path); -} - -bool SkOrderedReadBuffer::readArray(void* value, size_t size, size_t elementSize) { - const size_t count = this->getArrayCount(); - if (count == size) { - (void)fReader.skip(sizeof(uint32_t)); // Skip array count - const size_t byteLength = count * elementSize; - memcpy(value, fReader.skip(SkAlign4(byteLength)), byteLength); - return true; - } - SkASSERT(false); - fReader.skip(fReader.available()); - return false; -} - -bool SkOrderedReadBuffer::readByteArray(void* value, size_t size) { - return readArray(static_cast(value), size, sizeof(unsigned char)); -} - -bool SkOrderedReadBuffer::readColorArray(SkColor* colors, size_t size) { - return readArray(colors, size, sizeof(SkColor)); -} - -bool SkOrderedReadBuffer::readIntArray(int32_t* values, size_t size) { - return readArray(values, size, sizeof(int32_t)); -} - -bool SkOrderedReadBuffer::readPointArray(SkPoint* points, size_t size) { - return readArray(points, size, sizeof(SkPoint)); -} - -bool SkOrderedReadBuffer::readScalarArray(SkScalar* values, size_t size) { - return readArray(values, size, sizeof(SkScalar)); -} - -uint32_t SkOrderedReadBuffer::getArrayCount() { - return *(uint32_t*)fReader.peek(); -} - -void SkOrderedReadBuffer::readBitmap(SkBitmap* bitmap) { - const int width = this->readInt(); - const int height = this->readInt(); - // The writer stored a boolean value to determine whether an SkBitmapHeap was used during - // writing. - if (this->readBool()) { - // An SkBitmapHeap was used for writing. Read the index from the stream and find the - // corresponding SkBitmap in fBitmapStorage. - const uint32_t index = fReader.readU32(); - fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::writeBitmap) - if (fBitmapStorage) { - *bitmap = *fBitmapStorage->getBitmap(index); - fBitmapStorage->releaseRef(index); - return; - } else { - // The bitmap was stored in a heap, but there is no way to access it. Set an error and - // fall through to use a place holder bitmap. - SkErrorInternals::SetError(kParseError_SkError, "SkOrderedWriteBuffer::writeBitmap " - "stored the SkBitmap in an SkBitmapHeap, but " - "SkOrderedReadBuffer has no SkBitmapHeapReader to " - "retrieve the SkBitmap."); - } - } else { - // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap. - const size_t length = this->readUInt(); - if (length > 0) { -#ifdef DEBUG_NON_DETERMINISTIC_ASSERT - fDecodedBitmapIndex++; -#endif // DEBUG_NON_DETERMINISTIC_ASSERT - // A non-zero size means the SkBitmap was encoded. Read the data and pixel - // offset. - const void* data = this->skip(length); - const int32_t xOffset = fReader.readS32(); - const int32_t yOffset = fReader.readS32(); - if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap)) { - if (bitmap->width() == width && bitmap->height() == height) { -#ifdef DEBUG_NON_DETERMINISTIC_ASSERT - if (0 != xOffset || 0 != yOffset) { - SkDebugf("SkOrderedReadBuffer::readBitmap: heights match," - " but offset is not zero. \nInfo about the bitmap:" - "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncoded" - " data size: %d\n\tOffset: (%d, %d)\n", - fDecodedBitmapIndex, width, height, length, xOffset, - yOffset); - } -#endif // DEBUG_NON_DETERMINISTIC_ASSERT - // If the width and height match, there should be no offset. - SkASSERT(0 == xOffset && 0 == yOffset); - return; - } - - // This case can only be reached if extractSubset was called, so - // the recorded width and height must be smaller than (or equal to - // the encoded width and height. - SkASSERT(width <= bitmap->width() && height <= bitmap->height()); - - SkBitmap subsetBm; - SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height); - if (bitmap->extractSubset(&subsetBm, subset)) { - bitmap->swap(subsetBm); - return; - } - } - // This bitmap was encoded when written, but we are unable to decode, possibly due to - // not having a decoder. - SkErrorInternals::SetError(kParseError_SkError, - "Could not decode bitmap. Resulting bitmap will be red."); - } else { - // A size of zero means the SkBitmap was simply flattened. - bitmap->unflatten(*this); - return; - } - } - // Could not read the SkBitmap. Use a placeholder bitmap. - bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); - bitmap->allocPixels(); - bitmap->eraseColor(SK_ColorRED); -} - -SkTypeface* SkOrderedReadBuffer::readTypeface() { - - uint32_t index = fReader.readU32(); - if (0 == index || index > (unsigned)fTFCount) { - if (index) { - SkDebugf("====== typeface index %d\n", index); - } - return NULL; - } else { - SkASSERT(fTFArray); - return fTFArray[index - 1]; - } -} - -SkFlattenable* SkOrderedReadBuffer::readFlattenable(SkFlattenable::Type ft) { - // - // TODO: confirm that ft matches the factory we decide to use - // - - SkFlattenable::Factory factory = NULL; - - if (fFactoryCount > 0) { - int32_t index = fReader.readU32(); - if (0 == index) { - return NULL; // writer failed to give us the flattenable - } - index -= 1; // we stored the index-base-1 - SkASSERT(index < fFactoryCount); - factory = fFactoryArray[index]; - } else if (fFactoryTDArray) { - int32_t index = fReader.readU32(); - if (0 == index) { - return NULL; // writer failed to give us the flattenable - } - index -= 1; // we stored the index-base-1 - factory = (*fFactoryTDArray)[index]; - } else { - factory = (SkFlattenable::Factory)readFunctionPtr(); - if (NULL == factory) { - return NULL; // writer failed to give us the flattenable - } - } - - // if we get here, factory may still be null, but if that is the case, the - // failure was ours, not the writer. - SkFlattenable* obj = NULL; - uint32_t sizeRecorded = fReader.readU32(); - if (factory) { - uint32_t offset = fReader.offset(); - obj = (*factory)(*this); - // check that we read the amount we expected - uint32_t sizeRead = fReader.offset() - offset; - if (sizeRecorded != sizeRead) { - // we could try to fix up the offset... - sk_throw(); - } - } else { - // we must skip the remaining data - fReader.skip(sizeRecorded); - } - return obj; -} diff --git a/gfx/skia/trunk/src/core/SkOrderedWriteBuffer.cpp b/gfx/skia/trunk/src/core/SkOrderedWriteBuffer.cpp deleted file mode 100644 index 25ca769168da..000000000000 --- a/gfx/skia/trunk/src/core/SkOrderedWriteBuffer.cpp +++ /dev/null @@ -1,319 +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. - */ - -#include "SkOrderedWriteBuffer.h" -#include "SkBitmap.h" -#include "SkData.h" -#include "SkPtrRecorder.h" -#include "SkStream.h" -#include "SkTypeface.h" - -SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize) - : INHERITED() - , fFactorySet(NULL) - , fNamedFactorySet(NULL) - , fWriter(minSize) - , fBitmapHeap(NULL) - , fTFSet(NULL) - , fBitmapEncoder(NULL) { -} - -SkOrderedWriteBuffer::SkOrderedWriteBuffer(size_t minSize, void* storage, size_t storageSize) - : INHERITED() - , fFactorySet(NULL) - , fNamedFactorySet(NULL) - , fWriter(minSize, storage, storageSize) - , fBitmapHeap(NULL) - , fTFSet(NULL) - , fBitmapEncoder(NULL) { -} - -SkOrderedWriteBuffer::~SkOrderedWriteBuffer() { - SkSafeUnref(fFactorySet); - SkSafeUnref(fNamedFactorySet); - SkSafeUnref(fBitmapHeap); - SkSafeUnref(fTFSet); -} - -void SkOrderedWriteBuffer::writeByteArray(const void* data, size_t size) { - fWriter.write32(size); - fWriter.writePad(data, size); -} - -void SkOrderedWriteBuffer::writeBool(bool value) { - fWriter.writeBool(value); -} - -void SkOrderedWriteBuffer::writeFixed(SkFixed value) { - fWriter.write32(value); -} - -void SkOrderedWriteBuffer::writeScalar(SkScalar value) { - fWriter.writeScalar(value); -} - -void SkOrderedWriteBuffer::writeScalarArray(const SkScalar* value, uint32_t count) { - fWriter.write32(count); - fWriter.write(value, count * sizeof(SkScalar)); -} - -void SkOrderedWriteBuffer::writeInt(int32_t value) { - fWriter.write32(value); -} - -void SkOrderedWriteBuffer::writeIntArray(const int32_t* value, uint32_t count) { - fWriter.write32(count); - fWriter.write(value, count * sizeof(int32_t)); -} - -void SkOrderedWriteBuffer::writeUInt(uint32_t value) { - fWriter.write32(value); -} - -void SkOrderedWriteBuffer::write32(int32_t value) { - fWriter.write32(value); -} - -void SkOrderedWriteBuffer::writeString(const char* value) { - fWriter.writeString(value); -} - -void SkOrderedWriteBuffer::writeEncodedString(const void* value, size_t byteLength, - SkPaint::TextEncoding encoding) { - fWriter.writeInt(encoding); - fWriter.writeInt(byteLength); - fWriter.write(value, byteLength); -} - - -void SkOrderedWriteBuffer::writeColor(const SkColor& color) { - fWriter.write32(color); -} - -void SkOrderedWriteBuffer::writeColorArray(const SkColor* color, uint32_t count) { - fWriter.write32(count); - fWriter.write(color, count * sizeof(SkColor)); -} - -void SkOrderedWriteBuffer::writePoint(const SkPoint& point) { - fWriter.writeScalar(point.fX); - fWriter.writeScalar(point.fY); -} - -void SkOrderedWriteBuffer::writePointArray(const SkPoint* point, uint32_t count) { - fWriter.write32(count); - fWriter.write(point, count * sizeof(SkPoint)); -} - -void SkOrderedWriteBuffer::writeMatrix(const SkMatrix& matrix) { - fWriter.writeMatrix(matrix); -} - -void SkOrderedWriteBuffer::writeIRect(const SkIRect& rect) { - fWriter.write(&rect, sizeof(SkIRect)); -} - -void SkOrderedWriteBuffer::writeRect(const SkRect& rect) { - fWriter.writeRect(rect); -} - -void SkOrderedWriteBuffer::writeRegion(const SkRegion& region) { - fWriter.writeRegion(region); -} - -void SkOrderedWriteBuffer::writePath(const SkPath& path) { - fWriter.writePath(path); -} - -size_t SkOrderedWriteBuffer::writeStream(SkStream* stream, size_t length) { - fWriter.write32(length); - size_t bytesWritten = fWriter.readFromStream(stream, length); - if (bytesWritten < length) { - fWriter.reservePad(length - bytesWritten); - } - return bytesWritten; -} - -bool SkOrderedWriteBuffer::writeToStream(SkWStream* stream) { - return fWriter.writeToStream(stream); -} - -// Defined in SkBitmap.cpp -bool get_upper_left_from_offset(SkBitmap::Config config, size_t offset, size_t rowBytes, - int32_t* x, int32_t* y); - -void SkOrderedWriteBuffer::writeBitmap(const SkBitmap& bitmap) { - // Record the width and height. This way if readBitmap fails a dummy bitmap can be drawn at the - // right size. - this->writeInt(bitmap.width()); - this->writeInt(bitmap.height()); - - // Record information about the bitmap in one of three ways, in order of priority: - // 1. If there is an SkBitmapHeap, store it in the heap. The client can avoid serializing the - // bitmap entirely or serialize it later as desired. A boolean value of true will be written - // to the stream to signify that a heap was used. - // 2. If there is a function for encoding bitmaps, use it to write an encoded version of the - // bitmap. After writing a boolean value of false, signifying that a heap was not used, write - // the size of the encoded data. A non-zero size signifies that encoded data was written. - // 3. Call SkBitmap::flatten. After writing a boolean value of false, signifying that a heap was - // not used, write a zero to signify that the data was not encoded. - bool useBitmapHeap = fBitmapHeap != NULL; - // Write a bool: true if the SkBitmapHeap is to be used, in which case the reader must use an - // SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serialized another way. - this->writeBool(useBitmapHeap); - if (useBitmapHeap) { - SkASSERT(NULL == fBitmapEncoder); - int32_t slot = fBitmapHeap->insert(bitmap); - fWriter.write32(slot); - // crbug.com/155875 - // The generation ID is not required information. We write it to prevent collisions - // in SkFlatDictionary. It is possible to get a collision when a previously - // unflattened (i.e. stale) instance of a similar flattenable is in the dictionary - // and the instance currently being written is re-using the same slot from the - // bitmap heap. - fWriter.write32(bitmap.getGenerationID()); - return; - } - if (fBitmapEncoder != NULL) { - SkASSERT(NULL == fBitmapHeap); - size_t offset = 0; - SkAutoDataUnref data(fBitmapEncoder(&offset, bitmap)); - if (data.get() != NULL) { - // Write the length to indicate that the bitmap was encoded successfully, followed - // by the actual data. - this->writeUInt(SkToU32(data->size())); - fWriter.writePad(data->data(), data->size()); - // Store the coordinate of the offset, rather than fPixelRefOffset, which may be - // different depending on the decoder. - int32_t x, y; - if (0 == offset || !get_upper_left_from_offset(bitmap.config(), offset, - bitmap.rowBytes(), &x, &y)) { - x = y = 0; - } - this->write32(x); - this->write32(y); - return; - } - } - // Bitmap was not encoded. Record a zero, implying that the reader need not decode. - this->writeUInt(0); - bitmap.flatten(*this); -} - -void SkOrderedWriteBuffer::writeTypeface(SkTypeface* obj) { - if (NULL == obj || NULL == fTFSet) { - fWriter.write32(0); - } else { - fWriter.write32(fTFSet->add(obj)); - } -} - -SkFactorySet* SkOrderedWriteBuffer::setFactoryRecorder(SkFactorySet* rec) { - SkRefCnt_SafeAssign(fFactorySet, rec); - if (fNamedFactorySet != NULL) { - fNamedFactorySet->unref(); - fNamedFactorySet = NULL; - } - return rec; -} - -SkNamedFactorySet* SkOrderedWriteBuffer::setNamedFactoryRecorder(SkNamedFactorySet* rec) { - SkRefCnt_SafeAssign(fNamedFactorySet, rec); - if (fFactorySet != NULL) { - fFactorySet->unref(); - fFactorySet = NULL; - } - return rec; -} - -SkRefCntSet* SkOrderedWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) { - SkRefCnt_SafeAssign(fTFSet, rec); - return rec; -} - -void SkOrderedWriteBuffer::setBitmapHeap(SkBitmapHeap* bitmapHeap) { - SkRefCnt_SafeAssign(fBitmapHeap, bitmapHeap); - if (bitmapHeap != NULL) { - SkASSERT(NULL == fBitmapEncoder); - fBitmapEncoder = NULL; - } -} - -void SkOrderedWriteBuffer::setBitmapEncoder(SkPicture::EncodeBitmap bitmapEncoder) { - fBitmapEncoder = bitmapEncoder; - if (bitmapEncoder != NULL) { - SkASSERT(NULL == fBitmapHeap); - SkSafeUnref(fBitmapHeap); - fBitmapHeap = NULL; - } -} - -void SkOrderedWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { - /* - * If we have a factoryset, then the first 32bits tell us... - * 0: failure to write the flattenable - * >0: (1-based) index into the SkFactorySet or SkNamedFactorySet - * If we don't have a factoryset, then the first "ptr" is either the - * factory, or null for failure. - * - * The distinction is important, since 0-index is 32bits (always), but a - * 0-functionptr might be 32 or 64 bits. - */ - - SkFlattenable::Factory factory = NULL; - if (flattenable) { - factory = flattenable->getFactory(); - } - if (NULL == factory) { - if (this->isValidating()) { - this->writeString(""); - SkASSERT(NULL == flattenable); // We shouldn't get in here in this scenario - } else if (fFactorySet != NULL || fNamedFactorySet != NULL) { - this->write32(0); - } else { - this->writeFunctionPtr(NULL); - } - return; - } - - /* - * We can write 1 of 3 versions of the flattenable: - * 1. function-ptr : this is the fastest for the reader, but assumes that - * the writer and reader are in the same process. - * 2. index into fFactorySet : This is assumes the writer will later - * resolve the function-ptrs into strings for its reader. SkPicture - * does exactly this, by writing a table of names (matching the indices) - * up front in its serialized form. - * 3. index into fNamedFactorySet. fNamedFactorySet will also store the - * name. SkGPipe uses this technique so it can write the name to its - * stream before writing the flattenable. - */ - if (this->isValidating()) { - this->writeString(flattenable->getTypeName()); - } else if (fFactorySet) { - this->write32(fFactorySet->add(factory)); - } else if (fNamedFactorySet) { - int32_t index = fNamedFactorySet->find(factory); - this->write32(index); - if (0 == index) { - return; - } - } else { - this->writeFunctionPtr((void*)factory); - } - - // make room for the size of the flattened object - (void)fWriter.reserve(sizeof(uint32_t)); - // record the current size, so we can subtract after the object writes. - uint32_t offset = fWriter.bytesWritten(); - // now flatten the object - flattenObject(flattenable, *this); - uint32_t objSize = fWriter.bytesWritten() - offset; - // record the obj's size - *fWriter.peek32(offset - sizeof(uint32_t)) = objSize; -} diff --git a/gfx/skia/trunk/src/core/SkOrderedWriteBuffer.h b/gfx/skia/trunk/src/core/SkOrderedWriteBuffer.h deleted file mode 100644 index f3b414e104a4..000000000000 --- a/gfx/skia/trunk/src/core/SkOrderedWriteBuffer.h +++ /dev/null @@ -1,117 +0,0 @@ - -/* - * 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 SkOrderedWriteBuffer_DEFINED -#define SkOrderedWriteBuffer_DEFINED - -#include "SkFlattenableBuffers.h" - -#include "SkRefCnt.h" -#include "SkBitmapHeap.h" -#include "SkPath.h" -#include "SkPicture.h" -#include "SkWriter32.h" - -class SkBitmap; -class SkFlattenable; -class SkFactorySet; -class SkNamedFactorySet; -class SkRefCntSet; - -class SkOrderedWriteBuffer : public SkFlattenableWriteBuffer { -public: - SkOrderedWriteBuffer(size_t minSize); - SkOrderedWriteBuffer(size_t minSize, void* initialStorage, size_t storageSize); - virtual ~SkOrderedWriteBuffer(); - - virtual bool isOrderedBinaryBuffer() SK_OVERRIDE { return true; } - virtual SkOrderedWriteBuffer* getOrderedBinaryBuffer() SK_OVERRIDE { return this; } - - SkWriter32* getWriter32() { return &fWriter; } - void reset(void* storage, size_t storageSize) { fWriter.reset(storage, storageSize); } - - // Returns true if we've written only into the storage passed into constructor or reset. - // (You may be able to use this to avoid a call to writeToMemory.) - bool wroteOnlyToStorage() const { return fWriter.wroteOnlyToStorage(); } - - void writeToMemory(void* dst) { fWriter.flatten(dst); } - uint32_t* reserve(size_t size) { return fWriter.reserve(size); } - - size_t bytesWritten() const { return fWriter.bytesWritten(); } - // Deprecated. Please call bytesWritten instead. TODO(mtklein): clean up - size_t size() const { return this->bytesWritten(); } - - virtual void writeByteArray(const void* data, size_t size) SK_OVERRIDE; - virtual void writeBool(bool value) SK_OVERRIDE; - virtual void writeFixed(SkFixed value) SK_OVERRIDE; - virtual void writeScalar(SkScalar value) SK_OVERRIDE; - virtual void writeScalarArray(const SkScalar* value, uint32_t count) SK_OVERRIDE; - virtual void writeInt(int32_t value) SK_OVERRIDE; - virtual void writeIntArray(const int32_t* value, uint32_t count) SK_OVERRIDE; - virtual void writeUInt(uint32_t value) SK_OVERRIDE; - virtual void write32(int32_t value) SK_OVERRIDE; - virtual void writeString(const char* value) SK_OVERRIDE; - virtual void writeEncodedString(const void* value, size_t byteLength, - SkPaint::TextEncoding encoding) SK_OVERRIDE; - - virtual void writeFlattenable(const SkFlattenable* flattenable) SK_OVERRIDE; - virtual void writeColor(const SkColor& color) SK_OVERRIDE; - virtual void writeColorArray(const SkColor* color, uint32_t count) SK_OVERRIDE; - virtual void writePoint(const SkPoint& point) SK_OVERRIDE; - virtual void writePointArray(const SkPoint* point, uint32_t count) SK_OVERRIDE; - virtual void writeMatrix(const SkMatrix& matrix) SK_OVERRIDE; - virtual void writeIRect(const SkIRect& rect)SK_OVERRIDE; - virtual void writeRect(const SkRect& rect) SK_OVERRIDE; - virtual void writeRegion(const SkRegion& region) SK_OVERRIDE; - virtual void writePath(const SkPath& path) SK_OVERRIDE; - virtual size_t writeStream(SkStream* stream, size_t length) SK_OVERRIDE; - - virtual void writeBitmap(const SkBitmap& bitmap) SK_OVERRIDE; - virtual void writeTypeface(SkTypeface* typeface) SK_OVERRIDE; - - virtual bool writeToStream(SkWStream*) SK_OVERRIDE; - - SkFactorySet* setFactoryRecorder(SkFactorySet*); - SkNamedFactorySet* setNamedFactoryRecorder(SkNamedFactorySet*); - - SkRefCntSet* getTypefaceRecorder() const { return fTFSet; } - SkRefCntSet* setTypefaceRecorder(SkRefCntSet*); - - /** - * Set an SkBitmapHeap to store bitmaps rather than flattening. - * - * Incompatible with an EncodeBitmap function. If an EncodeBitmap function is set, setting an - * SkBitmapHeap will set the function to NULL in release mode and crash in debug. - */ - void setBitmapHeap(SkBitmapHeap*); - - /** - * Provide a function to encode an SkBitmap to an SkData. writeBitmap will attempt to use - * bitmapEncoder to store the SkBitmap. If the reader does not provide a function to decode, it - * will not be able to restore SkBitmaps, but will still be able to read the rest of the stream. - * bitmapEncoder will never be called with a NULL pixelRefOffset. - * - * Incompatible with the SkBitmapHeap. If an encoder is set fBitmapHeap will be set to NULL in - * release and crash in debug. - */ - void setBitmapEncoder(SkPicture::EncodeBitmap bitmapEncoder); - -private: - SkFactorySet* fFactorySet; - SkNamedFactorySet* fNamedFactorySet; - SkWriter32 fWriter; - - SkBitmapHeap* fBitmapHeap; - SkRefCntSet* fTFSet; - - SkPicture::EncodeBitmap fBitmapEncoder; - - typedef SkFlattenableWriteBuffer INHERITED; -}; - -#endif // SkOrderedWriteBuffer_DEFINED diff --git a/gfx/skia/trunk/src/core/SkPaint.cpp b/gfx/skia/trunk/src/core/SkPaint.cpp index c3f217cefc60..2449ed6793c2 100644 --- a/gfx/skia/trunk/src/core/SkPaint.cpp +++ b/gfx/skia/trunk/src/core/SkPaint.cpp @@ -35,6 +35,26 @@ #include "SkTypeface.h" #include "SkXfermode.h" +enum { + kColor_DirtyBit = 1 << 0, + kBitfields_DirtyBit = 1 << 1, + kTextSize_DirtyBit = 1 << 2, + kTextScaleX_DirtyBit = 1 << 3, + kTextSkewX_DirtyBit = 1 << 4, + kStrokeWidth_DirtyBit = 1 << 5, + kStrokeMiter_DirtyBit = 1 << 6, + kPathEffect_DirtyBit = 1 << 7, + kShader_DirtyBit = 1 << 8, + kXfermode_DirtyBit = 1 << 9, + kMaskFilter_DirtyBit = 1 << 10, + kColorFilter_DirtyBit = 1 << 11, + kRasterizer_DirtyBit = 1 << 12, + kLooper_DirtyBit = 1 << 13, + kImageFilter_DirtyBit = 1 << 14, + kTypeface_DirtyBit = 1 << 15, + kAnnotation_DirtyBit = 1 << 16, + kPaintOptionsAndroid_DirtyBit = 1 << 17, +}; // define this to get a printf for out-of-range parameter in setters // e.g. setTextSize(-1) @@ -55,8 +75,8 @@ SkPaint::SkPaint() { sk_bzero(this, sizeof(*this)); #if 0 // not needed with the bzero call above - fTypeface = NULL; - fTextSkewX = 0; + fTypeface = NULL; + fTextSkewX = 0; fPathEffect = NULL; fShader = NULL; fXfermode = NULL; @@ -66,7 +86,8 @@ SkPaint::SkPaint() { fLooper = NULL; fImageFilter = NULL; fAnnotation = NULL; - fWidth = 0; + fWidth = 0; + fDirtyBits = 0; #endif fTextSize = SkPaintDefaults_TextSize; @@ -198,6 +219,7 @@ void SkPaint::setPaintOptionsAndroid(const SkPaintOptionsAndroid& options) { if (options != fPaintOptionsAndroid) { fPaintOptionsAndroid = options; GEN_ID_INC; + fDirtyBits |= kPaintOptionsAndroid_DirtyBit; } } #endif @@ -228,11 +250,13 @@ void SkPaint::setFilterLevel(FilterLevel level) { void SkPaint::setHinting(Hinting hintingLevel) { GEN_ID_INC_EVAL((unsigned) hintingLevel != fHinting); fHinting = hintingLevel; + fDirtyBits |= kBitfields_DirtyBit; } void SkPaint::setFlags(uint32_t flags) { GEN_ID_INC_EVAL(fFlags != flags); fFlags = flags; + fDirtyBits |= kBitfields_DirtyBit; } void SkPaint::setAntiAlias(bool doAA) { @@ -283,10 +307,15 @@ void SkPaint::setDevKernText(bool doDevKern) { this->setFlags(SkSetClearMask(fFlags, doDevKern, kDevKernText_Flag)); } +void SkPaint::setDistanceFieldTextTEMP(bool doDistanceFieldText) { + this->setFlags(SkSetClearMask(fFlags, doDistanceFieldText, kDistanceFieldTextTEMP_Flag)); +} + void SkPaint::setStyle(Style style) { if ((unsigned)style < kStyleCount) { GEN_ID_INC_EVAL((unsigned)style != fStyle); fStyle = style; + fDirtyBits |= kBitfields_DirtyBit; } else { #ifdef SK_REPORT_API_RANGE_CHECK SkDebugf("SkPaint::setStyle(%d) out of range\n", style); @@ -297,6 +326,7 @@ void SkPaint::setStyle(Style style) { void SkPaint::setColor(SkColor color) { GEN_ID_INC_EVAL(color != fColor); fColor = color; + fDirtyBits |= kColor_DirtyBit; } void SkPaint::setAlpha(U8CPU a) { @@ -312,6 +342,7 @@ void SkPaint::setStrokeWidth(SkScalar width) { if (width >= 0) { GEN_ID_INC_EVAL(width != fWidth); fWidth = width; + fDirtyBits |= kStrokeWidth_DirtyBit; } else { #ifdef SK_REPORT_API_RANGE_CHECK SkDebugf("SkPaint::setStrokeWidth() called with negative value\n"); @@ -323,6 +354,7 @@ void SkPaint::setStrokeMiter(SkScalar limit) { if (limit >= 0) { GEN_ID_INC_EVAL(limit != fMiterLimit); fMiterLimit = limit; + fDirtyBits |= kStrokeMiter_DirtyBit; } else { #ifdef SK_REPORT_API_RANGE_CHECK SkDebugf("SkPaint::setStrokeMiter() called with negative value\n"); @@ -334,6 +366,7 @@ void SkPaint::setStrokeCap(Cap ct) { if ((unsigned)ct < kCapCount) { GEN_ID_INC_EVAL((unsigned)ct != fCapType); fCapType = SkToU8(ct); + fDirtyBits |= kBitfields_DirtyBit; } else { #ifdef SK_REPORT_API_RANGE_CHECK SkDebugf("SkPaint::setStrokeCap(%d) out of range\n", ct); @@ -345,6 +378,7 @@ void SkPaint::setStrokeJoin(Join jt) { if ((unsigned)jt < kJoinCount) { GEN_ID_INC_EVAL((unsigned)jt != fJoinType); fJoinType = SkToU8(jt); + fDirtyBits |= kBitfields_DirtyBit; } else { #ifdef SK_REPORT_API_RANGE_CHECK SkDebugf("SkPaint::setStrokeJoin(%d) out of range\n", jt); @@ -358,6 +392,7 @@ void SkPaint::setTextAlign(Align align) { if ((unsigned)align < kAlignCount) { GEN_ID_INC_EVAL((unsigned)align != fTextAlign); fTextAlign = SkToU8(align); + fDirtyBits |= kBitfields_DirtyBit; } else { #ifdef SK_REPORT_API_RANGE_CHECK SkDebugf("SkPaint::setTextAlign(%d) out of range\n", align); @@ -369,6 +404,7 @@ void SkPaint::setTextSize(SkScalar ts) { if (ts >= 0) { GEN_ID_INC_EVAL(ts != fTextSize); fTextSize = ts; + fDirtyBits |= kTextSize_DirtyBit; } else { #ifdef SK_REPORT_API_RANGE_CHECK SkDebugf("SkPaint::setTextSize() called with negative value\n"); @@ -379,17 +415,20 @@ void SkPaint::setTextSize(SkScalar ts) { void SkPaint::setTextScaleX(SkScalar scaleX) { GEN_ID_INC_EVAL(scaleX != fTextScaleX); fTextScaleX = scaleX; + fDirtyBits |= kTextScaleX_DirtyBit; } void SkPaint::setTextSkewX(SkScalar skewX) { GEN_ID_INC_EVAL(skewX != fTextSkewX); fTextSkewX = skewX; + fDirtyBits |= kTextSkewX_DirtyBit; } void SkPaint::setTextEncoding(TextEncoding encoding) { if ((unsigned)encoding <= kGlyphID_TextEncoding) { GEN_ID_INC_EVAL((unsigned)encoding != fTextEncoding); fTextEncoding = encoding; + fDirtyBits |= kBitfields_DirtyBit; } else { #ifdef SK_REPORT_API_RANGE_CHECK SkDebugf("SkPaint::setTextEncoding(%d) out of range\n", encoding); @@ -399,33 +438,43 @@ void SkPaint::setTextEncoding(TextEncoding encoding) { /////////////////////////////////////////////////////////////////////////////// +// Returns dst with the given bitmask enabled or disabled, depending on value. +inline static uint32_t set_mask(uint32_t dst, uint32_t bitmask, bool value) { + return value ? (dst | bitmask) : (dst & ~bitmask); +} + SkTypeface* SkPaint::setTypeface(SkTypeface* font) { SkRefCnt_SafeAssign(fTypeface, font); GEN_ID_INC; + fDirtyBits = set_mask(fDirtyBits, kTypeface_DirtyBit, font != NULL); return font; } SkRasterizer* SkPaint::setRasterizer(SkRasterizer* r) { SkRefCnt_SafeAssign(fRasterizer, r); GEN_ID_INC; + fDirtyBits = set_mask(fDirtyBits, kRasterizer_DirtyBit, r != NULL); return r; } SkDrawLooper* SkPaint::setLooper(SkDrawLooper* looper) { SkRefCnt_SafeAssign(fLooper, looper); GEN_ID_INC; + fDirtyBits = set_mask(fDirtyBits, kLooper_DirtyBit, looper != NULL); return looper; } SkImageFilter* SkPaint::setImageFilter(SkImageFilter* imageFilter) { SkRefCnt_SafeAssign(fImageFilter, imageFilter); GEN_ID_INC; + fDirtyBits = set_mask(fDirtyBits, kImageFilter_DirtyBit, imageFilter != NULL); return imageFilter; } SkAnnotation* SkPaint::setAnnotation(SkAnnotation* annotation) { SkRefCnt_SafeAssign(fAnnotation, annotation); GEN_ID_INC; + fDirtyBits = set_mask(fDirtyBits, kAnnotation_DirtyBit, annotation != NULL); return annotation; } @@ -470,42 +519,6 @@ static void DetachDescProc(SkTypeface* typeface, const SkDescriptor* desc, *((SkGlyphCache**)context) = SkGlyphCache::DetachCache(typeface, desc); } -#ifdef SK_BUILD_FOR_ANDROID -const SkGlyph& SkPaint::getUnicharMetrics(SkUnichar text, - const SkMatrix* deviceMatrix) { - SkGlyphCache* cache; - descriptorProc(NULL, deviceMatrix, DetachDescProc, &cache, true); - - const SkGlyph& glyph = cache->getUnicharMetrics(text); - - SkGlyphCache::AttachCache(cache); - return glyph; -} - -const SkGlyph& SkPaint::getGlyphMetrics(uint16_t glyphId, - const SkMatrix* deviceMatrix) { - SkGlyphCache* cache; - descriptorProc(NULL, deviceMatrix, DetachDescProc, &cache, true); - - const SkGlyph& glyph = cache->getGlyphIDMetrics(glyphId); - - SkGlyphCache::AttachCache(cache); - return glyph; -} - -const void* SkPaint::findImage(const SkGlyph& glyph, - const SkMatrix* deviceMatrix) { - // See ::detachCache() - SkGlyphCache* cache; - descriptorProc(NULL, deviceMatrix, DetachDescProc, &cache, true); - - const void* image = cache->findImage(glyph); - - SkGlyphCache::AttachCache(cache); - return image; -} -#endif - int SkPaint::textToGlyphs(const void* textData, size_t byteLength, uint16_t glyphs[]) const { if (byteLength == 0) { @@ -1296,6 +1309,8 @@ SkScalar SkPaint::getFontMetrics(FontMetrics* metrics, SkScalar zoom) const { metrics->fXMin = SkScalarMul(metrics->fXMin, scale); metrics->fXMax = SkScalarMul(metrics->fXMax, scale); metrics->fXHeight = SkScalarMul(metrics->fXHeight, scale); + metrics->fUnderlineThickness = SkScalarMul(metrics->fUnderlineThickness, scale); + metrics->fUnderlinePosition = SkScalarMul(metrics->fUnderlinePosition, scale); } return metrics->fDescent - metrics->fAscent + metrics->fLeading; } @@ -1537,10 +1552,10 @@ static SkColor computeLuminanceColor(const SkPaint& paint) { #endif static bool tooBigForLCD(const SkScalerContext::Rec& rec) { - SkScalar area = SkScalarMul(rec.fPost2x2[0][0], rec.fPost2x2[1][1]) - - SkScalarMul(rec.fPost2x2[1][0], rec.fPost2x2[0][1]); - SkScalar size = SkScalarMul(area, rec.fTextSize); - return SkScalarAbs(size) > SkIntToScalar(SK_MAX_SIZE_FOR_LCDTEXT); + SkScalar area = rec.fPost2x2[0][0] * rec.fPost2x2[1][1] - + rec.fPost2x2[1][0] * rec.fPost2x2[0][1]; + SkScalar size = SkScalarSqrt(SkScalarAbs(area)) * rec.fTextSize; + return size > SkIntToScalar(SK_MAX_SIZE_FOR_LCDTEXT); } /* @@ -2119,7 +2134,7 @@ void SkPaint::unflatten(SkReadBuffer& buffer) { SkSafeUnref(this->setImageFilter(buffer.readImageFilter())); if (buffer.readBool()) { - this->setAnnotation(SkNEW_ARGS(SkAnnotation, (buffer)))->unref(); + this->setAnnotation(SkAnnotation::Create(buffer))->unref(); } } else { this->setPathEffect(NULL); @@ -2149,18 +2164,21 @@ void SkPaint::unflatten(SkReadBuffer& buffer) { SkShader* SkPaint::setShader(SkShader* shader) { GEN_ID_INC_EVAL(shader != fShader); SkRefCnt_SafeAssign(fShader, shader); + fDirtyBits = set_mask(fDirtyBits, kShader_DirtyBit, shader != NULL); return shader; } SkColorFilter* SkPaint::setColorFilter(SkColorFilter* filter) { GEN_ID_INC_EVAL(filter != fColorFilter); SkRefCnt_SafeAssign(fColorFilter, filter); + fDirtyBits = set_mask(fDirtyBits, kColorFilter_DirtyBit, filter != NULL); return filter; } SkXfermode* SkPaint::setXfermode(SkXfermode* mode) { GEN_ID_INC_EVAL(mode != fXfermode); SkRefCnt_SafeAssign(fXfermode, mode); + fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, mode != NULL); return mode; } @@ -2168,18 +2186,21 @@ SkXfermode* SkPaint::setXfermodeMode(SkXfermode::Mode mode) { SkSafeUnref(fXfermode); fXfermode = SkXfermode::Create(mode); GEN_ID_INC; + fDirtyBits = set_mask(fDirtyBits, kXfermode_DirtyBit, fXfermode != NULL); return fXfermode; } SkPathEffect* SkPaint::setPathEffect(SkPathEffect* effect) { GEN_ID_INC_EVAL(effect != fPathEffect); SkRefCnt_SafeAssign(fPathEffect, effect); + fDirtyBits = set_mask(fDirtyBits, kPathEffect_DirtyBit, effect != NULL); return effect; } SkMaskFilter* SkPaint::setMaskFilter(SkMaskFilter* filter) { GEN_ID_INC_EVAL(filter != fMaskFilter); SkRefCnt_SafeAssign(fMaskFilter, filter); + fDirtyBits = set_mask(fDirtyBits, kMaskFilter_DirtyBit, filter != NULL); return filter; } @@ -2257,7 +2278,7 @@ const SkRect& SkPaint::doComputeFastBounds(const SkRect& origSrc, return *storage; } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkPaint::toString(SkString* str) const { str->append("
SkPaint:
"); @@ -2427,7 +2448,6 @@ void SkPaint::toString(SkString* str) const { } #endif - /////////////////////////////////////////////////////////////////////////////// static bool has_thick_frame(const SkPaint& paint) { @@ -2550,3 +2570,97 @@ bool SkPaint::nothingToDraw() const { } return false; } + +void SkPaint::setBitfields(uint32_t bitfields) { + fBitfields = bitfields; + fDirtyBits |= kBitfields_DirtyBit; +} + +inline static unsigned popcount(uint8_t x) { + // As in Hacker's delight, adapted for just 8 bits. + x = (x & 0x55) + ((x >> 1) & 0x55); // a b c d w x y z -> a+b c+d w+x y+z + x = (x & 0x33) + ((x >> 2) & 0x33); // a+b c+d w+x y+z -> a+b+c+d w+x+y+z + x = (x & 0x0F) + ((x >> 4) & 0x0F); // a+b+c+d w+x+y+z -> a+b+c+d+w+x+y+z + return x; +} + +void SkPaint::FlatteningTraits::Flatten(SkWriteBuffer& buffer, const SkPaint& paint) { + const uint32_t dirty = paint.fDirtyBits; + + // Each of the low 7 dirty bits corresponds to a 4-byte flat value, plus one for the dirty bits. + const size_t flatBytes = 4 * (popcount(dirty & 127) + 1); + SkASSERT(flatBytes <= 32); + uint32_t* u32 = buffer.reserve(flatBytes); + *u32++ = dirty; + if (dirty == 0) { + return; + } + +#define F(dst, field) if (dirty & k##field##_DirtyBit) *dst++ = paint.get##field() + F(u32, Color); + F(u32, Bitfields); + SkScalar* f32 = reinterpret_cast(u32); + F(f32, TextSize); + F(f32, TextScaleX); + F(f32, TextSkewX); + F(f32, StrokeWidth); + F(f32, StrokeMiter); +#undef F +#define F(field) if (dirty & k##field##_DirtyBit) buffer.writeFlattenable(paint.get##field()) + F(PathEffect); + F(Shader); + F(Xfermode); + F(MaskFilter); + F(ColorFilter); + F(Rasterizer); + F(Looper); + F(ImageFilter); +#undef F + if (dirty & kTypeface_DirtyBit) buffer.writeTypeface(paint.getTypeface()); + if (dirty & kAnnotation_DirtyBit) paint.getAnnotation()->writeToBuffer(buffer); +#ifdef SK_BUILD_FOR_ANDROID + if (dirty & kPaintOptionsAndroid_DirtyBit) paint.getPaintOptionsAndroid().flatten(buffer); +#endif +} + +void SkPaint::FlatteningTraits::Unflatten(SkReadBuffer& buffer, SkPaint* paint) { + const uint32_t dirty = buffer.readUInt(); + if (dirty == 0) { + return; + } +#define F(field, reader) if (dirty & k##field##_DirtyBit) paint->set##field(buffer.reader()) +// Same function, except it unrefs the object newly set on the paint: +#define F_UNREF(field, reader) \ + if (dirty & k##field##_DirtyBit) \ + paint->set##field(buffer.reader())->unref() + + F(Color, readUInt); + F(Bitfields, readUInt); + F(TextSize, readScalar); + F(TextScaleX, readScalar); + F(TextSkewX, readScalar); + F(StrokeWidth, readScalar); + F(StrokeMiter, readScalar); + F_UNREF(PathEffect, readPathEffect); + F_UNREF(Shader, readShader); + F_UNREF(Xfermode, readXfermode); + F_UNREF(MaskFilter, readMaskFilter); + F_UNREF(ColorFilter, readColorFilter); + F_UNREF(Rasterizer, readRasterizer); + F_UNREF(Looper, readDrawLooper); + F_UNREF(ImageFilter, readImageFilter); + F(Typeface, readTypeface); +#undef F +#undef F_UNREF + if (dirty & kAnnotation_DirtyBit) { + paint->setAnnotation(SkAnnotation::Create(buffer))->unref(); + } +#ifdef SK_BUILD_FOR_ANDROID + if (dirty & kPaintOptionsAndroid_DirtyBit) { + SkPaintOptionsAndroid options; + options.unflatten(buffer); + paint->setPaintOptionsAndroid(options); + } +#endif + SkASSERT(dirty == paint->fDirtyBits); +} diff --git a/gfx/skia/trunk/src/core/SkPathHeap.cpp b/gfx/skia/trunk/src/core/SkPathHeap.cpp index a8271e1fa285..84ffb04b80ee 100644 --- a/gfx/skia/trunk/src/core/SkPathHeap.cpp +++ b/gfx/skia/trunk/src/core/SkPathHeap.cpp @@ -9,6 +9,7 @@ #include "SkPath.h" #include "SkStream.h" #include "SkReadBuffer.h" +#include "SkTSearch.h" #include "SkWriteBuffer.h" #include @@ -49,6 +50,38 @@ int SkPathHeap::append(const SkPath& path) { return fPaths.count(); } +SkPathHeap::LookupEntry::LookupEntry(const SkPath& path) + : fGenerationID(path.getGenerationID()), fStorageSlot(0) { +} + +SkPathHeap::LookupEntry* SkPathHeap::addIfNotPresent(const SkPath& path) { + LookupEntry searchKey(path); + int index = SkTSearch( + fLookupTable.begin(), + fLookupTable.count(), + searchKey, + sizeof(LookupEntry)); + if (index < 0) { + index = ~index; + *fLookupTable.insert(index) = LookupEntry(path); + } + + return &fLookupTable[index];; +} + +int SkPathHeap::insert(const SkPath& path) { + SkPathHeap::LookupEntry* entry = this->addIfNotPresent(path); + + if (entry->storageSlot() > 0) { + return entry->storageSlot(); + } + + int newSlot = this->append(path); + SkASSERT(newSlot > 0); + entry->setStorageSlot(newSlot); + return newSlot; +} + void SkPathHeap::flatten(SkWriteBuffer& buffer) const { int count = fPaths.count(); diff --git a/gfx/skia/trunk/src/core/SkPathHeap.h b/gfx/skia/trunk/src/core/SkPathHeap.h index e3b0f7a84fc2..377d8d968ba1 100644 --- a/gfx/skia/trunk/src/core/SkPathHeap.h +++ b/gfx/skia/trunk/src/core/SkPathHeap.h @@ -30,6 +30,11 @@ public: */ int append(const SkPath&); + /** Add the specified path to the heap using its gen ID to de-duplicate. + Returns the path's index in the heap + 1. + */ + int insert(const SkPath&); + // called during picture-playback int count() const { return fPaths.count(); } const SkPath& operator[](int index) const { @@ -44,6 +49,27 @@ private: // we just store ptrs into fHeap here SkTDArray fPaths; + class LookupEntry { + public: + LookupEntry(const SkPath& path); + + int storageSlot() const { return fStorageSlot; } + void setStorageSlot(int storageSlot) { fStorageSlot = storageSlot; } + + static bool Less(const LookupEntry& a, const LookupEntry& b) { + return a.fGenerationID < b.fGenerationID; + } + + private: + uint32_t fGenerationID; // the SkPath's generation ID + // the path's index in the heap + 1. It is 0 if the path is not yet in the heap. + int fStorageSlot; + }; + + SkTDArray fLookupTable; + + SkPathHeap::LookupEntry* addIfNotPresent(const SkPath& path); + typedef SkRefCnt INHERITED; }; diff --git a/gfx/skia/trunk/src/core/SkPicture.cpp b/gfx/skia/trunk/src/core/SkPicture.cpp index e226c2642ac1..1285ff1eefbf 100644 --- a/gfx/skia/trunk/src/core/SkPicture.cpp +++ b/gfx/skia/trunk/src/core/SkPicture.cpp @@ -117,9 +117,12 @@ SkPicture::SkPicture() { fRecord = NULL; fPlayback = NULL; fWidth = fHeight = 0; + fAccelData = NULL; } -SkPicture::SkPicture(const SkPicture& src) : INHERITED() { +SkPicture::SkPicture(const SkPicture& src) + : INHERITED() + , fAccelData(NULL) { fWidth = src.fWidth; fHeight = src.fHeight; fRecord = NULL; @@ -141,11 +144,19 @@ SkPicture::SkPicture(const SkPicture& src) : INHERITED() { SkPicture::~SkPicture() { SkSafeUnref(fRecord); SkDELETE(fPlayback); + SkSafeUnref(fAccelData); +} + +void SkPicture::internalOnly_EnableOpts(bool enableOpts) { + if (NULL != fRecord) { + fRecord->internalOnly_EnableOpts(enableOpts); + } } void SkPicture::swap(SkPicture& other) { SkTSwap(fRecord, other.fRecord); SkTSwap(fPlayback, other.fPlayback); + SkTSwap(fAccelData, other.fAccelData); SkTSwap(fWidth, other.fWidth); SkTSwap(fHeight, other.fHeight); } @@ -164,12 +175,7 @@ void SkPicture::clone(SkPicture* pictures, int count) const { clone->fWidth = fWidth; clone->fHeight = fHeight; - clone->fRecord = NULL; - - if (NULL != clone->fRecord) { - clone->fRecord->unref(); - clone->fRecord = NULL; - } + SkSafeSetNull(clone->fRecord); SkDELETE(clone->fPlayback); /* We want to copy the src's playback. However, if that hasn't been built @@ -187,6 +193,17 @@ void SkPicture::clone(SkPicture* pictures, int count) const { } } +SkPicture::AccelData::Domain SkPicture::AccelData::GenerateDomain() { + static int32_t gNextID = 0; + + int32_t id = sk_atomic_inc(&gNextID); + if (id >= 1 << (8 * sizeof(Domain))) { + SK_CRASH(); + } + + return static_cast(id); +} + /////////////////////////////////////////////////////////////////////////////// SkCanvas* SkPicture::beginRecording(int width, int height, @@ -195,27 +212,22 @@ SkCanvas* SkPicture::beginRecording(int width, int height, SkDELETE(fPlayback); fPlayback = NULL; } - - if (NULL != fRecord) { - fRecord->unref(); - fRecord = NULL; - } - - SkBitmap bm; - bm.setConfig(SkBitmap::kNo_Config, width, height); - SkAutoTUnref dev(SkNEW_ARGS(SkBitmapDevice, (bm))); + SkSafeUnref(fAccelData); + SkSafeSetNull(fRecord); // Must be set before calling createBBoxHierarchy fWidth = width; fHeight = height; + const SkISize size = SkISize::Make(width, height); + if (recordingFlags & kOptimizeForClippedPlayback_RecordingFlag) { SkBBoxHierarchy* tree = this->createBBoxHierarchy(); SkASSERT(NULL != tree); - fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (recordingFlags, tree, dev)); + fRecord = SkNEW_ARGS(SkBBoxHierarchyRecord, (size, recordingFlags, tree)); tree->unref(); } else { - fRecord = SkNEW_ARGS(SkPictureRecord, (recordingFlags, dev)); + fRecord = SkNEW_ARGS(SkPictureRecord, (size, recordingFlags)); } fRecord->beginRecording(); @@ -246,8 +258,7 @@ void SkPicture::endRecording() { if (NULL != fRecord) { fRecord->endRecording(); fPlayback = SkNEW_ARGS(SkPicturePlayback, (*fRecord)); - fRecord->unref(); - fRecord = NULL; + SkSafeSetNull(fRecord); } } SkASSERT(NULL == fRecord); @@ -255,7 +266,7 @@ void SkPicture::endRecording() { void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) { this->endRecording(); - if (fPlayback) { + if (NULL != fPlayback) { fPlayback->draw(*surface, callback); } } @@ -265,26 +276,29 @@ void SkPicture::draw(SkCanvas* surface, SkDrawPictureCallback* callback) { #include "SkStream.h" static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' }; -static const size_t kHeaderSize = sizeof(kMagic) + sizeof(SkPictInfo); -bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) { +bool SkPicture::IsValidPictInfo(const SkPictInfo& info) { + if (0 != memcmp(info.fMagic, kMagic, sizeof(kMagic))) { + return false; + } + + if (info.fVersion < MIN_PICTURE_VERSION || + info.fVersion > CURRENT_PICTURE_VERSION) { + return false; + } + + return true; +} + +bool SkPicture::InternalOnly_StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) { if (NULL == stream) { return false; } // Check magic bytes. - char magic[sizeof(kMagic)]; - if (!stream->read(magic, sizeof(kMagic)) || - (0 != memcmp(magic, kMagic, sizeof(kMagic)))) { - return false; - } - SkPictInfo info; - if (!stream->read(&info, sizeof(SkPictInfo))) { - return false; - } - - if (PICTURE_VERSION != info.fVersion) { + SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); + if (!stream->read(&info, sizeof(info)) || !IsValidPictInfo(info)) { return false; } @@ -294,21 +308,11 @@ bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) { return true; } -bool SkPicture::BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo) { +bool SkPicture::InternalOnly_BufferIsSKP(SkReadBuffer& buffer, SkPictInfo* pInfo) { // Check magic bytes. - char magic[sizeof(kMagic)]; - - if (!buffer.readByteArray(magic, sizeof(kMagic)) || - (0 != memcmp(magic, kMagic, sizeof(kMagic)))) { - return false; - } - SkPictInfo info; - if (!buffer.readByteArray(&info, sizeof(SkPictInfo))) { - return false; - } - - if (PICTURE_VERSION != info.fVersion) { + SkASSERT(sizeof(kMagic) == sizeof(info.fMagic)); + if (!buffer.readByteArray(&info, sizeof(info)) || !IsValidPictInfo(info)) { return false; } @@ -322,12 +326,13 @@ SkPicture::SkPicture(SkPicturePlayback* playback, int width, int height) : fPlayback(playback) , fRecord(NULL) , fWidth(width) - , fHeight(height) {} + , fHeight(height) + , fAccelData(NULL) {} SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc proc) { SkPictInfo info; - if (!StreamIsSKP(stream, &info)) { + if (!InternalOnly_StreamIsSKP(stream, &info)) { return NULL; } @@ -348,7 +353,7 @@ SkPicture* SkPicture::CreateFromStream(SkStream* stream, InstallPixelRefProc pro SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { SkPictInfo info; - if (!BufferIsSKP(buffer, &info)) { + if (!InternalOnly_BufferIsSKP(buffer, &info)) { return NULL; } @@ -366,14 +371,14 @@ SkPicture* SkPicture::CreateFromBuffer(SkReadBuffer& buffer) { return SkNEW_ARGS(SkPicture, (playback, info.fWidth, info.fHeight)); } -void SkPicture::createHeader(void* header) const { +void SkPicture::createHeader(SkPictInfo* info) const { // Copy magic bytes at the beginning of the header SkASSERT(sizeof(kMagic) == 8); - memcpy(header, kMagic, sizeof(kMagic)); + SkASSERT(sizeof(kMagic) == sizeof(info->fMagic)); + memcpy(info->fMagic, kMagic, sizeof(kMagic)); - // Set piture info after magic bytes in the header - SkPictInfo* info = (SkPictInfo*)(((char*)header) + sizeof(kMagic)); - info->fVersion = PICTURE_VERSION; + // Set picture info after magic bytes in the header + info->fVersion = CURRENT_PICTURE_VERSION; info->fWidth = fWidth; info->fHeight = fHeight; info->fFlags = SkPictInfo::kCrossProcess_Flag; @@ -392,9 +397,9 @@ void SkPicture::serialize(SkWStream* stream, EncodeBitmap encoder) const { playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord)); } - char header[kHeaderSize]; - createHeader(&header); - stream->write(header, kHeaderSize); + SkPictInfo header; + this->createHeader(&header); + stream->write(&header, sizeof(header)); if (playback) { stream->writeBool(true); playback->serialize(stream, encoder); @@ -414,9 +419,9 @@ void SkPicture::flatten(SkWriteBuffer& buffer) const { playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord)); } - char header[kHeaderSize]; - createHeader(&header); - buffer.writeByteArray(header, kHeaderSize); + SkPictInfo header; + this->createHeader(&header); + buffer.writeByteArray(&header, sizeof(header)); if (playback) { buffer.writeBool(true); playback->flatten(buffer); @@ -430,7 +435,9 @@ void SkPicture::flatten(SkWriteBuffer& buffer) const { } bool SkPicture::willPlayBackBitmaps() const { - if (!fPlayback) return false; + if (!fPlayback) { + return false; + } return fPlayback->containsBitmaps(); } diff --git a/gfx/skia/trunk/src/core/SkPictureFlat.h b/gfx/skia/trunk/src/core/SkPictureFlat.h index 7973e6539818..bd8f66cb7e4a 100644 --- a/gfx/skia/trunk/src/core/SkPictureFlat.h +++ b/gfx/skia/trunk/src/core/SkPictureFlat.h @@ -63,7 +63,12 @@ enum DrawType { COMMENT, END_COMMENT_GROUP, - LAST_DRAWTYPE_ENUM = END_COMMENT_GROUP + // new ops -- feel free to re-alphabetize on next version bump + DRAW_DRRECT, + PUSH_CULL, + POP_CULL, + + LAST_DRAWTYPE_ENUM = POP_CULL }; // In the 'match' method, this constant will match any flavor of DRAW_BITMAP* @@ -265,7 +270,7 @@ public: buffer.setTypefaceRecorder(controller->getTypefaceSet()); buffer.setNamedFactoryRecorder(controller->getNamedFactorySet()); - Traits::flatten(buffer, obj); + Traits::Flatten(buffer, obj); size_t size = buffer.bytesWritten(); SkASSERT(SkIsAlign4(size)); @@ -294,7 +299,7 @@ public: facePlayback->setupBuffer(buffer); } - Traits::unflatten(buffer, result); + Traits::Unflatten(buffer, result); SkASSERT(fFlatSize == (int32_t)buffer.offset()); } @@ -500,7 +505,9 @@ private: const SkFlatData& scratch = this->resetScratch(element, this->count()+1); SkFlatData* candidate = fHash.find(scratch); - if (candidate != NULL) return candidate; + if (candidate != NULL) { + return candidate; + } SkFlatData* detached = this->detachScratch(); fHash.add(detached); @@ -516,7 +523,7 @@ private: // Layout of fScratch: [ SkFlatData header, 20 bytes ] [ data ..., 4-byte aligned ] fScratch.reset(); fScratch.reserve(sizeof(SkFlatData)); - Traits::flatten(fScratch, element); + Traits::Flatten(fScratch, element); const size_t dataSize = fScratch.bytesWritten() - sizeof(SkFlatData); // Reinterpret data in fScratch as an SkFlatData. @@ -561,15 +568,7 @@ private: SkFlatData::Identity, SkFlatData::Hash, SkFlatData::Equal> fHash; }; -struct SkPaintTraits { - static void flatten(SkWriteBuffer& buffer, const SkPaint& paint) { - paint.flatten(buffer); - } - static void unflatten(SkReadBuffer& buffer, SkPaint* paint) { - paint->unflatten(buffer); - } -}; -typedef SkFlatDictionary SkPaintDictionary; +typedef SkFlatDictionary SkPaintDictionary; class SkChunkFlatController : public SkFlatController { public: diff --git a/gfx/skia/trunk/src/core/SkPicturePlayback.cpp b/gfx/skia/trunk/src/core/SkPicturePlayback.cpp index 8b8c6b0862da..d61e616c4da9 100644 --- a/gfx/skia/trunk/src/core/SkPicturePlayback.cpp +++ b/gfx/skia/trunk/src/core/SkPicturePlayback.cpp @@ -5,15 +5,16 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -#include "SkPicturePlayback.h" -#include "SkPictureRecord.h" -#include "SkTypeface.h" -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" #include #include "SkBBoxHierarchy.h" +#include "SkOffsetTable.h" +#include "SkPicturePlayback.h" +#include "SkPictureRecord.h" #include "SkPictureStateTree.h" +#include "SkReadBuffer.h" +#include "SkTypeface.h" #include "SkTSort.h" +#include "SkWriteBuffer.h" template int SafeCount(const T* obj) { return obj ? obj->count() : 0; @@ -69,10 +70,12 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record, bool deepCop record.validate(record.writeStream().bytesWritten(), 0); const SkWriter32& writer = record.writeStream(); init(); + SkASSERT(!fOpData); if (writer.bytesWritten() == 0) { fOpData = SkData::NewEmpty(); return; } + fOpData = writer.snapshotAsData(); fBoundingHierarchy = record.fBoundingHierarchy; fStateTree = record.fStateTree; @@ -84,14 +87,6 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record, bool deepCop fBoundingHierarchy->flushDeferredInserts(); } - { - size_t size = writer.bytesWritten(); - void* buffer = sk_malloc_throw(size); - writer.flatten(buffer); - SkASSERT(!fOpData); - fOpData = SkData::NewFromMalloc(buffer, size); - } - // copy over the refcnt dictionary to our reader record.fFlattenableHeap.setupPlaybacks(); @@ -101,6 +96,8 @@ SkPicturePlayback::SkPicturePlayback(const SkPictureRecord& record, bool deepCop fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap)); fPathHeap.reset(SkSafeRef(record.fPathHeap)); + fBitmapUseOffsets.reset(SkSafeRef(record.fBitmapUseOffsets.get())); + // ensure that the paths bounds are pre-computed if (fPathHeap.get()) { for (int i = 0; i < fPathHeap->count(); i++) { @@ -209,7 +206,7 @@ SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInf for (int i = 0; i < paintCount; i++) { if (needs_deep_copy(src.fPaints->at(i))) { deepCopyInfo->paintData[i] = - SkFlatData::Create(&deepCopyInfo->controller, + SkFlatData::Create(&deepCopyInfo->controller, src.fPaints->at(i), 0); } else { @@ -230,8 +227,8 @@ SkPicturePlayback::SkPicturePlayback(const SkPicturePlayback& src, SkPictCopyInf SkTypefacePlayback* tfPlayback = deepCopyInfo->controller.getTypefacePlayback(); for (int i = 0; i < paintCount; i++) { if (deepCopyInfo->paintData[i]) { - deepCopyInfo->paintData[i]->unflatten(&fPaints->writableAt(i), - bmHeap, tfPlayback); + deepCopyInfo->paintData[i]->unflatten( + &fPaints->writableAt(i), bmHeap, tfPlayback); } else { // needs_deep_copy was false, so just need to assign fPaints->writableAt(i) = src.fPaints->at(i); @@ -267,7 +264,7 @@ void SkPicturePlayback::init() { } SkPicturePlayback::~SkPicturePlayback() { - fOpData->unref(); + SkSafeUnref(fOpData); SkSafeUnref(fBitmaps); SkSafeUnref(fPaints); @@ -305,44 +302,49 @@ bool SkPicturePlayback::containsBitmaps() const { /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// -#define PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd') -#define PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't') -#define PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c') -#define PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r') - -// This tag specifies the size of the ReadBuffer, needed for the following tags -#define PICT_BUFFER_SIZE_TAG SkSetFourByteTag('a', 'r', 'a', 'y') -// these are all inside the ARRAYS tag -#define PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p') -#define PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ') -#define PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ') - -// Always write this guy last (with no length field afterwards) -#define PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ') - #include "SkStream.h" -static void writeTagSize(SkWriteBuffer& buffer, uint32_t tag, - uint32_t size) { +static void write_tag_size(SkWriteBuffer& buffer, uint32_t tag, uint32_t size) { buffer.writeUInt(tag); buffer.writeUInt(size); } -static void writeTagSize(SkWStream* stream, uint32_t tag, - uint32_t size) { +static void write_tag_size(SkWStream* stream, uint32_t tag, uint32_t size) { stream->write32(tag); stream->write32(size); } -static void writeFactories(SkWStream* stream, const SkFactorySet& rec) { - int count = rec.count(); +static size_t compute_chunk_size(SkFlattenable::Factory* array, int count) { + size_t size = 4; // for 'count' - writeTagSize(stream, PICT_FACTORY_TAG, count); + for (int i = 0; i < count; i++) { + const char* name = SkFlattenable::FactoryToName(array[i]); + if (NULL == name || 0 == *name) { + size += SkWStream::SizeOfPackedUInt(0); + } else { + size_t len = strlen(name); + size += SkWStream::SizeOfPackedUInt(len); + size += len; + } + } + + return size; +} + +static void write_factories(SkWStream* stream, const SkFactorySet& rec) { + int count = rec.count(); SkAutoSTMalloc<16, SkFlattenable::Factory> storage(count); SkFlattenable::Factory* array = (SkFlattenable::Factory*)storage.get(); rec.copyToArray(array); + size_t size = compute_chunk_size(array, count); + + // TODO: write_tag_size should really take a size_t + write_tag_size(stream, SK_PICT_FACTORY_TAG, (uint32_t) size); + SkDEBUGCODE(size_t start = stream->bytesWritten()); + stream->write32(count); + for (int i = 0; i < count; i++) { const char* name = SkFlattenable::FactoryToName(array[i]); // SkDebugf("---- write factories [%d] %p <%s>\n", i, array[i], name); @@ -354,12 +356,14 @@ static void writeFactories(SkWStream* stream, const SkFactorySet& rec) { stream->write(name, len); } } + + SkASSERT(size == (stream->bytesWritten() - start)); } -static void writeTypefaces(SkWStream* stream, const SkRefCntSet& rec) { +static void write_typefaces(SkWStream* stream, const SkRefCntSet& rec) { int count = rec.count(); - writeTagSize(stream, PICT_TYPEFACE_TAG, count); + write_tag_size(stream, SK_PICT_TYPEFACE_TAG, count); SkAutoSTMalloc<16, SkTypeface*> storage(count); SkTypeface** array = (SkTypeface**)storage.get(); @@ -374,32 +378,32 @@ void SkPicturePlayback::flattenToBuffer(SkWriteBuffer& buffer) const { int i, n; if ((n = SafeCount(fBitmaps)) > 0) { - writeTagSize(buffer, PICT_BITMAP_BUFFER_TAG, n); + write_tag_size(buffer, SK_PICT_BITMAP_BUFFER_TAG, n); for (i = 0; i < n; i++) { buffer.writeBitmap((*fBitmaps)[i]); } } if ((n = SafeCount(fPaints)) > 0) { - writeTagSize(buffer, PICT_PAINT_BUFFER_TAG, n); + write_tag_size(buffer, SK_PICT_PAINT_BUFFER_TAG, n); for (i = 0; i < n; i++) { buffer.writePaint((*fPaints)[i]); } } if ((n = SafeCount(fPathHeap.get())) > 0) { - writeTagSize(buffer, PICT_PATH_BUFFER_TAG, n); + write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n); fPathHeap->flatten(buffer); } } void SkPicturePlayback::serialize(SkWStream* stream, SkPicture::EncodeBitmap encoder) const { - writeTagSize(stream, PICT_READER_TAG, fOpData->size()); + write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size()); stream->write(fOpData->bytes(), fOpData->size()); if (fPictureCount > 0) { - writeTagSize(stream, PICT_PICTURE_TAG, fPictureCount); + write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount); for (int i = 0; i < fPictureCount; i++) { fPictureRefs[i]->serialize(stream, encoder); } @@ -418,25 +422,25 @@ void SkPicturePlayback::serialize(SkWStream* stream, this->flattenToBuffer(buffer); - // We have to write these to sets into the stream *before* we write + // We have to write these two sets into the stream *before* we write // the buffer, since parsing that buffer will require that we already // have these sets available to use. - writeFactories(stream, factSet); - writeTypefaces(stream, typefaceSet); + write_factories(stream, factSet); + write_typefaces(stream, typefaceSet); - writeTagSize(stream, PICT_BUFFER_SIZE_TAG, buffer.bytesWritten()); + write_tag_size(stream, SK_PICT_BUFFER_SIZE_TAG, buffer.bytesWritten()); buffer.writeToStream(stream); } - stream->write32(PICT_EOF_TAG); + stream->write32(SK_PICT_EOF_TAG); } void SkPicturePlayback::flatten(SkWriteBuffer& buffer) const { - writeTagSize(buffer, PICT_READER_TAG, fOpData->size()); + write_tag_size(buffer, SK_PICT_READER_TAG, fOpData->size()); buffer.writeByteArray(fOpData->bytes(), fOpData->size()); if (fPictureCount > 0) { - writeTagSize(buffer, PICT_PICTURE_TAG, fPictureCount); + write_tag_size(buffer, SK_PICT_PICTURE_TAG, fPictureCount); for (int i = 0; i < fPictureCount; i++) { fPictureRefs[i]->flatten(buffer); } @@ -444,7 +448,7 @@ void SkPicturePlayback::flatten(SkWriteBuffer& buffer) const { // Write this picture playback's data into a writebuffer this->flattenToBuffer(buffer); - buffer.write32(PICT_EOF_TAG); + buffer.write32(SK_PICT_EOF_TAG); } /////////////////////////////////////////////////////////////////////////////// @@ -486,7 +490,7 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, SkDEBUGCODE(bool haveBuffer = false;) switch (tag) { - case PICT_READER_TAG: { + case SK_PICT_READER_TAG: { SkAutoMalloc storage(size); if (stream->read(storage.get(), size) != size) { return false; @@ -494,8 +498,19 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, SkASSERT(NULL == fOpData); fOpData = SkData::NewFromMalloc(storage.detach(), size); } break; - case PICT_FACTORY_TAG: { + case SK_PICT_FACTORY_TAG: { SkASSERT(!haveBuffer); + // Remove this code when v21 and below are no longer supported. At the + // same time add a new 'count' variable and use it rather then reusing 'size'. +#ifndef DISABLE_V21_COMPATIBILITY_CODE + if (info.fVersion >= 22) { + // in v22 this tag's size represents the size of the chunk in bytes + // and the number of factory strings is written out separately +#endif + size = stream->readU32(); +#ifndef DISABLE_V21_COMPATIBILITY_CODE + } +#endif fFactoryPlayback = SkNEW_ARGS(SkFactoryPlayback, (size)); for (size_t i = 0; i < size; i++) { SkString str; @@ -507,7 +522,7 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, fFactoryPlayback->base()[i] = SkFlattenable::NameToFactory(str.c_str()); } } break; - case PICT_TYPEFACE_TAG: { + case SK_PICT_TYPEFACE_TAG: { SkASSERT(!haveBuffer); fTFPlayback.setCount(size); for (size_t i = 0; i < size; i++) { @@ -520,7 +535,7 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, fTFPlayback.set(i, tf); } } break; - case PICT_PICTURE_TAG: { + case SK_PICT_PICTURE_TAG: { fPictureCount = size; fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount); bool success = true; @@ -543,7 +558,7 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, return false; } } break; - case PICT_BUFFER_SIZE_TAG: { + case SK_PICT_BUFFER_SIZE_TAG: { SkAutoMalloc storage(size); if (stream->read(storage.get(), size) != size) { return false; @@ -572,7 +587,7 @@ bool SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, bool SkPicturePlayback::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, size_t size) { switch (tag) { - case PICT_BITMAP_BUFFER_TAG: { + case SK_PICT_BITMAP_BUFFER_TAG: { fBitmaps = SkTRefArray::Create(size); for (size_t i = 0; i < size; ++i) { SkBitmap* bm = &fBitmaps->writableAt(i); @@ -580,17 +595,52 @@ bool SkPicturePlayback::parseBufferTag(SkReadBuffer& buffer, bm->setImmutable(); } } break; - case PICT_PAINT_BUFFER_TAG: { + case SK_PICT_PAINT_BUFFER_TAG: { fPaints = SkTRefArray::Create(size); for (size_t i = 0; i < size; ++i) { buffer.readPaint(&fPaints->writableAt(i)); } } break; - case PICT_PATH_BUFFER_TAG: + case SK_PICT_PATH_BUFFER_TAG: if (size > 0) { fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer))); } break; + case SK_PICT_READER_TAG: { + SkAutoMalloc storage(size); + if (!buffer.readByteArray(storage.get(), size) || + !buffer.validate(NULL == fOpData)) { + return false; + } + SkASSERT(NULL == fOpData); + fOpData = SkData::NewFromMalloc(storage.detach(), size); + } break; + case SK_PICT_PICTURE_TAG: { + if (!buffer.validate((0 == fPictureCount) && (NULL == fPictureRefs))) { + return false; + } + fPictureCount = size; + fPictureRefs = SkNEW_ARRAY(SkPicture*, fPictureCount); + bool success = true; + int i = 0; + for ( ; i < fPictureCount; i++) { + fPictureRefs[i] = SkPicture::CreateFromBuffer(buffer); + if (NULL == fPictureRefs[i]) { + success = false; + break; + } + } + if (!success) { + // Delete all of the pictures that were already created (up to but excluding i): + for (int j = 0; j < i; j++) { + fPictureRefs[j]->unref(); + } + // Delete the array + SkDELETE_ARRAY(fPictureRefs); + fPictureCount = 0; + return false; + } + } break; default: // The tag was invalid. return false; @@ -622,7 +672,7 @@ bool SkPicturePlayback::parseStream(SkStream* stream, const SkPictInfo& info, SkPicture::InstallPixelRefProc proc) { for (;;) { uint32_t tag = stream->readU32(); - if (PICT_EOF_TAG == tag) { + if (SK_PICT_EOF_TAG == tag) { break; } @@ -637,7 +687,7 @@ bool SkPicturePlayback::parseStream(SkStream* stream, const SkPictInfo& info, bool SkPicturePlayback::parseBuffer(SkReadBuffer& buffer) { for (;;) { uint32_t tag = buffer.readUInt(); - if (PICT_EOF_TAG == tag) { + if (SK_PICT_EOF_TAG == tag) { break; } @@ -701,13 +751,58 @@ static DrawType read_op_and_size(SkReader32* reader, uint32_t* size) { return (DrawType) op; } +// The activeOps parameter is actually "const SkTDArray&". +// It represents the operations about to be drawn, as generated by some spatial +// subdivision helper class. It should already be in 'fOffset' sorted order. +void SkPicturePlayback::preLoadBitmaps(const SkTDArray& activeOps) { + if (0 == activeOps.count() || NULL == fBitmapUseOffsets) { + return; + } + + SkTDArray active; + + SkAutoTDeleteArray needToCheck(new bool[fBitmapUseOffsets->numIDs()]); + for (int i = 0; i < fBitmapUseOffsets->numIDs(); ++i) { + needToCheck.get()[i] = true; + } + + uint32_t max = ((SkPictureStateTree::Draw*)activeOps[activeOps.count()-1])->fOffset; + + for (int i = 0; i < activeOps.count(); ++i) { + SkPictureStateTree::Draw* draw = (SkPictureStateTree::Draw*) activeOps[i]; + + for (int j = 0; j < fBitmapUseOffsets->numIDs(); ++j) { + if (!needToCheck.get()[j]) { + continue; + } + + if (!fBitmapUseOffsets->overlap(j, draw->fOffset, max)) { + needToCheck.get()[j] = false; + continue; + } + + if (!fBitmapUseOffsets->includes(j, draw->fOffset)) { + continue; + } + + *active.append() = j; + needToCheck.get()[j] = false; + } + } + + for (int i = 0; i < active.count(); ++i) { + SkDebugf("preload texture %d\n", active[i]); + } +} + void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) { #ifdef ENABLE_TIME_DRAW SkAutoTime at("SkPicture::draw", 50); #endif #ifdef SPEW_CLIP_SKIPPING - SkipClipRec skipRect, skipRRect, skipRegion, skipPath; + SkipClipRec skipRect, skipRRect, skipRegion, skipPath, skipCull; + int opCount = 0; #endif #ifdef SK_BUILD_FOR_ANDROID @@ -720,26 +815,26 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) SkReader32 reader(fOpData->bytes(), fOpData->size()); TextContainer text; - SkTDArray results; + SkTDArray activeOps; if (NULL != fStateTree && NULL != fBoundingHierarchy) { SkRect clipBounds; if (canvas.getClipBounds(&clipBounds)) { SkIRect query; clipBounds.roundOut(&query); - fBoundingHierarchy->search(query, &results); - if (results.count() == 0) { + fBoundingHierarchy->search(query, &activeOps); + if (activeOps.count() == 0) { return; } SkTQSort( - reinterpret_cast(results.begin()), - reinterpret_cast(results.end()-1)); + reinterpret_cast(activeOps.begin()), + reinterpret_cast(activeOps.end()-1)); } } SkPictureStateTree::Iterator it = (NULL == fStateTree) ? SkPictureStateTree::Iterator() : - fStateTree->getIterator(results, &canvas); + fStateTree->getIterator(activeOps, &canvas); if (it.isValid()) { uint32_t skipTo = it.draw(); @@ -749,6 +844,8 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) reader.setOffset(skipTo); } + this->preLoadBitmaps(activeOps); + // Record this, so we can concat w/ it if we encounter a setMatrix() SkMatrix initialMatrix = canvas.getTotalMatrix(); int originalSaveCount = canvas.getSaveCount(); @@ -772,6 +869,10 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) } #endif +#ifdef SPEW_CLIP_SKIPPING + opCount++; +#endif + size_t curOffset = reader.offset(); uint32_t size; DrawType op = read_op_and_size(&reader, &size); @@ -814,7 +915,8 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) size_t offsetToRestore = reader.readInt(); SkASSERT(!offsetToRestore || \ offsetToRestore >= reader.offset()); - if (!canvas.clipPath(path, regionOp, doAA) && offsetToRestore) { + canvas.clipPath(path, regionOp, doAA); + if (canvas.isClipEmpty() && offsetToRestore) { #ifdef SPEW_CLIP_SKIPPING skipPath.recordSkip(offsetToRestore - reader.offset()); #endif @@ -829,7 +931,8 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) size_t offsetToRestore = reader.readInt(); SkASSERT(!offsetToRestore || \ offsetToRestore >= reader.offset()); - if (!canvas.clipRegion(region, regionOp) && offsetToRestore) { + canvas.clipRegion(region, regionOp); + if (canvas.isClipEmpty() && offsetToRestore) { #ifdef SPEW_CLIP_SKIPPING skipRegion.recordSkip(offsetToRestore - reader.offset()); #endif @@ -844,7 +947,8 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) size_t offsetToRestore = reader.readInt(); SkASSERT(!offsetToRestore || \ offsetToRestore >= reader.offset()); - if (!canvas.clipRect(rect, regionOp, doAA) && offsetToRestore) { + canvas.clipRect(rect, regionOp, doAA); + if (canvas.isClipEmpty() && offsetToRestore) { #ifdef SPEW_CLIP_SKIPPING skipRect.recordSkip(offsetToRestore - reader.offset()); #endif @@ -860,13 +964,29 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) size_t offsetToRestore = reader.readInt(); SkASSERT(!offsetToRestore || \ offsetToRestore >= reader.offset()); - if (!canvas.clipRRect(rrect, regionOp, doAA) && offsetToRestore) { + canvas.clipRRect(rrect, regionOp, doAA); + if (canvas.isClipEmpty() && offsetToRestore) { #ifdef SPEW_CLIP_SKIPPING skipRRect.recordSkip(offsetToRestore - reader.offset()); #endif reader.setOffset(offsetToRestore); } } break; + case PUSH_CULL: { + const SkRect& cullRect = reader.skipT(); + size_t offsetToRestore = reader.readInt(); + if (offsetToRestore && canvas.quickReject(cullRect)) { +#ifdef SPEW_CLIP_SKIPPING + skipCull.recordSkip(offsetToRestore - reader.offset()); +#endif + reader.setOffset(offsetToRestore); + } else { + canvas.pushCull(cullRect); + } + } break; + case POP_CULL: + canvas.popCull(); + break; case CONCAT: { SkMatrix matrix; this->getMatrix(reader, &matrix); @@ -874,14 +994,14 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) break; } case DRAW_BITMAP: { - const SkPaint* paint = getPaint(reader); - const SkBitmap& bitmap = getBitmap(reader); + const SkPaint* paint = this->getPaint(reader); + const SkBitmap& bitmap = this->getBitmap(reader); const SkPoint& loc = reader.skipT(); canvas.drawBitmap(bitmap, loc.fX, loc.fY, paint); } break; case DRAW_BITMAP_RECT_TO_RECT: { - const SkPaint* paint = getPaint(reader); - const SkBitmap& bitmap = getBitmap(reader); + const SkPaint* paint = this->getPaint(reader); + const SkBitmap& bitmap = this->getBitmap(reader); const SkRect* src = this->getRectPtr(reader); // may be null const SkRect& dst = reader.skipT(); // required SkCanvas::DrawBitmapRectFlags flags; @@ -889,15 +1009,15 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) canvas.drawBitmapRectToRect(bitmap, src, dst, paint, flags); } break; case DRAW_BITMAP_MATRIX: { - const SkPaint* paint = getPaint(reader); - const SkBitmap& bitmap = getBitmap(reader); + const SkPaint* paint = this->getPaint(reader); + const SkBitmap& bitmap = this->getBitmap(reader); SkMatrix matrix; this->getMatrix(reader, &matrix); canvas.drawBitmapMatrix(bitmap, matrix, paint); } break; case DRAW_BITMAP_NINE: { - const SkPaint* paint = getPaint(reader); - const SkBitmap& bitmap = getBitmap(reader); + const SkPaint* paint = this->getPaint(reader); + const SkBitmap& bitmap = this->getBitmap(reader); const SkIRect& src = reader.skipT(); const SkRect& dst = reader.skipT(); canvas.drawBitmapNine(bitmap, src, dst, paint); @@ -910,6 +1030,13 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) canvas.drawData(reader.skip(length), length); // skip handles padding the read out to a multiple of 4 } break; + case DRAW_DRRECT: { + const SkPaint& paint = *this->getPaint(reader); + SkRRect outer, inner; + reader.readRRect(&outer); + reader.readRRect(&inner); + canvas.drawDRRect(outer, inner, paint); + } break; case BEGIN_COMMENT_GROUP: { const char* desc = reader.readString(); canvas.beginCommentGroup(desc); @@ -923,35 +1050,35 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) canvas.endCommentGroup(); } break; case DRAW_OVAL: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); canvas.drawOval(reader.skipT(), paint); } break; case DRAW_PAINT: - canvas.drawPaint(*getPaint(reader)); + canvas.drawPaint(*this->getPaint(reader)); break; case DRAW_PATH: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); canvas.drawPath(getPath(reader), paint); } break; case DRAW_PICTURE: - canvas.drawPicture(getPicture(reader)); + canvas.drawPicture(this->getPicture(reader)); break; case DRAW_POINTS: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); SkCanvas::PointMode mode = (SkCanvas::PointMode)reader.readInt(); size_t count = reader.readInt(); const SkPoint* pts = (const SkPoint*)reader.skip(sizeof(SkPoint) * count); canvas.drawPoints(mode, count, pts, paint); } break; case DRAW_POS_TEXT: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); getText(reader, &text); size_t points = reader.readInt(); const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof(SkPoint)); canvas.drawPosText(text.text(), text.length(), pos, paint); } break; case DRAW_POS_TEXT_TOP_BOTTOM: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); getText(reader, &text); size_t points = reader.readInt(); const SkPoint* pos = (const SkPoint*)reader.skip(points * sizeof(SkPoint)); @@ -962,7 +1089,7 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) } } break; case DRAW_POS_TEXT_H: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); getText(reader, &text); size_t xCount = reader.readInt(); const SkScalar constY = reader.readScalar(); @@ -971,7 +1098,7 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) paint); } break; case DRAW_POS_TEXT_H_TOP_BOTTOM: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); getText(reader, &text); size_t xCount = reader.readInt(); const SkScalar* xpos = (const SkScalar*)reader.skip((3 + xCount) * sizeof(SkScalar)); @@ -984,32 +1111,32 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) } } break; case DRAW_RECT: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); canvas.drawRect(reader.skipT(), paint); } break; case DRAW_RRECT: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); SkRRect rrect; reader.readRRect(&rrect); canvas.drawRRect(rrect, paint); } break; case DRAW_SPRITE: { - const SkPaint* paint = getPaint(reader); - const SkBitmap& bitmap = getBitmap(reader); + const SkPaint* paint = this->getPaint(reader); + const SkBitmap& bitmap = this->getBitmap(reader); int left = reader.readInt(); int top = reader.readInt(); canvas.drawSprite(bitmap, left, top, paint); } break; case DRAW_TEXT: { - const SkPaint& paint = *getPaint(reader); - getText(reader, &text); + const SkPaint& paint = *this->getPaint(reader); + this->getText(reader, &text); SkScalar x = reader.readScalar(); SkScalar y = reader.readScalar(); canvas.drawText(text.text(), text.length(), x, y, paint); } break; case DRAW_TEXT_TOP_BOTTOM: { - const SkPaint& paint = *getPaint(reader); - getText(reader, &text); + const SkPaint& paint = *this->getPaint(reader); + this->getText(reader, &text); const SkScalar* ptr = (const SkScalar*)reader.skip(4 * sizeof(SkScalar)); // ptr[0] == x // ptr[1] == y @@ -1021,16 +1148,16 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) } } break; case DRAW_TEXT_ON_PATH: { - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); getText(reader, &text); - const SkPath& path = getPath(reader); + const SkPath& path = this->getPath(reader); SkMatrix matrix; this->getMatrix(reader, &matrix); canvas.drawTextOnPath(text.text(), text.length(), path, &matrix, paint); } break; case DRAW_VERTICES: { SkAutoTUnref xfer; - const SkPaint& paint = *getPaint(reader); + const SkPaint& paint = *this->getPaint(reader); DrawVertexFlags flags = (DrawVertexFlags)reader.readInt(); SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader.readInt(); int vCount = reader.readInt(); @@ -1073,8 +1200,8 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) canvas.save((SkCanvas::SaveFlags) reader.readInt()); break; case SAVE_LAYER: { - const SkRect* boundsPtr = getRectPtr(reader); - const SkPaint* paint = getPaint(reader); + const SkRect* boundsPtr = this->getRectPtr(reader); + const SkPaint* paint = this->getPaint(reader); canvas.saveLayer(boundsPtr, paint, (SkCanvas::SaveFlags) reader.readInt()); } break; case SCALE: { @@ -1117,10 +1244,12 @@ void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) #ifdef SPEW_CLIP_SKIPPING { - size_t size = skipRect.fSize + skipRRect.fSize + skipPath.fSize + skipRegion.fSize; - SkDebugf("--- Clip skips %d%% rect:%d rrect:%d path:%d rgn:%d\n", + size_t size = skipRect.fSize + skipRRect.fSize + skipPath.fSize + skipRegion.fSize + + skipCull.fSize; + SkDebugf("--- Clip skips %d%% rect:%d rrect:%d path:%d rgn:%d cull:%d\n", size * 100 / reader.offset(), skipRect.fCount, skipRRect.fCount, - skipPath.fCount, skipRegion.fCount); + skipPath.fCount, skipRegion.fCount, skipCull.fCount); + SkDebugf("--- Total ops: %d\n", opCount); } #endif // this->dumpSize(); diff --git a/gfx/skia/trunk/src/core/SkPicturePlayback.h b/gfx/skia/trunk/src/core/SkPicturePlayback.h index 909488b4b7a4..512f24a77e43 100644 --- a/gfx/skia/trunk/src/core/SkPicturePlayback.h +++ b/gfx/skia/trunk/src/core/SkPicturePlayback.h @@ -31,6 +31,7 @@ class SkStream; class SkWStream; class SkBBoxHierarchy; class SkPictureStateTree; +class SkOffsetTable; struct SkPictInfo { enum Flags { @@ -39,12 +40,28 @@ struct SkPictInfo { kPtrIs64Bit_Flag = 1 << 2, }; + char fMagic[8]; uint32_t fVersion; uint32_t fWidth; uint32_t fHeight; uint32_t fFlags; }; +#define SK_PICT_READER_TAG SkSetFourByteTag('r', 'e', 'a', 'd') +#define SK_PICT_FACTORY_TAG SkSetFourByteTag('f', 'a', 'c', 't') +#define SK_PICT_TYPEFACE_TAG SkSetFourByteTag('t', 'p', 'f', 'c') +#define SK_PICT_PICTURE_TAG SkSetFourByteTag('p', 'c', 't', 'r') + +// This tag specifies the size of the ReadBuffer, needed for the following tags +#define SK_PICT_BUFFER_SIZE_TAG SkSetFourByteTag('a', 'r', 'a', 'y') +// these are all inside the ARRAYS tag +#define SK_PICT_BITMAP_BUFFER_TAG SkSetFourByteTag('b', 't', 'm', 'p') +#define SK_PICT_PAINT_BUFFER_TAG SkSetFourByteTag('p', 'n', 't', ' ') +#define SK_PICT_PATH_BUFFER_TAG SkSetFourByteTag('p', 't', 'h', ' ') + +// Always write this guy last (with no length field afterwards) +#define SK_PICT_EOF_TAG SkSetFourByteTag('e', 'o', 'f', ' ') + /** * Container for data that is needed to deep copy a SkPicture. The container * enables the data to be generated once and reused for subsequent copies. @@ -92,6 +109,8 @@ protected: virtual void postDraw(int opIndex); #endif + void preLoadBitmaps(const SkTDArray& results); + private: class TextContainer { public: @@ -210,6 +229,7 @@ private: SkTRefArray* fPaints; SkData* fOpData; // opcodes and parameters + SkAutoTUnref fBitmapUseOffsets; SkPicture** fPictureRefs; int fPictureCount; diff --git a/gfx/skia/trunk/src/core/SkPictureRecord.cpp b/gfx/skia/trunk/src/core/SkPictureRecord.cpp index 042e6a39cb96..55670baa7341 100644 --- a/gfx/skia/trunk/src/core/SkPictureRecord.cpp +++ b/gfx/skia/trunk/src/core/SkPictureRecord.cpp @@ -11,6 +11,7 @@ #include "SkRRect.h" #include "SkBBoxHierarchy.h" #include "SkDevice.h" +#include "SkOffsetTable.h" #include "SkPictureStateTree.h" #include "SkSurface.h" @@ -28,13 +29,14 @@ static const uint32_t kSaveSize = 2 * kUInt32Size; static const uint32_t kSaveLayerNoBoundsSize = 4 * kUInt32Size; static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect); -SkPictureRecord::SkPictureRecord(uint32_t flags, SkBaseDevice* device) - : INHERITED(device) +SkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags) + : INHERITED(dimensions.width(), dimensions.height()) , fBoundingHierarchy(NULL) , fStateTree(NULL) , fFlattenableHeap(HEAP_BLOCK_SIZE) , fPaints(&fFlattenableHeap) - , fRecordFlags(flags) { + , fRecordFlags(flags) + , fOptsEnabled(true) { #ifdef SK_DEBUG_SIZE fPointBytes = fRectBytes = fTextBytes = 0; fPointWrites = fRectWrites = fTextWrites = 0; @@ -43,6 +45,7 @@ SkPictureRecord::SkPictureRecord(uint32_t flags, SkBaseDevice* device) fBitmapHeap = SkNEW(SkBitmapHeap); fFlattenableHeap.setBitmapStorage(fBitmapHeap); fPathHeap = NULL; // lazy allocate + #ifndef SK_COLLAPSE_MATRIX_CLIP_STATE fFirstSavedLayerIndex = kNoSavedLayerIndex; #endif @@ -111,9 +114,13 @@ static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { 0, // BEGIN_GROUP - no paint 0, // COMMENT - no paint 0, // END_GROUP - no paint + 1, // DRAWDRRECT - right after op code + 0, // PUSH_CULL - no paint + 0, // POP_CULL - no paint }; - SkASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1); + SK_COMPILE_ASSERT(sizeof(gPaintOffsets) == LAST_DRAWTYPE_ENUM + 1, + need_to_be_in_sync); SkASSERT((unsigned)op <= (unsigned)LAST_DRAWTYPE_ENUM); int overflow = 0; @@ -139,12 +146,7 @@ static inline uint32_t getPaintOffset(DrawType op, uint32_t opSize) { return gPaintOffsets[op] * sizeof(uint32_t) + overflow; } -SkBaseDevice* SkPictureRecord::setDevice(SkBaseDevice* device) { - SkDEBUGFAIL("eeek, don't try to change the device on a recording canvas"); - return this->INHERITED::setDevice(device); -} - -int SkPictureRecord::save(SaveFlags flags) { +void SkPictureRecord::willSave(SaveFlags flags) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.save(flags); @@ -154,7 +156,8 @@ int SkPictureRecord::save(SaveFlags flags) { fRestoreOffsetStack.push(-(int32_t)fWriter.bytesWritten()); this->recordSave(flags); #endif - return this->INHERITED::save(flags); + + this->INHERITED::willSave(flags); } void SkPictureRecord::recordSave(SaveFlags flags) { @@ -166,12 +169,11 @@ void SkPictureRecord::recordSave(SaveFlags flags) { this->validate(initialOffset, size); } -int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { +SkCanvas::SaveLayerStrategy SkPictureRecord::willSaveLayer(const SkRect* bounds, + const SkPaint* paint, SaveFlags flags) { - int count; #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE - count = fMCMgr.saveLayer(bounds, paint, flags); + fMCMgr.saveLayer(bounds, paint, flags); #else // record the offset to us, making it non-positive to distinguish a save // from a clip entry. @@ -182,15 +184,13 @@ int SkPictureRecord::saveLayer(const SkRect* bounds, const SkPaint* paint, } #endif - /* Don't actually call INHERITED::saveLayer, because that will try to allocate - an offscreen device (potentially very big) which we don't actually need + this->INHERITED::willSaveLayer(bounds, paint, flags); + /* No need for a (potentially very big) layer which we don't actually need at this time (and may not be able to afford since during record our clip starts out the size of the picture, which is often much larger than the size of the actual device we'll use during playback). */ - count = this->INHERITED::save(flags); - this->clipRectBounds(bounds, flags, NULL); - return count; + return kNoLayer_SaveLayerStrategy; } void SkPictureRecord::recordSaveLayer(const SkRect* bounds, const SkPaint* paint, @@ -222,6 +222,15 @@ bool SkPictureRecord::isDrawingToLayer() const { #endif } +/* + * Read the op code from 'offset' in 'writer'. + */ +#ifdef SK_DEBUG +static DrawType peek_op(SkWriter32* writer, int32_t offset) { + return (DrawType)(writer->readTAt(offset) >> 24); +} +#endif + /* * Read the op code from 'offset' in 'writer' and extract the size too. */ @@ -468,6 +477,10 @@ static bool remove_save_layer2(SkWriter32* writer, int32_t offset, result[0], result[3]); } +static bool is_drawing_op(DrawType op) { + return (op > CONCAT && op < ROTATE) || DRAW_DRRECT == op; +} + /* * Restore has just been called (but not recorded), so look back at the * matching save(), and see if we can eliminate the pair of them, due to no @@ -516,7 +529,7 @@ static bool collapse_save_clip_restore(SkWriter32* writer, int32_t offset, offset += opSize; while (offset < restoreOffset) { op = peek_op_and_size(writer, offset, &opSize); - if ((op > CONCAT && op < ROTATE) || (SAVE_LAYER == op)) { + if (is_drawing_op(op) || (SAVE_LAYER == op)) { // drawing verb, abort return false; } @@ -590,7 +603,7 @@ static void apply_optimization_to_bbh(PictureRecordOptType opt, SkPictureStateTr } } -void SkPictureRecord::restore() { +void SkPictureRecord::willRestore() { // FIXME: SkDeferredCanvas needs to be refactored to respect // save/restore balancing so that the following test can be // turned on permanently. @@ -603,7 +616,6 @@ void SkPictureRecord::restore() { return; } - // TODO: don't write the restore to the op stream for normal saves fMCMgr.restore(); #else // check for underflow @@ -616,7 +628,7 @@ void SkPictureRecord::restore() { } size_t opt = 0; - if (!(fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag)) { + if (fOptsEnabled) { for (opt = 0; opt < SK_ARRAY_COUNT(gPictureRecordOpts); ++opt) { if (0 != (gPictureRecordOpts[opt].fFlags & kSkipIfBBoxHierarchy_Flag) && NULL != fBoundingHierarchy) { @@ -631,8 +643,7 @@ void SkPictureRecord::restore() { } } - if ((fRecordFlags & SkPicture::kDisableRecordOptimizations_RecordingFlag) || - SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { + if (!fOptsEnabled || SK_ARRAY_COUNT(gPictureRecordOpts) == opt) { // No optimization fired so add the RESTORE this->recordRestore(); } @@ -640,7 +651,7 @@ void SkPictureRecord::restore() { fRestoreOffsetStack.pop(); #endif - return this->INHERITED::restore(); + this->INHERITED::willRestore(); } void SkPictureRecord::recordRestore(bool fillInSkips) { @@ -653,7 +664,7 @@ void SkPictureRecord::recordRestore(bool fillInSkips) { this->validate(initialOffset, size); } -bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { +void SkPictureRecord::didTranslate(SkScalar dx, SkScalar dy) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.translate(dx, dy); #else @@ -664,10 +675,10 @@ bool SkPictureRecord::translate(SkScalar dx, SkScalar dy) { this->addScalar(dy); this->validate(initialOffset, size); #endif - return this->INHERITED::translate(dx, dy); + this->INHERITED::didTranslate(dx, dy); } -bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { +void SkPictureRecord::didScale(SkScalar sx, SkScalar sy) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.scale(sx, sy); @@ -679,10 +690,10 @@ bool SkPictureRecord::scale(SkScalar sx, SkScalar sy) { this->addScalar(sy); this->validate(initialOffset, size); #endif - return this->INHERITED::scale(sx, sy); + this->INHERITED::didScale(sx, sy); } -bool SkPictureRecord::rotate(SkScalar degrees) { +void SkPictureRecord::didRotate(SkScalar degrees) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.rotate(degrees); @@ -693,10 +704,10 @@ bool SkPictureRecord::rotate(SkScalar degrees) { this->addScalar(degrees); this->validate(initialOffset, size); #endif - return this->INHERITED::rotate(degrees); + this->INHERITED::didRotate(degrees); } -bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { +void SkPictureRecord::didSkew(SkScalar sx, SkScalar sy) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.skew(sx, sy); @@ -708,17 +719,17 @@ bool SkPictureRecord::skew(SkScalar sx, SkScalar sy) { this->addScalar(sy); this->validate(initialOffset, size); #endif - return this->INHERITED::skew(sx, sy); + this->INHERITED::didSkew(sx, sy); } -bool SkPictureRecord::concat(const SkMatrix& matrix) { +void SkPictureRecord::didConcat(const SkMatrix& matrix) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.concat(matrix); #else this->recordConcat(matrix); #endif - return this->INHERITED::concat(matrix); + this->INHERITED::didConcat(matrix); } void SkPictureRecord::recordConcat(const SkMatrix& matrix) { @@ -730,7 +741,7 @@ void SkPictureRecord::recordConcat(const SkMatrix& matrix) { this->validate(initialOffset, size); } -void SkPictureRecord::setMatrix(const SkMatrix& matrix) { +void SkPictureRecord::didSetMatrix(const SkMatrix& matrix) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.setMatrix(matrix); @@ -742,7 +753,7 @@ void SkPictureRecord::setMatrix(const SkMatrix& matrix) { this->addMatrix(matrix); this->validate(initialOffset, size); #endif - this->INHERITED::setMatrix(matrix); + this->INHERITED::didSetMatrix(matrix); } static bool regionOpExpands(SkRegion::Op op) { @@ -836,14 +847,14 @@ int SkPictureRecord::recordRestoreOffsetPlaceholder(SkRegion::Op op) { } #endif -bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { +void SkPictureRecord::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.clipRect(rect, op, doAA); #else - this->recordClipRect(rect, op, doAA); + this->recordClipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); #endif - return this->INHERITED::clipRect(rect, op, doAA); + this->INHERITED::onClipRect(rect, op, edgeStyle); } int SkPictureRecord::recordClipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { @@ -867,20 +878,17 @@ int SkPictureRecord::recordClipRect(const SkRect& rect, SkRegion::Op op, bool do return offset; } -bool SkPictureRecord::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { - if (rrect.isRect()) { - return this->SkPictureRecord::clipRect(rrect.getBounds(), op, doAA); - } +void SkPictureRecord::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.clipRRect(rrect, op, doAA); #else - this->recordClipRRect(rrect, op, doAA); + this->recordClipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); #endif if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { - return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); + this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); } else { - return this->INHERITED::clipRRect(rrect, op, doAA); + this->INHERITED::onClipRRect(rrect, op, edgeStyle); } } @@ -904,25 +912,20 @@ int SkPictureRecord::recordClipRRect(const SkRRect& rrect, SkRegion::Op op, bool return offset; } -bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { - - SkRect r; - if (!path.isInverseFillType() && path.isRect(&r)) { - return this->clipRect(r, op, doAA); - } +void SkPictureRecord::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.clipPath(path, op, doAA); #else int pathID = this->addPathToHeap(path); - this->recordClipPath(pathID, op, doAA); + this->recordClipPath(pathID, op, kSoft_ClipEdgeStyle == edgeStyle); #endif if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) { - return this->updateClipConservativelyUsingBounds(path.getBounds(), op, - path.isInverseFillType()); + this->updateClipConservativelyUsingBounds(path.getBounds(), op, + path.isInverseFillType()); } else { - return this->INHERITED::clipPath(path, op, doAA); + this->INHERITED::onClipPath(path, op, edgeStyle); } } @@ -946,14 +949,14 @@ int SkPictureRecord::recordClipPath(int pathID, SkRegion::Op op, bool doAA) { return offset; } -bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) { +void SkPictureRecord::onClipRegion(const SkRegion& region, SkRegion::Op op) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE fMCMgr.clipRegion(region, op); #else this->recordClipRegion(region, op); #endif - return this->INHERITED::clipRegion(region, op); + this->INHERITED::onClipRegion(region, op); } int SkPictureRecord::recordClipRegion(const SkRegion& region, SkRegion::Op op) { @@ -1074,6 +1077,24 @@ void SkPictureRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) { } } +void SkPictureRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + +#ifdef SK_COLLAPSE_MATRIX_CLIP_STATE + fMCMgr.call(SkMatrixClipStateMgr::kOther_CallType); +#endif + + // op + paint index + rrects + uint32_t initialOffset, size; + size = 2 * kUInt32Size + SkRRect::kSizeInMemory * 2; + initialOffset = this->addDraw(DRAW_DRRECT, &size); + SkASSERT(initialOffset+getPaintOffset(DRAW_DRRECT, size) == fWriter.bytesWritten()); + this->addPaint(paint); + this->addRRect(outer); + this->addRRect(inner); + this->validate(initialOffset, size); +} + void SkPictureRecord::drawPath(const SkPath& path, const SkPaint& paint) { #ifdef SK_COLLAPSE_MATRIX_CLIP_STATE @@ -1104,10 +1125,11 @@ void SkPictureRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar size_t initialOffset = this->addDraw(DRAW_BITMAP, &size); SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP, size) == fWriter.bytesWritten()); this->addPaintPtr(paint); - this->addBitmap(bitmap); + int bitmapID = this->addBitmap(bitmap); this->addScalar(left); this->addScalar(top); this->validate(initialOffset, size); + this->trackBitmapUse(bitmapID, initialOffset); } void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src, @@ -1131,11 +1153,12 @@ void SkPictureRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_RECT_TO_RECT, size) == fWriter.bytesWritten()); this->addPaintPtr(paint); - this->addBitmap(bitmap); + int bitmapID = this->addBitmap(bitmap); this->addRectPtr(src); // may be null this->addRect(dst); this->addInt(flags); this->validate(initialOffset, size); + this->trackBitmapUse(bitmapID, initialOffset); } void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& matrix, @@ -1153,9 +1176,10 @@ void SkPictureRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& m size_t initialOffset = this->addDraw(DRAW_BITMAP_MATRIX, &size); SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_MATRIX, size) == fWriter.bytesWritten()); this->addPaintPtr(paint); - this->addBitmap(bitmap); + int bitmapID = this->addBitmap(bitmap); this->addMatrix(matrix); this->validate(initialOffset, size); + this->trackBitmapUse(bitmapID, initialOffset); } void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, @@ -1173,10 +1197,11 @@ void SkPictureRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& cent size_t initialOffset = this->addDraw(DRAW_BITMAP_NINE, &size); SkASSERT(initialOffset+getPaintOffset(DRAW_BITMAP_NINE, size) == fWriter.bytesWritten()); this->addPaintPtr(paint); - this->addBitmap(bitmap); + int bitmapID = this->addBitmap(bitmap); this->addIRect(center); this->addRect(dst); this->validate(initialOffset, size); + this->trackBitmapUse(bitmapID, initialOffset); } void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, @@ -1194,10 +1219,11 @@ void SkPictureRecord::drawSprite(const SkBitmap& bitmap, int left, int top, size_t initialOffset = this->addDraw(DRAW_SPRITE, &size); SkASSERT(initialOffset+getPaintOffset(DRAW_SPRITE, size) == fWriter.bytesWritten()); this->addPaintPtr(paint); - this->addBitmap(bitmap); + int bitmapID = this->addBitmap(bitmap); this->addInt(left); this->addInt(top); this->validate(initialOffset, size); + this->trackBitmapUse(bitmapID, initialOffset); } void SkPictureRecord::ComputeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]) { @@ -1530,19 +1556,95 @@ void SkPictureRecord::endCommentGroup() { this->validate(initialOffset, size); } +// [op/size] [rect] [skip offset] +static const uint32_t kPushCullOpSize = 2 * kUInt32Size + sizeof(SkRect); +void SkPictureRecord::onPushCull(const SkRect& cullRect) { + // Skip identical cull rects. + if (!fCullOffsetStack.isEmpty()) { + const SkRect& prevCull = fWriter.readTAt(fCullOffsetStack.top() - sizeof(SkRect)); + if (prevCull == cullRect) { + // Skipped culls are tracked on the stack, but they point to the previous offset. + fCullOffsetStack.push(fCullOffsetStack.top()); + return; + } + + SkASSERT(prevCull.contains(cullRect)); + } + + uint32_t size = kPushCullOpSize; + size_t initialOffset = this->addDraw(PUSH_CULL, &size); + // PUSH_CULL's size should stay constant (used to rewind). + SkASSERT(size == kPushCullOpSize); + + this->addRect(cullRect); + fCullOffsetStack.push(fWriter.bytesWritten()); + this->addInt(0); + this->validate(initialOffset, size); +} + +void SkPictureRecord::onPopCull() { + SkASSERT(!fCullOffsetStack.isEmpty()); + + uint32_t cullSkipOffset = fCullOffsetStack.top(); + fCullOffsetStack.pop(); + + // Skipped push, do the same for pop. + if (!fCullOffsetStack.isEmpty() && cullSkipOffset == fCullOffsetStack.top()) { + return; + } + + // Collapse empty push/pop pairs. + if ((size_t)(cullSkipOffset + kUInt32Size) == fWriter.bytesWritten()) { + SkASSERT(fWriter.bytesWritten() >= kPushCullOpSize); + SkASSERT(PUSH_CULL == peek_op(&fWriter, fWriter.bytesWritten() - kPushCullOpSize)); + fWriter.rewindToOffset(fWriter.bytesWritten() - kPushCullOpSize); + return; + } + + // op only + uint32_t size = kUInt32Size; + size_t initialOffset = this->addDraw(POP_CULL, &size); + + // update the cull skip offset to point past this op. + fWriter.overwriteTAt(cullSkipOffset, fWriter.bytesWritten()); + + this->validate(initialOffset, size); +} + /////////////////////////////////////////////////////////////////////////////// SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info) { return SkSurface::NewPicture(info.fWidth, info.fHeight); } -void SkPictureRecord::addBitmap(const SkBitmap& bitmap) { +void SkPictureRecord::trackBitmapUse(int bitmapID, size_t offset) { +#ifndef SK_ALLOW_BITMAP_TRACKING + return; +#endif + + if (!(fRecordFlags & SkPicture::kOptimizeForClippedPlayback_RecordingFlag)) { + return; + } + + if (SkBitmapHeap::INVALID_SLOT == bitmapID) { + return; + } + + if (NULL == fBitmapUseOffsets) { + fBitmapUseOffsets.reset(SkNEW(SkOffsetTable)); + } + + fBitmapUseOffsets->add(bitmapID, offset); +} + +int SkPictureRecord::addBitmap(const SkBitmap& bitmap) { const int index = fBitmapHeap->insert(bitmap); // In debug builds, a bad return value from insert() will crash, allowing for debugging. In // release builds, the invalid value will be recorded so that the reader will know that there // was a problem. SkASSERT(index != SkBitmapHeap::INVALID_SLOT); this->addInt(index); + return index; } void SkPictureRecord::addMatrix(const SkMatrix& matrix) { @@ -1568,7 +1670,11 @@ int SkPictureRecord::addPathToHeap(const SkPath& path) { if (NULL == fPathHeap) { fPathHeap = SkNEW(SkPathHeap); } +#ifdef SK_DEDUP_PICTURE_PATHS + return fPathHeap->insert(path); +#else return fPathHeap->append(path); +#endif } void SkPictureRecord::addPath(const SkPath& path) { diff --git a/gfx/skia/trunk/src/core/SkPictureRecord.h b/gfx/skia/trunk/src/core/SkPictureRecord.h index 0df120b31a12..c0b0eb11de02 100644 --- a/gfx/skia/trunk/src/core/SkPictureRecord.h +++ b/gfx/skia/trunk/src/core/SkPictureRecord.h @@ -19,8 +19,9 @@ #include "SkTemplates.h" #include "SkWriter32.h" -class SkPictureStateTree; class SkBBoxHierarchy; +class SkOffsetTable; +class SkPictureStateTree; // These macros help with packing and unpacking a single byte value and // a 3 byte value into/out of a uint32_t @@ -33,24 +34,9 @@ class SkBBoxHierarchy; class SkPictureRecord : public SkCanvas { public: - SkPictureRecord(uint32_t recordFlags, SkBaseDevice*); + SkPictureRecord(const SkISize& dimensions, uint32_t recordFlags); virtual ~SkPictureRecord(); - virtual SkBaseDevice* setDevice(SkBaseDevice* device) SK_OVERRIDE; - - virtual int save(SaveFlags) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint*, SaveFlags) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE; virtual void clear(SkColor) SK_OVERRIDE; virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(PointMode, size_t count, const SkPoint pts[], @@ -109,6 +95,10 @@ public: void beginRecording(); void endRecording(); + void internalOnly_EnableOpts(bool optsEnabled) { + fOptsEnabled = optsEnabled; + } + private: void handleOptimization(int opt); int recordRestoreOffsetPlaceholder(SkRegion::Op); @@ -122,6 +112,8 @@ private: }; #endif + SkTDArray fCullOffsetStack; + /* * Write the 'drawType' operation and chunk size to the skp. 'size' * can potentially be increased if the chunk size needs its own storage @@ -164,7 +156,9 @@ private: fWriter.writeScalar(scalar); } - void addBitmap(const SkBitmap& bitmap); + // The command at 'offset' in the skp uses the specified bitmap + void trackBitmapUse(int bitmapID, size_t offset); + int addBitmap(const SkBitmap& bitmap); void addMatrix(const SkMatrix& matrix); const SkFlatData* addPaint(const SkPaint& paint) { return this->addPaintPtr(&paint); } const SkFlatData* addPaintPtr(const SkPaint* paint); @@ -221,6 +215,29 @@ public: protected: virtual SkSurface* onNewSurface(const SkImageInfo&) SK_OVERRIDE; + const void* onPeekPixels(SkImageInfo*, size_t*) SK_OVERRIDE { + return NULL; + } + + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; + virtual void onPushCull(const SkRect&) SK_OVERRIDE; + virtual void onPopCull() SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; // Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been // tweaked by paint.computeFastBounds(). @@ -280,7 +297,10 @@ private: SkTDArray fPictureRefs; uint32_t fRecordFlags; - int fInitialSaveCount; + bool fOptsEnabled; + int fInitialSaveCount; + + SkAutoTUnref fBitmapUseOffsets; friend class SkPicturePlayback; friend class SkPictureTester; // for unit testing diff --git a/gfx/skia/trunk/src/core/SkQuadTree.cpp b/gfx/skia/trunk/src/core/SkQuadTree.cpp index 97f86cfb5add..8531823278b1 100644 --- a/gfx/skia/trunk/src/core/SkQuadTree.cpp +++ b/gfx/skia/trunk/src/core/SkQuadTree.cpp @@ -10,188 +10,157 @@ #include #include -class SkQuadTree::QuadTreeNode { -public: - struct Data { - Data(const SkIRect& bounds, void* data) : fBounds(bounds), fInnerBounds(bounds), fData(data) {} - SkIRect fBounds; - SkIRect fInnerBounds; - void* fData; - }; - - QuadTreeNode(const SkIRect& bounds) - : fBounds(bounds) - , fTopLeft(NULL) - , fTopRight(NULL) - , fBottomLeft(NULL) - , fBottomRight(NULL) - , fCanSubdivide((fBounds.width() * fBounds.height()) > 0) {} - - ~QuadTreeNode() { - clear(); - } - - void clear() { - SkDELETE(fTopLeft); - fTopLeft = NULL; - SkDELETE(fTopRight); - fTopRight = NULL; - SkDELETE(fBottomLeft); - fBottomLeft = NULL; - SkDELETE(fBottomRight); - fBottomRight = NULL; - fData.reset(); - } - - const SkIRect& getBounds() const { return fBounds; } - - // Insert data into the QuadTreeNode - bool insert(Data& data) { - // Ignore objects which do not belong in this quad tree - return data.fInnerBounds.intersect(fBounds) && doInsert(data); - } - - // Find all data which appear within a range - void queryRange(const SkIRect& range, SkTDArray* dataInRange) const { - // Automatically abort if the range does not collide with this quad - if (!SkIRect::Intersects(fBounds, range)) { - return; // nothing added to the list - } - - // Check objects at this quad level - for (int i = 0; i < fData.count(); ++i) { - if (SkIRect::Intersects(fData[i].fBounds, range)) { - dataInRange->push(fData[i].fData); - } - } - - // Terminate here, if there are no children - if (!hasChildren()) { - return; - } - - // Otherwise, add the data from the children - fTopLeft->queryRange(range, dataInRange); - fTopRight->queryRange(range, dataInRange); - fBottomLeft->queryRange(range, dataInRange); - fBottomRight->queryRange(range, dataInRange); - } - - int getDepth(int i = 1) const { - if (hasChildren()) { - int depthTL = fTopLeft->getDepth(++i); - int depthTR = fTopRight->getDepth(i); - int depthBL = fBottomLeft->getDepth(i); - int depthBR = fBottomRight->getDepth(i); - return SkTMax(SkTMax(depthTL, depthTR), SkTMax(depthBL, depthBR)); - } - return i; - } - - void rewindInserts(SkBBoxHierarchyClient* client) { - for (int i = fData.count() - 1; i >= 0; --i) { - if (client->shouldRewind(fData[i].fData)) { - fData.remove(i); - } - } - if (hasChildren()) { - fTopLeft->rewindInserts(client); - fTopRight->rewindInserts(client); - fBottomLeft->rewindInserts(client); - fBottomRight->rewindInserts(client); - } - } - -private: - // create four children which fully divide this quad into four quads of equal area - void subdivide() { - if (!hasChildren() && fCanSubdivide) { - SkIPoint center = SkIPoint::Make(fBounds.centerX(), fBounds.centerY()); - fTopLeft = SkNEW_ARGS(QuadTreeNode, (SkIRect::MakeLTRB( - fBounds.fLeft, fBounds.fTop, center.fX, center.fY))); - fTopRight = SkNEW_ARGS(QuadTreeNode, (SkIRect::MakeLTRB( - center.fX, fBounds.fTop, fBounds.fRight, center.fY))); - fBottomLeft = SkNEW_ARGS(QuadTreeNode, (SkIRect::MakeLTRB( - fBounds.fLeft, center.fY, center.fX, fBounds.fBottom))); - fBottomRight = SkNEW_ARGS(QuadTreeNode, (SkIRect::MakeLTRB( - center.fX, center.fY, fBounds.fRight, fBounds.fBottom))); - - // If any of the data can fit entirely into a subregion, move it down now - for (int i = fData.count() - 1; i >= 0; --i) { - // If the data fits entirely into one of the 4 subregions, move that data - // down to that subregion. - if (fTopLeft->doInsert(fData[i]) || - fTopRight->doInsert(fData[i]) || - fBottomLeft->doInsert(fData[i]) || - fBottomRight->doInsert(fData[i])) { - fData.remove(i); - } - } - } - } - - bool doInsert(const Data& data) { - if (!fBounds.contains(data.fInnerBounds)) { - return false; - } - - if (fData.count() > kQuadTreeNodeCapacity) { - subdivide(); - } - - // If there is space in this quad tree, add the object here - // If this quadtree can't be subdivided, we have no choice but to add it here - if ((fData.count() <= kQuadTreeNodeCapacity) || !fCanSubdivide) { - if (fData.isEmpty()) { - fData.setReserve(kQuadTreeNodeCapacity); - } - fData.push(data); - } else if (!fTopLeft->doInsert(data) && !fTopRight->doInsert(data) && - !fBottomLeft->doInsert(data) && !fBottomRight->doInsert(data)) { - // Can't be pushed down to children ? keep it here - fData.push(data); - } - - return true; - } - - bool hasChildren() const { - return (NULL != fTopLeft); - } - - // Arbitrary constant to indicate how many elements can be stored in this quad tree node - enum { kQuadTreeNodeCapacity = 4 }; - - // Bounds of this quad tree - SkIRect fBounds; - - // Data in this quad tree node - SkTDArray fData; - - // Children - QuadTreeNode* fTopLeft; - QuadTreeNode* fTopRight; - QuadTreeNode* fBottomLeft; - QuadTreeNode* fBottomRight; - - // Whether or not this node can have children - bool fCanSubdivide; -}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -SkQuadTree* SkQuadTree::Create(const SkIRect& bounds) { - return new SkQuadTree(bounds); -} +static const int kSplitThreshold = 8; +static const int kMinDimensions = 128; SkQuadTree::SkQuadTree(const SkIRect& bounds) - : fCount(0) - , fRoot(SkNEW_ARGS(QuadTreeNode, (bounds))) { + : fEntryCount(0) + , fRoot(NULL) { SkASSERT((bounds.width() * bounds.height()) > 0); + fRoot = fNodePool.acquire(); + fRoot->fBounds = bounds; } SkQuadTree::~SkQuadTree() { - SkDELETE(fRoot); +} + +SkQuadTree::Node* SkQuadTree::pickChild(Node* node, + const SkIRect& bounds) const { + // is it entirely to the left? + int index = 0; + if (bounds.fRight < node->fSplitPoint.fX) { + // Inside the left side + } else if(bounds.fLeft >= node->fSplitPoint.fX) { + // Inside the right side + index |= 1; + } else { + // Not inside any children + return NULL; + } + if (bounds.fBottom < node->fSplitPoint.fY) { + // Inside the top side + } else if(bounds.fTop >= node->fSplitPoint.fY) { + // Inside the bottom side + index |= 2; + } else { + // Not inside any children + return NULL; + } + return node->fChildren[index]; +} + +void SkQuadTree::insert(Node* node, Entry* entry) { + // does it belong in a child? + if (NULL != node->fChildren[0]) { + Node* child = pickChild(node, entry->fBounds); + if (NULL != child) { + insert(child, entry); + } else { + node->fEntries.push(entry); + } + return; + } + // No children yet, add to this node + node->fEntries.push(entry); + // should I split? + if (node->fEntries.getCount() < kSplitThreshold) { + return; + } + + if ((node->fBounds.width() < kMinDimensions) || + (node->fBounds.height() < kMinDimensions)) { + return; + } + + // Build all the children + node->fSplitPoint = SkIPoint::Make(node->fBounds.centerX(), + node->fBounds.centerY()); + for(int index=0; indexfChildren[index] = fNodePool.acquire(); + } + node->fChildren[0]->fBounds = SkIRect::MakeLTRB( + node->fBounds.fLeft, node->fBounds.fTop, + node->fSplitPoint.fX, node->fSplitPoint.fY); + node->fChildren[1]->fBounds = SkIRect::MakeLTRB( + node->fSplitPoint.fX, node->fBounds.fTop, + node->fBounds.fRight, node->fSplitPoint.fY); + node->fChildren[2]->fBounds = SkIRect::MakeLTRB( + node->fBounds.fLeft, node->fSplitPoint.fY, + node->fSplitPoint.fX, node->fBounds.fBottom); + node->fChildren[3]->fBounds = SkIRect::MakeLTRB( + node->fSplitPoint.fX, node->fSplitPoint.fY, + node->fBounds.fRight, node->fBounds.fBottom); + // reinsert all the entries of this node to allow child trickle + SkTInternalSList entries; + entries.pushAll(&node->fEntries); + while(!entries.isEmpty()) { + insert(node, entries.pop()); + } +} + +void SkQuadTree::search(Node* node, const SkIRect& query, + SkTDArray* results) const { + for (Entry* entry = node->fEntries.head(); NULL != entry; + entry = entry->getSListNext()) { + if (SkIRect::IntersectsNoEmptyCheck(entry->fBounds, query)) { + results->push(entry->fData); + } + } + if (NULL == node->fChildren[0]) { + return; + } + // fast quadrant test + bool left = true; + bool right = true; + if (query.fRight < node->fSplitPoint.fX) { + right = false; + } else if(query.fLeft >= node->fSplitPoint.fX) { + left = false; + } + bool top = true; + bool bottom = true; + if (query.fBottom < node->fSplitPoint.fY) { + bottom = false; + } else if(query.fTop >= node->fSplitPoint.fY) { + top = false; + } + // search all the active quadrants + if (top && left) { + search(node->fChildren[0], query, results); + } + if (top && right) { + search(node->fChildren[1], query, results); + } + if (bottom && left) { + search(node->fChildren[2], query, results); + } + if (bottom && right) { + search(node->fChildren[3], query, results); + } +} + +void SkQuadTree::clear(Node* node) { + // first clear the entries of this node + fEntryPool.releaseAll(&node->fEntries); + // recurse into and clear all child nodes + for(int index=0; indexfChildren[index]; + node->fChildren[index] = NULL; + if (NULL != child) { + clear(child); + fNodePool.release(child); + } + } +} + +int SkQuadTree::getDepth(Node* node) const { + int maxDepth = 0; + if (NULL != node->fChildren[0]) { + for(int index=0; indexfChildren[index])); + } + } + return maxDepth + 1; } void SkQuadTree::insert(void* data, const SkIRect& bounds, bool) { @@ -199,27 +168,54 @@ void SkQuadTree::insert(void* data, const SkIRect& bounds, bool) { SkASSERT(false); return; } - - QuadTreeNode::Data quadTreeData(bounds, data); - fRoot->insert(quadTreeData); - ++fCount; + Entry* entry = fEntryPool.acquire(); + entry->fData = data; + entry->fBounds = bounds; + ++fEntryCount; + if (fRoot->fEntries.isEmpty() && (NULL == fRoot->fChildren[0])) { + fDeferred.push(entry); + } else { + insert(fRoot, entry); + } } void SkQuadTree::search(const SkIRect& query, SkTDArray* results) { + SkASSERT(fDeferred.isEmpty()); SkASSERT(NULL != results); - fRoot->queryRange(query, results); + if (SkIRect::Intersects(fRoot->fBounds, query)) { + search(fRoot, query, results); + } } void SkQuadTree::clear() { - fCount = 0; - fRoot->clear(); + fEntryCount = 0; + clear(fRoot); } int SkQuadTree::getDepth() const { - return fRoot->getDepth(); + return getDepth(fRoot); } void SkQuadTree::rewindInserts() { SkASSERT(fClient); - fRoot->rewindInserts(fClient); + // Currently only supports deferred inserts + SkASSERT(fRoot->fEntries.isEmpty() && fRoot->fChildren[0] == NULL); + SkTInternalSList entries; + entries.pushAll(&fDeferred); + while(!entries.isEmpty()) { + Entry* entry = entries.pop(); + if (fClient->shouldRewind(entry->fData)) { + entry->fData = NULL; + fEntryPool.release(entry); + --fEntryCount; + } else { + fDeferred.push(entry); + } + } +} + +void SkQuadTree::flushDeferredInserts() { + while(!fDeferred.isEmpty()) { + insert(fRoot, fDeferred.pop()); + } } diff --git a/gfx/skia/trunk/src/core/SkQuadTree.h b/gfx/skia/trunk/src/core/SkQuadTree.h index a26174960953..a3b47bdba4ec 100644 --- a/gfx/skia/trunk/src/core/SkQuadTree.h +++ b/gfx/skia/trunk/src/core/SkQuadTree.h @@ -11,9 +11,11 @@ #include "SkRect.h" #include "SkTDArray.h" #include "SkBBoxHierarchy.h" +#include "SkTInternalSList.h" +#include "SkTObjectPool.h" /** - * An QuadTree implementation. In short, it is a tree containing a hierarchy of bounding rectangles + * A QuadTree implementation. In short, it is a tree containing a hierarchy of bounding rectangles * in which each internal node has exactly four children. * * For more details see: @@ -25,9 +27,13 @@ public: SK_DECLARE_INST_COUNT(SkQuadTree) /** - * Create a new QuadTree + * Quad tree constructor. + * @param bounds The bounding box for the root of the quad tree. + * giving the quad tree bounds that fall outside the root + * bounds may result in pathological but correct behavior. */ - static SkQuadTree* Create(const SkIRect& bounds); + SkQuadTree(const SkIRect& bounds); + virtual ~SkQuadTree(); /** @@ -43,7 +49,7 @@ public: /** * If any inserts have been deferred, this will add them into the tree */ - virtual void flushDeferredInserts() SK_OVERRIDE {} + virtual void flushDeferredInserts() SK_OVERRIDE; /** * Given a query rectangle, populates the passed-in array with the elements it intersects @@ -60,19 +66,44 @@ public: /** * This gets the insertion count (rather than the node count) */ - virtual int getCount() const SK_OVERRIDE { return fCount; } + virtual int getCount() const SK_OVERRIDE { return fEntryCount; } virtual void rewindInserts() SK_OVERRIDE; private: - class QuadTreeNode; + struct Entry { + Entry() : fData(NULL) {} + SkIRect fBounds; + void* fData; + SK_DECLARE_INTERNAL_SLIST_INTERFACE(Entry); + }; - SkQuadTree(const SkIRect& bounds); + static const int kChildCount = 4; - // This is the count of data elements (rather than total nodes in the tree) - int fCount; + struct Node { + Node() { + for (int index=0; index fEntries; + SkIRect fBounds; + SkIPoint fSplitPoint; // Only valid if the node has children. + Node* fChildren[kChildCount]; + SK_DECLARE_INTERNAL_SLIST_ADAPTER(Node, fChildren[0]); + }; - QuadTreeNode* fRoot; + SkTObjectPool fEntryPool; + SkTObjectPool fNodePool; + int fEntryCount; + Node* fRoot; + SkTInternalSList fDeferred; + + Node* pickChild(Node* node, const SkIRect& bounds) const; + void insert(Node* node, Entry* entry); + void search(Node* node, const SkIRect& query, SkTDArray* results) const; + void clear(Node* node); + int getDepth(Node* node) const; typedef SkBBoxHierarchy INHERITED; }; diff --git a/gfx/skia/trunk/src/core/SkQuadTreePicture.cpp b/gfx/skia/trunk/src/core/SkQuadTreePicture.cpp index 354b904b56a5..091f4406216d 100644 --- a/gfx/skia/trunk/src/core/SkQuadTreePicture.cpp +++ b/gfx/skia/trunk/src/core/SkQuadTreePicture.cpp @@ -10,5 +10,5 @@ #include "SkQuadTree.h" SkBBoxHierarchy* SkQuadTreePicture::createBBoxHierarchy() const { - return SkQuadTree::Create(fBounds); + return SkNEW_ARGS(SkQuadTree, (fBounds)); } diff --git a/gfx/skia/trunk/src/core/SkRRect.cpp b/gfx/skia/trunk/src/core/SkRRect.cpp index e5296d4e3a7d..915ed75327f5 100644 --- a/gfx/skia/trunk/src/core/SkRRect.cpp +++ b/gfx/skia/trunk/src/core/SkRRect.cpp @@ -172,6 +172,13 @@ bool SkRRect::checkCornerContainment(SkScalar x, SkScalar y) const { return dist <= SkScalarSquare(SkScalarMul(fRadii[index].fX, fRadii[index].fY)); } +bool SkRRect::allCornersCircular() const { + return fRadii[0].fX == fRadii[0].fY && + fRadii[1].fX == fRadii[1].fY && + fRadii[2].fX == fRadii[2].fY && + fRadii[3].fX == fRadii[3].fY; +} + bool SkRRect::contains(const SkRect& rect) const { if (!this->getBounds().contains(rect)) { // If 'rect' isn't contained by the RR's bounds then the diff --git a/gfx/skia/trunk/src/core/SkScaledImageCache.cpp b/gfx/skia/trunk/src/core/SkScaledImageCache.cpp index 6a1264eb6a33..c436417f281b 100644 --- a/gfx/skia/trunk/src/core/SkScaledImageCache.cpp +++ b/gfx/skia/trunk/src/core/SkScaledImageCache.cpp @@ -289,13 +289,12 @@ bool SkScaledImageCacheDiscardableAllocator::allocPixelRef(SkBitmap* bitmap, return false; } - // can relax when we have bitmap::asImageInfo - if (SkBitmap::kARGB_8888_Config != bitmap->config()) { + // can we relax this? + if (kPMColor_SkColorType != bitmap->colorType()) { return false; } - SkImageInfo info = SkImageInfo::MakeN32(bitmap->width(), bitmap->height(), - bitmap->alphaType()); + SkImageInfo info = bitmap->info(); bitmap->setPixelRef(SkNEW_ARGS(SkOneShotDiscardablePixelRef, (info, dm, bitmap->rowBytes())))->unref(); bitmap->lockPixels(); @@ -426,6 +425,7 @@ SkScaledImageCache::ID* SkScaledImageCache::addAndLock(SkScaledImageCache::Rec* if (NULL != existing) { // Since we already have a matching entry, just delete the new one and return. // Call sites cannot assume the passed in object will live past this call. + existing->fBitmap = rec->fBitmap; SkDELETE(rec); return rec_to_id(existing); } diff --git a/gfx/skia/trunk/src/core/SkScalerContext.cpp b/gfx/skia/trunk/src/core/SkScalerContext.cpp index 8a333481c535..d0d24eebe8c0 100644 --- a/gfx/skia/trunk/src/core/SkScalerContext.cpp +++ b/gfx/skia/trunk/src/core/SkScalerContext.cpp @@ -102,7 +102,7 @@ SkScalerContext::SkScalerContext(SkTypeface* typeface, const SkDescriptor* desc) { #ifdef DUMP_REC desc->assertChecksum(); - SkDebugf("SkScalarContext checksum %x count %d length %d\n", + SkDebugf("SkScalerContext checksum %x count %d length %d\n", desc->getChecksum(), desc->getCount(), desc->getLength()); SkDebugf(" textsize %g prescale %g preskew %g post [%g %g %g %g]\n", rec->fTextSize, rec->fPreScaleX, rec->fPreSkewX, rec->fPost2x2[0][0], @@ -428,7 +428,7 @@ static void pack4xHToLCD16(const SkBitmap& src, const SkMask& dst, const SkMaskGamma::PreBlend& maskPreBlend) { #define SAMPLES_PER_PIXEL 4 #define LCD_PER_PIXEL 3 - SkASSERT(SkBitmap::kA8_Config == src.config()); + SkASSERT(kAlpha_8_SkColorType == src.colorType()); SkASSERT(SkMask::kLCD16_Format == dst.fFormat); const int sample_width = src.width(); @@ -502,7 +502,7 @@ static void pack4xHToLCD16(const SkBitmap& src, const SkMask& dst, template static void pack4xHToLCD32(const SkBitmap& src, const SkMask& dst, const SkMaskGamma::PreBlend& maskPreBlend) { - SkASSERT(SkBitmap::kA8_Config == src.config()); + SkASSERT(kAlpha_8_SkColorType == src.colorType()); SkASSERT(SkMask::kLCD32_Format == dst.fFormat); const int width = dst.fBounds.width(); diff --git a/gfx/skia/trunk/src/core/SkShader.cpp b/gfx/skia/trunk/src/core/SkShader.cpp index 47889f0d094d..31b208e2ccdf 100644 --- a/gfx/skia/trunk/src/core/SkShader.cpp +++ b/gfx/skia/trunk/src/core/SkShader.cpp @@ -5,13 +5,13 @@ * found in the LICENSE file. */ - +#include "SkBitmapProcShader.h" +#include "SkReadBuffer.h" +#include "SkMallocPixelRef.h" +#include "SkPaint.h" #include "SkScalar.h" #include "SkShader.h" -#include "SkReadBuffer.h" #include "SkWriteBuffer.h" -#include "SkPaint.h" -#include "SkMallocPixelRef.h" SkShader::SkShader() { fLocalMatrix.reset(); @@ -176,10 +176,10 @@ GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const { SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy) { - return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0); + return ::CreateBitmapShader(src, tmx, tmy, NULL); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkShader::toString(SkString* str) const { if (this->hasLocalMatrix()) { str->append(" "); @@ -309,7 +309,7 @@ SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { return kColor_GradientType; } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkColorShader::toString(SkString* str) const { str->append("SkColorShader: ("); @@ -348,7 +348,7 @@ void SkEmptyShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { SkDEBUGFAIL("should never get called, since setContext() returned false"); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkEmptyShader::toString(SkString* str) const { str->append("SkEmptyShader: ("); diff --git a/gfx/skia/trunk/src/core/SkSmallAllocator.h b/gfx/skia/trunk/src/core/SkSmallAllocator.h new file mode 100644 index 000000000000..2eddb510cd05 --- /dev/null +++ b/gfx/skia/trunk/src/core/SkSmallAllocator.h @@ -0,0 +1,149 @@ +/* + * 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 SkSmallAllocator_DEFINED +#define SkSmallAllocator_DEFINED + +#include "SkTDArray.h" +#include "SkTypes.h" + +// Used by SkSmallAllocator to call the destructor for objects it has +// allocated. +template void destroyT(void* ptr) { + static_cast(ptr)->~T(); +} + +/* + * Template class for allocating small objects without additional heap memory + * allocations. kMaxObjects is a hard limit on the number of objects that can + * be allocated using this class. After that, attempts to create more objects + * with this class will assert and return NULL. + * kTotalBytes is the total number of bytes provided for storage for all + * objects created by this allocator. If an object to be created is larger + * than the storage (minus storage already used), it will be allocated on the + * heap. This class's destructor will handle calling the destructor for each + * object it allocated and freeing its memory. + */ +template +class SkSmallAllocator : public SkNoncopyable { +public: + SkSmallAllocator() + : fStorageUsed(0) + , fNumObjects(0) + {} + + ~SkSmallAllocator() { + // Destruct in reverse order, in case an earlier object points to a + // later object. + while (fNumObjects > 0) { + fNumObjects--; + Rec* rec = &fRecs[fNumObjects]; + rec->fKillProc(rec->fObj); + // Safe to do if fObj is in fStorage, since fHeapStorage will + // point to NULL. + sk_free(rec->fHeapStorage); + } + } + + /* + * Create a new object of type T. Its lifetime will be handled by this + * SkSmallAllocator. + * Each version behaves the same but takes a different number of + * arguments. + * Note: If kMaxObjects have been created by this SkSmallAllocator, NULL + * will be returned. + */ + template + T* createT() { + void* buf = this->reserveT(); + if (NULL == buf) { + return NULL; + } + SkNEW_PLACEMENT(buf, T); + return static_cast(buf); + } + + template T* createT(const A1& a1) { + void* buf = this->reserveT(); + if (NULL == buf) { + return NULL; + } + SkNEW_PLACEMENT_ARGS(buf, T, (a1)); + return static_cast(buf); + } + + template + T* createT(const A1& a1, const A2& a2) { + void* buf = this->reserveT(); + if (NULL == buf) { + return NULL; + } + SkNEW_PLACEMENT_ARGS(buf, T, (a1, a2)); + return static_cast(buf); + } + + template + T* createT(const A1& a1, const A2& a2, const A3& a3) { + void* buf = this->reserveT(); + if (NULL == buf) { + return NULL; + } + SkNEW_PLACEMENT_ARGS(buf, T, (a1, a2, a3)); + return static_cast(buf); + } + + /* + * Reserve a specified amount of space (must be enough space for one T). + * The space will be in fStorage if there is room, or on the heap otherwise. + * Either way, this class will call ~T() in its destructor and free the heap + * allocation if necessary. + * Unlike createT(), this method will not call the constructor of T. + */ + template void* reserveT(size_t storageRequired = sizeof(T)) { + SkASSERT(fNumObjects < kMaxObjects); + SkASSERT(storageRequired >= sizeof(T)); + if (kMaxObjects == fNumObjects) { + return NULL; + } + const size_t storageRemaining = SkAlign4(kTotalBytes) - fStorageUsed; + storageRequired = SkAlign4(storageRequired); + Rec* rec = &fRecs[fNumObjects]; + if (storageRequired > storageRemaining) { + // Allocate on the heap. Ideally we want to avoid this situation, + // but we're not sure we can catch all callers, so handle it but + // assert false in debug mode. + SkASSERT(false); + rec->fHeapStorage = sk_malloc_throw(storageRequired); + rec->fObj = static_cast(rec->fHeapStorage); + } else { + // There is space in fStorage. + rec->fHeapStorage = NULL; + SkASSERT(SkIsAlign4(fStorageUsed)); + rec->fObj = static_cast(fStorage + (fStorageUsed / 4)); + fStorageUsed += storageRequired; + } + rec->fKillProc = destroyT; + fNumObjects++; + return rec->fObj; + } + +private: + struct Rec { + void* fObj; + void* fHeapStorage; + void (*fKillProc)(void*); + }; + + // Number of bytes used so far. + size_t fStorageUsed; + // Pad the storage size to be 4-byte aligned. + uint32_t fStorage[SkAlign4(kTotalBytes) >> 2]; + uint32_t fNumObjects; + Rec fRecs[kMaxObjects]; +}; + +#endif // SkSmallAllocator_DEFINED diff --git a/gfx/skia/trunk/src/core/SkSpriteBlitter.h b/gfx/skia/trunk/src/core/SkSpriteBlitter.h index ae79afe1d8e6..f69a55a2a0bf 100644 --- a/gfx/skia/trunk/src/core/SkSpriteBlitter.h +++ b/gfx/skia/trunk/src/core/SkSpriteBlitter.h @@ -10,8 +10,11 @@ #ifndef SkSpriteBlitter_DEFINED #define SkSpriteBlitter_DEFINED -#include "SkBlitter.h" #include "SkBitmap.h" +#include "SkBitmapProcShader.h" +#include "SkBlitter.h" +#include "SkShader.h" +#include "SkSmallAllocator.h" class SkPaint; @@ -32,9 +35,9 @@ public: #endif static SkSpriteBlitter* ChooseD16(const SkBitmap& source, const SkPaint&, - void* storage, size_t storageSize); + SkTBlitterAllocator*); static SkSpriteBlitter* ChooseD32(const SkBitmap& source, const SkPaint&, - void* storage, size_t storageSize); + SkTBlitterAllocator*); protected: const SkBitmap* fDevice; diff --git a/gfx/skia/trunk/src/core/SkSpriteBlitter_ARGB32.cpp b/gfx/skia/trunk/src/core/SkSpriteBlitter_ARGB32.cpp index 8255336c6599..b05e5033e44d 100644 --- a/gfx/skia/trunk/src/core/SkSpriteBlitter_ARGB32.cpp +++ b/gfx/skia/trunk/src/core/SkSpriteBlitter_ARGB32.cpp @@ -20,7 +20,7 @@ class Sprite_D32_S32 : public SkSpriteBlitter { public: Sprite_D32_S32(const SkBitmap& src, U8CPU alpha) : INHERITED(src) { - SkASSERT(src.config() == SkBitmap::kARGB_8888_Config); + SkASSERT(src.colorType() == kPMColor_SkColorType); unsigned flags32 = 0; if (255 != alpha) { @@ -263,11 +263,10 @@ public: /////////////////////////////////////////////////////////////////////////////// -#include "SkTemplatesPriv.h" +SkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, const SkPaint& paint, + SkTBlitterAllocator* allocator) { + SkASSERT(allocator != NULL); -SkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, - const SkPaint& paint, - void* storage, size_t storageSize) { if (paint.getMaskFilter() != NULL) { return NULL; } @@ -277,33 +276,28 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseD32(const SkBitmap& source, SkColorFilter* filter = paint.getColorFilter(); SkSpriteBlitter* blitter = NULL; - switch (source.config()) { - case SkBitmap::kARGB_4444_Config: + switch (source.colorType()) { + case kARGB_4444_SkColorType: if (alpha != 0xFF) { return NULL; // we only have opaque sprites } if (xfermode || filter) { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_XferFilter, - storage, storageSize, (source, paint)); + blitter = allocator->createT(source, paint); } else if (source.isOpaque()) { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444_Opaque, - storage, storageSize, (source)); + blitter = allocator->createT(source); } else { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S4444, - storage, storageSize, (source)); + blitter = allocator->createT(source); } break; - case SkBitmap::kARGB_8888_Config: + case kPMColor_SkColorType: if (xfermode || filter) { if (255 == alpha) { // this can handle xfermode or filter, but not alpha - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32A_XferFilter, - storage, storageSize, (source, paint)); + blitter = allocator->createT(source, paint); } } else { // this can handle alpha, but not xfermode or filter - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D32_S32, - storage, storageSize, (source, alpha)); + blitter = allocator->createT(source, alpha); } break; default: diff --git a/gfx/skia/trunk/src/core/SkSpriteBlitter_RGB16.cpp b/gfx/skia/trunk/src/core/SkSpriteBlitter_RGB16.cpp index 2bce41e993b7..74c1961dbdf8 100644 --- a/gfx/skia/trunk/src/core/SkSpriteBlitter_RGB16.cpp +++ b/gfx/skia/trunk/src/core/SkSpriteBlitter_RGB16.cpp @@ -306,11 +306,11 @@ private: /////////////////////////////////////////////////////////////////////////////// -#include "SkTemplatesPriv.h" +SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, const SkPaint& paint, + SkTBlitterAllocator* allocator) { + + SkASSERT(allocator != NULL); -SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, - const SkPaint& paint, - void* storage, size_t storageSize) { if (paint.getMaskFilter() != NULL) { // may add cases for this return NULL; } @@ -324,49 +324,41 @@ SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, SkSpriteBlitter* blitter = NULL; unsigned alpha = paint.getAlpha(); - switch (source.config()) { - case SkBitmap::kARGB_8888_Config: - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S32_BlitRowProc, - storage, storageSize, (source)); + switch (source.colorType()) { + case kPMColor_SkColorType: { + blitter = allocator->createT(source); break; - case SkBitmap::kARGB_4444_Config: + } + case kARGB_4444_SkColorType: if (255 == alpha) { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Opaque, - storage, storageSize, (source)); + blitter = allocator->createT(source); } else { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Blend, - storage, storageSize, (source, alpha >> 4)); + blitter = allocator->createT(source, alpha >> 4); } break; - case SkBitmap::kRGB_565_Config: + case kRGB_565_SkColorType: if (255 == alpha) { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Opaque, - storage, storageSize, (source)); + blitter = allocator->createT(source); } else { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Blend, - storage, storageSize, (source, alpha)); + blitter = allocator->createT(source, alpha); } break; - case SkBitmap::kIndex8_Config: + case kIndex_8_SkColorType: if (paint.isDither()) { // we don't support dither yet in these special cases break; } if (source.isOpaque()) { if (255 == alpha) { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Opaque, - storage, storageSize, (source)); + blitter = allocator->createT(source); } else { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Blend, - storage, storageSize, (source, alpha)); + blitter = allocator->createT(source, alpha); } } else { if (255 == alpha) { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Opaque, - storage, storageSize, (source)); + blitter = allocator->createT(source); } else { - SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Blend, - storage, storageSize, (source, alpha)); + blitter = allocator->createT(source, alpha); } } break; diff --git a/gfx/skia/trunk/src/core/SkStream.cpp b/gfx/skia/trunk/src/core/SkStream.cpp index 3350f82fc18c..c60f2a738efb 100644 --- a/gfx/skia/trunk/src/core/SkStream.cpp +++ b/gfx/skia/trunk/src/core/SkStream.cpp @@ -140,6 +140,15 @@ bool SkWStream::writeScalar(SkScalar value) { return this->write(&value, sizeof(value)); } +int SkWStream::SizeOfPackedUInt(size_t value) { + if (value <= SK_MAX_BYTE_FOR_U8) { + return 1; + } else if (value <= 0xFFFF) { + return 3; + } + return 5; +} + bool SkWStream::writePackedUInt(size_t value) { uint8_t data[5]; size_t len = 1; @@ -433,14 +442,20 @@ SkFILEWStream::SkFILEWStream(const char path[]) SkFILEWStream::~SkFILEWStream() { - if (fFILE) + if (fFILE) { sk_fclose(fFILE); + } +} + +size_t SkFILEWStream::bytesWritten() const { + return sk_ftell(fFILE); } bool SkFILEWStream::write(const void* buffer, size_t size) { - if (fFILE == NULL) + if (fFILE == NULL) { return false; + } if (sk_fwrite(buffer, size, fFILE) != size) { @@ -454,8 +469,9 @@ bool SkFILEWStream::write(const void* buffer, size_t size) void SkFILEWStream::flush() { - if (fFILE) + if (fFILE) { sk_fflush(fFILE); + } } //////////////////////////////////////////////////////////////////////// @@ -687,10 +703,10 @@ public: size_t bytesLeftToRead = count; while (fCurrent != NULL) { size_t bytesLeftInCurrent = fCurrent->written() - fCurrentOffset; - size_t bytesFromCurrent = bytesLeftToRead <= bytesLeftInCurrent - ? bytesLeftToRead : bytesLeftInCurrent; + size_t bytesFromCurrent = SkTMin(bytesLeftToRead, bytesLeftInCurrent); if (buffer) { memcpy(buffer, fCurrent->start() + fCurrentOffset, bytesFromCurrent); + buffer = SkTAddOffset(buffer, bytesFromCurrent); } if (bytesLeftToRead <= bytesFromCurrent) { fCurrentOffset += bytesFromCurrent; @@ -698,7 +714,6 @@ public: return count; } bytesLeftToRead -= bytesFromCurrent; - buffer = SkTAddOffset(buffer, bytesFromCurrent); fCurrent = fCurrent->fNext; fCurrentOffset = 0; } @@ -791,6 +806,7 @@ void SkDebugWStream::newline() { #if defined(SK_DEBUG) || defined(SK_DEVELOPER) SkDebugf("\n"); + fBytesWritten++; #endif } @@ -802,6 +818,7 @@ bool SkDebugWStream::write(const void* buffer, size_t size) s[size] = 0; SkDebugf("%s", s); delete[] s; + fBytesWritten += size; #endif return true; } diff --git a/gfx/skia/trunk/src/core/SkTDynamicHash.h b/gfx/skia/trunk/src/core/SkTDynamicHash.h index 8f66c86d907a..80570ae0acb9 100644 --- a/gfx/skia/trunk/src/core/SkTDynamicHash.h +++ b/gfx/skia/trunk/src/core/SkTDynamicHash.h @@ -28,6 +28,33 @@ public: sk_free(fArray); } + class Iter { + public: + explicit Iter(SkTDynamicHash* hash) : fHash(hash), fCurrentIndex(-1) { + SkASSERT(hash); + ++(*this); + } + bool done() const { + SkASSERT(fCurrentIndex <= fHash->fCapacity); + return fCurrentIndex == fHash->fCapacity; + } + T& operator*() const { + SkASSERT(!this->done()); + return *this->current(); + } + void operator++() { + do { + fCurrentIndex++; + } while (!this->done() && (this->current() == Empty() || this->current() == Deleted())); + } + + private: + T* current() const { return fHash->fArray[fCurrentIndex]; } + + SkTDynamicHash* fHash; + int fCurrentIndex; + }; + int count() const { return fCount; } // Return the entry with this key if we have it, otherwise NULL. diff --git a/gfx/skia/trunk/src/core/SkTInternalSList.h b/gfx/skia/trunk/src/core/SkTInternalSList.h new file mode 100644 index 000000000000..4695e5af292b --- /dev/null +++ b/gfx/skia/trunk/src/core/SkTInternalSList.h @@ -0,0 +1,132 @@ +/* + * 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 SkTInternalSList_DEFINED +#define SkTInternalSList_DEFINED + +#include "SkTInternalLList.h" // for SkPtrWrapper + +/** + * This macro creates the methods required by the SkTInternalSList class. + * It should be instantiated in the private block of the class you want to put + * into an SkTInternalSList. + * For most use cases you should use SK_DECLARE_INTERNAL_SLIST_INTERFACE and not + * this macro. If you care about the field name, or want to re-use an existing + * field, then you can use this macro to declare the methods pointing to a + * specific field. + * Unlike SK_DECLARE_INTERNAL_SLIST_INTERFACE this does not declare the field + * itself. + * It also makes SkTInternalSList a friend to give it access to the + * methods. + */ +#define SK_DECLARE_INTERNAL_SLIST_ADAPTER(ClassName, field) \ + ClassName* getSListNext() { \ + return this->field; \ + } \ + void setSListNext(ClassName* next) { \ + this->field = next; \ + } \ + friend class SkTInternalSList + +/** + * This macro declares an fSListNext that auto initializes to NULL and then + * uses SK_DECLARE_INTERNAL_SLIST_ADAPTER to add the methods needed by + * SkTInternalSList. + * It should be instantiated in the private block of the class you want to put + * into an SkTInternalSList. + */ +#define SK_DECLARE_INTERNAL_SLIST_INTERFACE(ClassName) \ + SK_DECLARE_INTERNAL_SLIST_ADAPTER(ClassName, fSListNext); \ + SkPtrWrapper fSListNext + +/** + * An implementation of an intrusive singly linked list. + * The type T must have a methods getSListNext and setSListNext that are visible + * to the list. The easiest way to do this is with + * SK_DECLARE_INTERNAL_SLIST_INTERFACE. + * The list does not maintain ownership of any of its elements, or ever delete + * them. + */ +template class SkTInternalSList { +public: + SkTInternalSList() : fHead(NULL), fCount(0) {} + + /** + * Push an item onto the head of the list. + * This method is *not* thread safe. + */ + void push(T* entry) { + SkASSERT(entry->getSListNext() == NULL); + entry->setSListNext(fHead); + fHead = entry; + ++fCount; + } + + /** + * Takes all the items from another list and pushes them into this list. + * No ordering guarantees are made, the other list will be emptied. + * This method is *not* thread safe. + */ + void pushAll(SkTInternalSList* other) { + if (this->isEmpty()) { + this->swap(other); + return; + } + while (!other->isEmpty()) { + this->push(other->pop()); + } + } + + /** + * Pop an item from the head of the list. + * Returns NULL if the list is empty. + * This method is *not* thread safe. + */ + T* pop() { + if (NULL == fHead) { + return NULL; + } + T* result = fHead; + fHead = result->getSListNext(); + result->setSListNext(NULL); + --fCount; + return result; + } + + T* head() const { + return fHead; + } + + /** + * Returns true if the list has no elements. + */ + bool isEmpty() const { + return NULL == fHead; + } + + /** + * Swaps the contents of this list with another one. + * This method is *not* thread safe. + */ + void swap(SkTInternalSList* other) { + SkTSwap(fHead, other->fHead); + SkTSwap(fCount, other->fCount); + } + + /** + * Returns the count of elements in the list. + */ + int getCount() const { + return fCount; + } +private: + T* fHead; + int fCount; +}; + + +#endif diff --git a/gfx/skia/trunk/src/core/SkTLList.h b/gfx/skia/trunk/src/core/SkTLList.h index 99b5bc67d964..aeae3f72eeb7 100644 --- a/gfx/skia/trunk/src/core/SkTLList.h +++ b/gfx/skia/trunk/src/core/SkTLList.h @@ -198,11 +198,11 @@ public: Iter() {} - Iter(const SkTLList& list, IterStart start) { + Iter(const SkTLList& list, IterStart start = kHead_IterStart) { INHERITED::init(list.fList, start); } - T* init(const SkTLList& list, IterStart start) { + T* init(const SkTLList& list, IterStart start = kHead_IterStart) { return this->nodeToObj(INHERITED::init(list.fList, start)); } diff --git a/gfx/skia/trunk/src/core/SkTObjectPool.h b/gfx/skia/trunk/src/core/SkTObjectPool.h new file mode 100644 index 000000000000..01e8e8e53b24 --- /dev/null +++ b/gfx/skia/trunk/src/core/SkTObjectPool.h @@ -0,0 +1,104 @@ +/* + * 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 SkFreeList_DEFINED +#define SkFreeList_DEFINED + +#include "SkTInternalSList.h" + +/** + * An implementation of a self growing pool of objects. + * It maintains a pool of fully initialized objects. If an attempt is made to + * acquire one, and there are none left, it makes some more. + * It does not automatically reclaim them, they have to be given back to it. + * Constructors will be called on objects allocated by the pool at allocation + * time. + * All allocated objects will be destroyed and memory will be reclaimed when + * the pool is destroyed, so the pool must survive longer than you are using + * any item taken from it. + */ +template class SkTObjectPool { +public: + SkTObjectPool() {} + ~SkTObjectPool() { + while (!fBlocks.isEmpty()) { + SkDELETE(fBlocks.pop()); + } + } + + /** + * Get an item from the pool. + * If the pool has no free items, it will allocate and construct some more. + * The returned item is only valid as long as the pool has not been + * destroyed, at that point all memory allocated by grow will have been + * reclaimed. + * This method is *not* thread safe. + */ + T* acquire() { + if (fAvailable.isEmpty()) { + grow(); + } + return fAvailable.pop(); + } + + /** + * Release an item into the pool. + * The item does not have to have come from the pool, but if it did not + * it must have a lifetime greater than the pool does. + * This method is *not* thread safe. + */ + void release(T* entry) { + fAvailable.push(entry); + } + + /** + * Takes all the items from an SkTInternalSList and adds them back to this + * pool. The other list will be left empty. + */ + void releaseAll(SkTInternalSList* other) { + fAvailable.pushAll(other); + } + + /** + * Returns the number of items immediately available without having to + * construct any new ones. + */ + int available() const { return fAvailable.getCount(); } + + /** + * Returns the number of blocks of items the pool has allocated so far. + */ + int blocks() const { return fBlocks.getCount(); } + +private: + /** + * The type for a new block of entries for the list. + */ + struct Block { + T entries[numItemsPerBlock]; + SK_DECLARE_INTERNAL_SLIST_INTERFACE(Block); + }; + SkTInternalSList fBlocks; + SkTInternalSList fAvailable; + + /** + * When the free list runs out of items, this method is called to allocate + * a new block of them. + * It calls the constructors and then pushes the nodes into the available + * list. + */ + void grow() { + Block* block = SkNEW(Block); + fBlocks.push(block); + for(int index = 0; index < numItemsPerBlock; ++index) { + fAvailable.push(&block->entries[index]); + } + } + +}; + +#endif diff --git a/gfx/skia/trunk/src/core/SkTRefArray.h b/gfx/skia/trunk/src/core/SkTRefArray.h old mode 100755 new mode 100644 diff --git a/gfx/skia/trunk/src/core/SkTemplatesPriv.h b/gfx/skia/trunk/src/core/SkTemplatesPriv.h deleted file mode 100644 index 79ae60933589..000000000000 --- a/gfx/skia/trunk/src/core/SkTemplatesPriv.h +++ /dev/null @@ -1,76 +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 SkTemplatesPriv_DEFINED -#define SkTemplatesPriv_DEFINED - -#include "SkTemplates.h" - -//////////////////////////////////////////////////////////////////////////////// - -#ifdef SK_BUILD_FOR_WIN32 - #define SK_PLACEMENT_NEW(result, classname, storage, storageSize) \ - result = SkNEW(classname) - - #define SK_PLACEMENT_NEW_ARGS(result, classname, storage, storageSize, args) \ - result = SkNEW_ARGS(classname, args) -#else - #include - #define SK_PLACEMENT_NEW(result, classname, storage, storagesize) \ - do { \ - if (storagesize) \ - { \ - SkASSERT(storageSize >= sizeof(classname)); \ - result = new(storage) classname; \ - } \ - else \ - result = SkNEW(classname); \ - } while (0) - - #define SK_PLACEMENT_NEW_ARGS(result, classname, storage, storagesize, args) \ - do { \ - if (storagesize) \ - { \ - SkASSERT(storageSize >= sizeof(classname)); \ - result = new(storage) classname args; \ - } \ - else \ - result = SkNEW_ARGS(classname, args); \ - } while (0) -#endif - -//////////////////////////////////////////////////////////////////////////////// - -template class SkAutoTPlacementDelete { -public: - SkAutoTPlacementDelete(T* obj, void* storage) : fObj(obj), fStorage(storage) - { - } - ~SkAutoTPlacementDelete() - { - if (fObj) - { - if (fObj == fStorage) - fObj->~T(); - else - delete fObj; - } - } - T* detach() - { - T* obj = fObj; - fObj = NULL; - return obj; - } -private: - T* fObj; - void* fStorage; -}; - -#endif diff --git a/gfx/skia/trunk/src/core/SkValidatingReadBuffer.cpp b/gfx/skia/trunk/src/core/SkValidatingReadBuffer.cpp index ae7a83684bc8..8db2c68b9aee 100644 --- a/gfx/skia/trunk/src/core/SkValidatingReadBuffer.cpp +++ b/gfx/skia/trunk/src/core/SkValidatingReadBuffer.cpp @@ -213,10 +213,10 @@ uint32_t SkValidatingReadBuffer::getArrayCount() { void SkValidatingReadBuffer::readBitmap(SkBitmap* bitmap) { const int width = this->readInt(); const int height = this->readInt(); + const bool useBitmapHeap = this->readBool(); const size_t length = this->readUInt(); // A size of zero means the SkBitmap was simply flattened. - this->validate(length == 0); - if (fError) { + if (!this->validate(!useBitmapHeap && (0 == length))) { return; } bitmap->unflatten(*this); diff --git a/gfx/skia/trunk/src/core/SkValidatingReadBuffer.h b/gfx/skia/trunk/src/core/SkValidatingReadBuffer.h index 59b5c1acc3e7..d5e192e1c782 100644 --- a/gfx/skia/trunk/src/core/SkValidatingReadBuffer.h +++ b/gfx/skia/trunk/src/core/SkValidatingReadBuffer.h @@ -75,7 +75,6 @@ private: return SkIsAlign4((uintptr_t)ptr); } - SkReader32 fReader; bool fError; typedef SkReadBuffer INHERITED; diff --git a/gfx/skia/trunk/src/core/SkWriteBuffer.cpp b/gfx/skia/trunk/src/core/SkWriteBuffer.cpp index 450c30ed5cde..cca7d8170ac5 100644 --- a/gfx/skia/trunk/src/core/SkWriteBuffer.cpp +++ b/gfx/skia/trunk/src/core/SkWriteBuffer.cpp @@ -270,15 +270,9 @@ void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { * The distinction is important, since 0-index is 32bits (always), but a * 0-functionptr might be 32 or 64 bits. */ - - SkFlattenable::Factory factory = NULL; - if (flattenable) { - factory = flattenable->getFactory(); - } - if (NULL == factory) { + if (NULL == flattenable) { if (this->isValidating()) { this->writeString(""); - SkASSERT(NULL == flattenable); // We shouldn't get in here in this scenario } else if (fFactorySet != NULL || fNamedFactorySet != NULL) { this->write32(0); } else { @@ -287,6 +281,9 @@ void SkWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) { return; } + SkFlattenable::Factory factory = flattenable->getFactory(); + SkASSERT(factory != NULL); + /* * We can write 1 of 3 versions of the flattenable: * 1. function-ptr : this is the fastest for the reader, but assumes that diff --git a/gfx/skia/trunk/src/core/SkWriter32.cpp b/gfx/skia/trunk/src/core/SkWriter32.cpp index 46150ee7522b..c7bfd92d56aa 100644 --- a/gfx/skia/trunk/src/core/SkWriter32.cpp +++ b/gfx/skia/trunk/src/core/SkWriter32.cpp @@ -63,19 +63,43 @@ size_t SkWriter32::WriteStringSize(const char* str, size_t len) { return SkAlign4(lenBytes + len + 1); } -const size_t kMinBufferBytes = 4096; - void SkWriter32::growToAtLeast(size_t size) { const bool wasExternal = (fExternal != NULL) && (fData == fExternal); - const size_t minCapacity = kMinBufferBytes + - SkTMax(size, fCapacity + (fCapacity >> 1)); - // cause the buffer to grow - fInternal.setCountExact(minCapacity); - fData = fInternal.begin(); - fCapacity = fInternal.reserved(); + fCapacity = 4096 + SkTMax(size, fCapacity + (fCapacity / 2)); + fInternal.realloc(fCapacity); + fData = fInternal.get(); + if (wasExternal) { // we were external, so copy in the data memcpy(fData, fExternal, fUsed); } + // Invalidate the snapshot, we know it is no longer useful. + fSnapshot.reset(NULL); +} + +SkData* SkWriter32::snapshotAsData() const { + // get a non const version of this, we are only conceptually const + SkWriter32& mutable_this = *const_cast(this); + // we use size change detection to invalidate the cached data + if ((fSnapshot.get() != NULL) && (fSnapshot->size() != fUsed)) { + mutable_this.fSnapshot.reset(NULL); + } + if (fSnapshot.get() == NULL) { + uint8_t* buffer = NULL; + if ((fExternal != NULL) && (fData == fExternal)) { + // We need to copy to an allocated buffer before returning. + buffer = (uint8_t*)sk_malloc_throw(fUsed); + memcpy(buffer, fData, fUsed); + } else { + buffer = mutable_this.fInternal.detach(); + // prepare us to do copy on write, by pretending the data buffer + // is external and size limited + mutable_this.fData = buffer; + mutable_this.fCapacity = fUsed; + mutable_this.fExternal = buffer; + } + mutable_this.fSnapshot.reset(SkData::NewFromMalloc(buffer, fUsed)); + } + return SkRef(fSnapshot.get()); // Take an extra ref for the caller. } diff --git a/gfx/skia/trunk/src/core/SkXfermode.cpp b/gfx/skia/trunk/src/core/SkXfermode.cpp index 66e0dea2f552..9b66a66f1714 100644 --- a/gfx/skia/trunk/src/core/SkXfermode.cpp +++ b/gfx/skia/trunk/src/core/SkXfermode.cpp @@ -876,7 +876,7 @@ void SkProcXfermode::flatten(SkWriteBuffer& buffer) const { } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkProcXfermode::toString(SkString* str) const { str->appendf("SkProcXfermode: %p", fProc); } @@ -1413,7 +1413,7 @@ const char* SkXfermode::ModeName(Mode mode) { SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, mode_count); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkProcCoeffXfermode::toString(SkString* str) const { str->append("SkProcCoeffXfermode: "); @@ -1444,15 +1444,18 @@ void SkProcCoeffXfermode::toString(SkString* str) const { class SkClearXfermode : public SkProcCoeffXfermode { public: - SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} + static SkClearXfermode* Create(const ProcCoeff& rec) { + return SkNEW_ARGS(SkClearXfermode, (rec)); + } virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkClearXfermode) private: + SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {} SkClearXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {} @@ -1496,7 +1499,7 @@ void SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst, } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkClearXfermode::toString(SkString* str) const { this->INHERITED::toString(str); } @@ -1506,15 +1509,18 @@ void SkClearXfermode::toString(SkString* str) const { class SkSrcXfermode : public SkProcCoeffXfermode { public: - SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} + static SkSrcXfermode* Create(const ProcCoeff& rec) { + return SkNEW_ARGS(SkSrcXfermode, (rec)); + } virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSrcXfermode) private: + SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {} SkSrcXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {} @@ -1563,7 +1569,7 @@ void SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst, } } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkSrcXfermode::toString(SkString* str) const { this->INHERITED::toString(str); } @@ -1573,14 +1579,17 @@ void SkSrcXfermode::toString(SkString* str) const { class SkDstInXfermode : public SkProcCoeffXfermode { public: - SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} + static SkDstInXfermode* Create(const ProcCoeff& rec) { + return SkNEW_ARGS(SkDstInXfermode, (rec)); + } virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstInXfermode) private: + SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {} SkDstInXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {} typedef SkProcCoeffXfermode INHERITED; @@ -1606,7 +1615,7 @@ void SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst, } while (--count != 0); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkDstInXfermode::toString(SkString* str) const { this->INHERITED::toString(str); } @@ -1616,14 +1625,17 @@ void SkDstInXfermode::toString(SkString* str) const { class SkDstOutXfermode : public SkProcCoeffXfermode { public: - SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} + static SkDstOutXfermode* Create(const ProcCoeff& rec) { + return SkNEW_ARGS(SkDstOutXfermode, (rec)); + } virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstOutXfermode) private: + SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {} SkDstOutXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {} @@ -1650,7 +1662,7 @@ void SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst, } while (--count != 0); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkDstOutXfermode::toString(SkString* str) const { this->INHERITED::toString(str); } @@ -1712,23 +1724,23 @@ SkXfermode* SkXfermode::Create(Mode mode) { // commonly used, so we call those out for their own subclasses here. switch (mode) { case kClear_Mode: - xfer = SkNEW_ARGS(SkClearXfermode, (rec)); + xfer = SkClearXfermode::Create(rec); break; case kSrc_Mode: - xfer = SkNEW_ARGS(SkSrcXfermode, (rec)); + xfer = SkSrcXfermode::Create(rec); break; case kSrcOver_Mode: SkASSERT(false); // should not land here break; case kDstIn_Mode: - xfer = SkNEW_ARGS(SkDstInXfermode, (rec)); + xfer = SkDstInXfermode::Create(rec); break; case kDstOut_Mode: - xfer = SkNEW_ARGS(SkDstOutXfermode, (rec)); + xfer = SkDstOutXfermode::Create(rec); break; default: // no special-case, just rely in the rec and its function-ptrs - xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); + xfer = SkProcCoeffXfermode::Create(rec, mode); break; } } diff --git a/gfx/skia/trunk/src/core/SkXfermode_proccoeff.h b/gfx/skia/trunk/src/core/SkXfermode_proccoeff.h index 1a2f7fcc7f35..b9e645c7cb58 100644 --- a/gfx/skia/trunk/src/core/SkXfermode_proccoeff.h +++ b/gfx/skia/trunk/src/core/SkXfermode_proccoeff.h @@ -15,12 +15,8 @@ struct ProcCoeff { class SkProcCoeffXfermode : public SkProcXfermode { public: - SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) - : INHERITED(rec.fProc) { - fMode = mode; - // these may be valid, or may be CANNOT_USE_COEFF - fSrcCoeff = rec.fSC; - fDstCoeff = rec.fDC; + static SkProcCoeffXfermode* Create(const ProcCoeff& rec, Mode mode) { + return SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); } virtual bool asMode(Mode* mode) const SK_OVERRIDE; @@ -32,10 +28,18 @@ public: GrTexture* background) const SK_OVERRIDE; #endif - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) protected: + SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) + : INHERITED(rec.fProc) { + fMode = mode; + // these may be valid, or may be CANNOT_USE_COEFF + fSrcCoeff = rec.fSC; + fDstCoeff = rec.fDC; + } + SkProcCoeffXfermode(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE; diff --git a/gfx/skia/trunk/src/device/xps/SkXPSDevice.cpp b/gfx/skia/trunk/src/device/xps/SkXPSDevice.cpp index f2658de1047d..e7b5d41fb065 100644 --- a/gfx/skia/trunk/src/device/xps/SkXPSDevice.cpp +++ b/gfx/skia/trunk/src/device/xps/SkXPSDevice.cpp @@ -106,10 +106,11 @@ static HRESULT create_id(wchar_t* buffer, size_t bufferSize, static SkBitmap make_fake_bitmap(int width, int height) { SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kNo_Config, width, height); + bitmap.setConfig(SkImageInfo::MakeUnknown(width, height)); return bitmap; } +// TODO: should inherit from SkBaseDevice instead of SkBitmapDevice... SkXPSDevice::SkXPSDevice() : SkBitmapDevice(make_fake_bitmap(10000, 10000)) , fCurrentPage(0) { @@ -1159,10 +1160,6 @@ HRESULT SkXPSDevice::createXpsQuad(const SkPoint (&points)[4], return S_OK; } -uint32_t SkXPSDevice::getDeviceCapabilities() { - return kVector_Capability; -} - void SkXPSDevice::clear(SkColor color) { //TODO: override this for XPS SkDEBUGF(("XPS clear not yet implemented.")); @@ -2418,11 +2415,7 @@ bool SkXPSDevice::onReadPixels(const SkBitmap& bitmap, int x, int y, return false; } -SkBaseDevice* SkXPSDevice::onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) { - +SkBaseDevice* SkXPSDevice::onCreateDevice(const SkImageInfo&, Usage) { //Conditional for bug compatibility with PDF device. #if 0 if (SkBaseDevice::kGeneral_Usage == usage) { diff --git a/gfx/skia/trunk/src/effects/SkAlphaThresholdFilter.cpp b/gfx/skia/trunk/src/effects/SkAlphaThresholdFilter.cpp index 6b55fdf90e45..f938ba61bbe7 100644 --- a/gfx/skia/trunk/src/effects/SkAlphaThresholdFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkAlphaThresholdFilter.cpp @@ -21,7 +21,7 @@ protected: explicit SkAlphaThresholdFilterImpl(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool asNewEffect(GrEffectRef** effect, GrTexture* texture, @@ -304,16 +304,16 @@ void SkAlphaThresholdFilterImpl::flatten(SkWriteBuffer& buffer) const { } bool SkAlphaThresholdFilterImpl::onFilterImage(Proxy*, const SkBitmap& src, - const SkMatrix& matrix, SkBitmap* dst, + const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { - SkASSERT(src.config() == SkBitmap::kARGB_8888_Config); + SkASSERT(src.colorType() == kPMColor_SkColorType); - if (src.config() != SkBitmap::kARGB_8888_Config) { + if (src.colorType() != kPMColor_SkColorType) { return false; } SkMatrix localInverse; - if (!matrix.invert(&localInverse)) { + if (!ctx.ctm().invert(&localInverse)) { return false; } diff --git a/gfx/skia/trunk/src/effects/SkArithmeticMode.cpp b/gfx/skia/trunk/src/effects/SkArithmeticMode.cpp index 052b06507c26..034ea376743d 100644 --- a/gfx/skia/trunk/src/effects/SkArithmeticMode.cpp +++ b/gfx/skia/trunk/src/effects/SkArithmeticMode.cpp @@ -16,24 +16,20 @@ #include "GrCoordTransform.h" #include "gl/GrGLEffect.h" #include "GrTBackendEffectFactory.h" -#include "SkImageFilterUtils.h" #endif static const bool gUseUnpremul = false; class SkArithmeticMode_scalar : public SkXfermode { public: - SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) { - fK[0] = k1; - fK[1] = k2; - fK[2] = k3; - fK[3] = k4; + static SkArithmeticMode_scalar* Create(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) { + return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4)); } virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, const SkAlpha aa[]) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) #if SK_SUPPORT_GPU @@ -41,6 +37,13 @@ public: #endif private: + SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) { + fK[0] = k1; + fK[1] = k2; + fK[2] = k3; + fK[3] = k4; + } + SkArithmeticMode_scalar(SkReadBuffer& buffer) : INHERITED(buffer) { fK[0] = buffer.readScalar(); fK[1] = buffer.readScalar(); @@ -170,7 +173,7 @@ void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkArithmeticMode_scalar::toString(SkString* str) const { str->append("SkArithmeticMode_scalar: "); for (int i = 0; i < 4; ++i) { @@ -216,7 +219,7 @@ SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4)); #endif } - return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4)); + return SkArithmeticMode_scalar::Create(k1, k2, k3, k4); } diff --git a/gfx/skia/trunk/src/effects/SkAvoidXfermode.cpp b/gfx/skia/trunk/src/effects/SkAvoidXfermode.cpp index a3334926f59c..ffe6a219ab8f 100644 --- a/gfx/skia/trunk/src/effects/SkAvoidXfermode.cpp +++ b/gfx/skia/trunk/src/effects/SkAvoidXfermode.cpp @@ -167,7 +167,7 @@ void SkAvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, // override in subclass } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkAvoidXfermode::toString(SkString* str) const { str->append("SkAvoidXfermode: opColor: "); str->appendHex(fOpColor); diff --git a/gfx/skia/trunk/src/effects/SkBicubicImageFilter.cpp b/gfx/skia/trunk/src/effects/SkBicubicImageFilter.cpp index cf71435cde61..eabf066c7df9 100644 --- a/gfx/skia/trunk/src/effects/SkBicubicImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkBicubicImageFilter.cpp @@ -18,7 +18,6 @@ #include "effects/GrBicubicEffect.h" #include "GrContext.h" #include "GrTexture.h" -#include "SkImageFilterUtils.h" #endif #define DS(x) SkDoubleToScalar(x) @@ -83,16 +82,16 @@ inline SkPMColor cubicBlend(const SkScalar c[16], SkScalar t, SkPMColor c0, SkPM bool SkBicubicImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, - const SkMatrix& matrix, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, &srcOffset)) { + if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } - if (src.config() != SkBitmap::kARGB_8888_Config) { + if (src.colorType() != kPMColor_SkColorType) { return false; } @@ -169,10 +168,10 @@ bool SkBicubicImageFilter::onFilterImage(Proxy* proxy, #if SK_SUPPORT_GPU -bool SkBicubicImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, +bool SkBicubicImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { - SkBitmap srcBM; - if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &srcBM, offset)) { + SkBitmap srcBM = src; + if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &srcBM, offset)) { return false; } GrTexture* srcTexture = srcBM.getTexture(); @@ -198,7 +197,8 @@ bool SkBicubicImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, con SkRect srcRect; srcBM.getBounds(&srcRect); context->drawRectToRect(paint, dstRect, srcRect); - return SkImageFilterUtils::WrapTexture(dst, desc.fWidth, desc.fHeight, result); + WrapTexture(dst, desc.fWidth, desc.fHeight, result); + return true; } #endif diff --git a/gfx/skia/trunk/src/effects/SkBitmapAlphaThresholdShader.cpp b/gfx/skia/trunk/src/effects/SkBitmapAlphaThresholdShader.cpp deleted file mode 100644 index 44db167d4ec2..000000000000 --- a/gfx/skia/trunk/src/effects/SkBitmapAlphaThresholdShader.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkBitmapAlphaThresholdShader.h" - -class BATShader : public SkShader { -public: - SK_DECLARE_INST_COUNT(BATShader); - - BATShader(const SkBitmap& bitmap, SkRegion region, U8CPU); - BATShader(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { - // We should probably do something here. - } - - - virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE {}; - -#if SK_SUPPORT_GPU - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const SK_OVERRIDE; -#endif - - SK_DEVELOPER_TO_STRING(); - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(BATShader) - -private: - SkBitmap fBitmap; - SkRegion fRegion; - U8CPU fThreshold; - - typedef SkShader INHERITED; -}; - -SkShader* SkBitmapAlphaThresholdShader::Create(const SkBitmap& bitmap, - const SkRegion& region, - U8CPU threshold) { - SkASSERT(threshold < 256); - return SkNEW_ARGS(BATShader, (bitmap, region, threshold)); -} - -BATShader::BATShader(const SkBitmap& bitmap, SkRegion region, U8CPU threshold) -: fBitmap(bitmap) -, fRegion(region) -, fThreshold(threshold) { -}; - - -#ifdef SK_DEVELOPER -void BATShader::toString(SkString* str) const { - str->append("BATShader: ("); - - fBitmap.toString(str); - - this->INHERITED::toString(str); - - str->append(")"); -} -#endif - -#if SK_SUPPORT_GPU -#include "GrContext.h" -#include "GrCoordTransform.h" -#include "GrEffect.h" -#include "gl/GrGLEffect.h" -#include "GrTBackendEffectFactory.h" -#include "GrTextureAccess.h" - -#include "SkGr.h" - -/** - * Could create specializations for some simple cases: - * - The region is empty. - * - The region fully contains the bitmap. - * - The regions is 1 rect (or maybe a small number of rects). - */ -class ThresholdEffect : public GrEffect { -public: - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { - return GrTBackendEffectFactory::getInstance(); - } - - static GrEffectRef* Create(GrTexture* bmpTexture, const SkMatrix& bmpMatrix, - GrTexture* maskTexture, const SkMatrix& maskMatrix, - U8CPU threshold) { - SkScalar thresh = SkIntToScalar(threshold) / 255; - - AutoEffectUnref effect(SkNEW_ARGS(ThresholdEffect, (bmpTexture, bmpMatrix, - maskTexture, maskMatrix, - thresh))); - return CreateEffectRef(effect); - } - - virtual void getConstantColorComponents(GrColor* color, - uint32_t* validFlags) const SK_OVERRIDE { - if ((kA_GrColorComponentFlag & *validFlags) && 0 == GrColorUnpackA(*color)) { - return; - } - *validFlags = 0; - return; - } - - static const char* Name() { return "Bitmap Alpha Threshold"; } - - class GLEffect : public GrGLEffect { - public: - GLEffect(const GrBackendEffectFactory& factory, - const GrDrawEffect& e) - : GrGLEffect(factory) - , fPrevThreshold(-SK_Scalar1) { - } - - virtual void emitCode(GrGLShaderBuilder* builder, - const GrDrawEffect& drawEffect, - EffectKey key, - const char* outputColor, - const char* inputColor, - const TransformedCoordsArray& coords, - const TextureSamplerArray& samplers) SK_OVERRIDE { - // put bitmap color in "color" - builder->fsCodeAppend("\t\tvec4 color = "); - builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type()); - builder->fsCodeAppend(";\n"); - - // put alpha from mask texture in "mask" - builder->fsCodeAppend("\t\tfloat mask = "); - builder->fsAppendTextureLookup(samplers[1], coords[1].c_str(), coords[1].type()); - builder->fsCodeAppend(".a;\n"); - - const char* threshold; - - fThresholdUniHandle = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kFloat_GrSLType, - "threshold", - &threshold); - builder->fsCodeAppendf("\t\tfloat thresh = %s;\n", threshold); - - builder->fsCodeAppend("\t\tif (mask < 0.5) {\n" - "\t\t\tif (color.a > thresh) {\n" - "\t\t\t\tfloat scale = thresh / color.a;\n" - "\t\t\t\tcolor.rgb *= scale;\n" - "\t\t\t\tcolor.a = thresh;\n" - "\t\t\t}\n" - "\t\t} else if (color.a < thresh) {\n" - "\t\t\tfloat scale = thresh / color.a;\n" - "\t\t\tcolor.rgb *= scale;\n" - "\t\t\tcolor.a = thresh;\n" - "\t\t}\n"); - - builder->fsCodeAppendf("color = %s = %s;\n", outputColor, - (GrGLSLExpr4(inputColor) * GrGLSLExpr4("color")).c_str()); - } - - virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& e) SK_OVERRIDE { - const ThresholdEffect& effect = e.castEffect(); - if (fPrevThreshold != effect.fThreshold) { - uman.set1f(fThresholdUniHandle, effect.fThreshold); - } - } - - private: - GrGLUniformManager::UniformHandle fThresholdUniHandle; - SkScalar fPrevThreshold; - }; - - GR_DECLARE_EFFECT_TEST; - -private: - ThresholdEffect(GrTexture* bmpTexture, const SkMatrix& bmpMatrix, - GrTexture* maskTexture, const SkMatrix& maskMatrix, - SkScalar threshold) - : fBmpTransform(kLocal_GrCoordSet, bmpMatrix, bmpTexture) - , fBmpAccess(bmpTexture, GrTextureParams()) - , fMaskTransform(kLocal_GrCoordSet, maskMatrix, maskTexture) - , fMaskAccess(maskTexture, GrTextureParams()) - , fThreshold(threshold) { - this->addCoordTransform(&fBmpTransform); - this->addTextureAccess(&fBmpAccess); - this->addCoordTransform(&fMaskTransform); - this->addTextureAccess(&fMaskAccess); - } - - virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { - const ThresholdEffect& e = CastEffect(other); - return e.fBmpAccess.getTexture() == fBmpAccess.getTexture() && - e.fMaskAccess.getTexture() == fMaskAccess.getTexture() && - e.fBmpTransform.getMatrix() == fBmpTransform.getMatrix() && - e.fMaskTransform.getMatrix() == fMaskTransform.getMatrix() && - e.fThreshold == fThreshold; - } - - GrCoordTransform fBmpTransform; - GrTextureAccess fBmpAccess; - GrCoordTransform fMaskTransform; - GrTextureAccess fMaskAccess; - - SkScalar fThreshold; -}; - -GR_DEFINE_EFFECT_TEST(ThresholdEffect); - -GrEffectRef* ThresholdEffect::TestCreate(SkRandom* rand, - GrContext*, - const GrDrawTargetCaps&, - GrTexture* textures[]) { - GrTexture* bmpTex = textures[GrEffectUnitTest::kSkiaPMTextureIdx]; - GrTexture* maskTex = textures[GrEffectUnitTest::kAlphaTextureIdx]; - U8CPU thresh = rand->nextU() % 0xff; - return ThresholdEffect::Create(bmpTex, SkMatrix::I(), maskTex, SkMatrix::I(), thresh); -} - -GrEffectRef* BATShader::asNewEffect(GrContext* context, const SkPaint& paint) const { - SkMatrix localInverse; - if (!this->getLocalMatrix().invert(&localInverse)) { - return NULL; - } - - GrTextureDesc maskDesc; - if (context->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { - maskDesc.fConfig = kAlpha_8_GrPixelConfig; - } else { - maskDesc.fConfig = kRGBA_8888_GrPixelConfig; - } - maskDesc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; - const SkIRect& bounds = fRegion.getBounds(); - // Add one pixel of border to ensure that clamp mode will be all zeros - // the outside. - maskDesc.fWidth = bounds.width() + 2; - maskDesc.fHeight = bounds.height() + 2; - GrAutoScratchTexture ast(context, maskDesc, GrContext::kApprox_ScratchTexMatch); - GrTexture* maskTexture = ast.texture(); - if (NULL == maskTexture) { - return NULL; - } - - GrPaint grPaint; - grPaint.setBlendFunc(kOne_GrBlendCoeff, kZero_GrBlendCoeff); - SkRegion::Iterator iter(fRegion); - context->setRenderTarget(maskTexture->asRenderTarget()); - context->clear(NULL, 0x0, true); - - // offset to ensure border is zero on top/left - SkMatrix matrix; - matrix.setTranslate(SK_Scalar1, SK_Scalar1); - context->setMatrix(matrix); - - while (!iter.done()) { - SkRect rect = SkRect::Make(iter.rect()); - context->drawRect(grPaint, rect); - iter.next(); - } - - GrTexture* bmpTexture = GrLockAndRefCachedBitmapTexture(context, fBitmap, NULL); - if (NULL == bmpTexture) { - return NULL; - } - - SkMatrix bmpMatrix = localInverse; - bmpMatrix.postIDiv(bmpTexture->width(), bmpTexture->height()); - - SkMatrix maskMatrix = localInverse; - // compensate for the border - maskMatrix.postTranslate(SK_Scalar1, SK_Scalar1); - maskMatrix.postIDiv(maskTexture->width(), maskTexture->height()); - - GrEffectRef* effect = ThresholdEffect::Create(bmpTexture, bmpMatrix, - maskTexture, maskMatrix, - fThreshold); - - GrUnlockAndUnrefCachedBitmapTexture(bmpTexture); - - return effect; -} - -#endif diff --git a/gfx/skia/trunk/src/effects/SkBitmapSource.cpp b/gfx/skia/trunk/src/effects/SkBitmapSource.cpp index ec4fcd16fbf5..6834e9e32e9b 100644 --- a/gfx/skia/trunk/src/effects/SkBitmapSource.cpp +++ b/gfx/skia/trunk/src/effects/SkBitmapSource.cpp @@ -42,11 +42,11 @@ void SkBitmapSource::flatten(SkWriteBuffer& buffer) const { buffer.writeRect(fDstRect); } -bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const SkMatrix& matrix, +bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkRect bounds, dstRect; fBitmap.getBounds(&bounds); - matrix.mapRect(&dstRect, fDstRect); + ctx.ctm().mapRect(&dstRect, fDstRect); if (fSrcRect == bounds && dstRect == bounds) { // No regions cropped out or resized; return entire bitmap. *result = fBitmap; @@ -71,7 +71,7 @@ bool SkBitmapSource::onFilterImage(Proxy* proxy, const SkBitmap&, const SkMatrix // None filtering when it's translate-only paint.setFilterLevel( fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ? - SkPaint::kNone_FilterLevel : SkPaint::kMedium_FilterLevel); + SkPaint::kNone_FilterLevel : SkPaint::kHigh_FilterLevel); canvas.drawBitmapRectToRect(fBitmap, &fSrcRect, dstRect, &paint); *result = device.get()->accessBitmap(false); diff --git a/gfx/skia/trunk/src/effects/SkBlurDrawLooper.cpp b/gfx/skia/trunk/src/effects/SkBlurDrawLooper.cpp index 3a5c69737157..2caa62e5ad39 100644 --- a/gfx/skia/trunk/src/effects/SkBlurDrawLooper.cpp +++ b/gfx/skia/trunk/src/effects/SkBlurDrawLooper.cpp @@ -33,7 +33,6 @@ void SkBlurDrawLooper::init(SkScalar sigma, SkScalar dx, SkScalar dy, fDy = dy; fBlurColor = color; fBlurFlags = flags; - fState = kDone; SkASSERT(flags <= kAll_BlurFlag); if (sigma > 0) { @@ -90,11 +89,16 @@ void SkBlurDrawLooper::flatten(SkWriteBuffer& buffer) const { buffer.writeUInt(fBlurFlags); } -void SkBlurDrawLooper::init(SkCanvas*) { - fState = kBeforeEdge; +SkDrawLooper::Context* SkBlurDrawLooper::createContext(SkCanvas*, void* storage) const { + return SkNEW_PLACEMENT_ARGS(storage, BlurDrawLooperContext, (this)); } -bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { +SkBlurDrawLooper::BlurDrawLooperContext::BlurDrawLooperContext( + const SkBlurDrawLooper* looper) + : fLooper(looper), fState(SkBlurDrawLooper::kBeforeEdge) {} + +bool SkBlurDrawLooper::BlurDrawLooperContext::next(SkCanvas* canvas, + SkPaint* paint) { switch (fState) { case kBeforeEdge: // we do nothing if a maskfilter is already installed @@ -104,23 +108,23 @@ bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { } #ifdef SK_BUILD_FOR_ANDROID SkColor blurColor; - blurColor = fBlurColor; + blurColor = fLooper->fBlurColor; if (SkColorGetA(blurColor) == 255) { blurColor = SkColorSetA(blurColor, paint->getAlpha()); } paint->setColor(blurColor); #else - paint->setColor(fBlurColor); + paint->setColor(fLooper->fBlurColor); #endif - paint->setMaskFilter(fBlur); - paint->setColorFilter(fColorFilter); + paint->setMaskFilter(fLooper->fBlur); + paint->setColorFilter(fLooper->fColorFilter); canvas->save(SkCanvas::kMatrix_SaveFlag); - if (fBlurFlags & kIgnoreTransform_BlurFlag) { + if (fLooper->fBlurFlags & kIgnoreTransform_BlurFlag) { SkMatrix transform(canvas->getTotalMatrix()); - transform.postTranslate(fDx, fDy); + transform.postTranslate(fLooper->fDx, fLooper->fDy); canvas->setMatrix(transform); } else { - canvas->translate(fDx, fDy); + canvas->translate(fLooper->fDx, fLooper->fDy); } fState = kAfterEdge; return true; @@ -134,7 +138,7 @@ bool SkBlurDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkBlurDrawLooper::toString(SkString* str) const { str->append("SkBlurDrawLooper: "); diff --git a/gfx/skia/trunk/src/effects/SkBlurImageFilter.cpp b/gfx/skia/trunk/src/effects/SkBlurImageFilter.cpp index a08b9c567549..ffebe54225ee 100644 --- a/gfx/skia/trunk/src/effects/SkBlurImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkBlurImageFilter.cpp @@ -14,7 +14,6 @@ #include "SkBlurImage_opts.h" #if SK_SUPPORT_GPU #include "GrContext.h" -#include "SkImageFilterUtils.h" #endif SkBlurImageFilter::SkBlurImageFilter(SkReadBuffer& buffer) @@ -135,15 +134,20 @@ static void getBox3Params(SkScalar s, int *kernelSize, int* kernelSize3, int *lo } bool SkBlurImageFilter::onFilterImage(Proxy* proxy, - const SkBitmap& source, const SkMatrix& ctm, + const SkBitmap& source, const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, &srcOffset)) { + if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } - if (src.config() != SkBitmap::kARGB_8888_Config) { + if (src.colorType() != kPMColor_SkColorType) { + return false; + } + + SkIRect srcBounds, dstBounds; + if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &srcBounds, &src)) { return false; } @@ -152,13 +156,6 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy, return false; } - SkIRect srcBounds, dstBounds; - src.getBounds(&srcBounds); - srcBounds.offset(srcOffset); - if (!this->applyCropRect(&srcBounds, ctm)) { - return false; - } - dst->setConfig(src.config(), srcBounds.width(), srcBounds.height()); dst->getBounds(&dstBounds); if (!dst->allocPixels()) { @@ -166,7 +163,7 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy, } SkVector sigma, localSigma = SkVector::Make(fSigma.width(), fSigma.height()); - ctm.mapVectors(&sigma, &localSigma, 1); + ctx.ctm().mapVectors(&sigma, &localSigma, 1); int kernelSizeX, kernelSizeX3, lowOffsetX, highOffsetX; int kernelSizeY, kernelSizeY3, lowOffsetY, highOffsetY; @@ -178,7 +175,7 @@ bool SkBlurImageFilter::onFilterImage(Proxy* proxy, } if (kernelSizeX == 0 && kernelSizeY == 0) { - src.copyTo(dst, dst->config()); + src.copyTo(dst, dst->colorType()); offset->fX = srcBounds.fLeft; offset->fY = srcBounds.fTop; return true; @@ -251,23 +248,21 @@ bool SkBlurImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, return true; } -bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, +bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { #if SK_SUPPORT_GPU - SkBitmap input; + SkBitmap input = src; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &input, &srcOffset)) { + if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { + return false; + } + SkIRect rect; + if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &rect, &input)) { return false; } GrTexture* source = input.getTexture(); - SkIRect rect; - src.getBounds(&rect); - rect.offset(srcOffset); - if (!this->applyCropRect(&rect, ctm)) { - return false; - } SkVector sigma, localSigma = SkVector::Make(fSigma.width(), fSigma.height()); - ctm.mapVectors(&sigma, &localSigma, 1); + ctx.ctm().mapVectors(&sigma, &localSigma, 1); offset->fX = rect.fLeft; offset->fY = rect.fTop; rect.offset(-srcOffset); @@ -278,7 +273,8 @@ bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const true, sigma.x(), sigma.y())); - return SkImageFilterUtils::WrapTexture(tex, rect.width(), rect.height(), result); + WrapTexture(tex, rect.width(), rect.height(), result); + return true; #else SkDEBUGFAIL("Should not call in GPU-less build"); return false; diff --git a/gfx/skia/trunk/src/effects/SkBlurMask.cpp b/gfx/skia/trunk/src/effects/SkBlurMask.cpp index 50c16f415152..9712ecc47571 100644 --- a/gfx/skia/trunk/src/effects/SkBlurMask.cpp +++ b/gfx/skia/trunk/src/effects/SkBlurMask.cpp @@ -475,14 +475,6 @@ void SkMask_FreeImage(uint8_t* image) { SkMask::FreeImage(image); } -bool SkBlurMask::Blur(SkMask* dst, const SkMask& src, - SkScalar radius, Style style, Quality quality, - SkIPoint* margin) { - return SkBlurMask::BoxBlur(dst, src, - SkBlurMask::ConvertRadiusToSigma(radius), - style, quality, margin); -} - bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, SkScalar sigma, Style style, Quality quality, SkIPoint* margin) { @@ -741,14 +733,6 @@ void SkBlurMask::ComputeBlurredScanline(uint8_t *pixels, const uint8_t *profile, } } -bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, - SkScalar radius, Style style, - SkIPoint *margin, SkMask::CreateMode createMode) { - return SkBlurMask::BlurRect(SkBlurMask::ConvertRadiusToSigma(radius), - dst, src, - style, margin, createMode); -} - bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, const SkRect &src, Style style, SkIPoint *margin, SkMask::CreateMode createMode) { @@ -850,10 +834,15 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, return true; } -bool SkBlurMask::BlurGroundTruth(SkMask* dst, const SkMask& src, SkScalar radius, - Style style, SkIPoint* margin) { - return BlurGroundTruth(ConvertRadiusToSigma(radius), dst, src, style, margin); +bool SkBlurMask::BlurRRect(SkScalar sigma, SkMask *dst, + const SkRRect &src, Style style, + SkIPoint *margin, SkMask::CreateMode createMode) { + // Temporary for now -- always fail, should cause caller to fall back + // to old path. Plumbing just to land API and parallelize effort. + + return false; } + // The "simple" blur is a direct implementation of separable convolution with a discrete // gaussian kernel. It's "ground truth" in a sense; too slow to be used, but very // useful for correctness comparisons. diff --git a/gfx/skia/trunk/src/effects/SkBlurMask.h b/gfx/skia/trunk/src/effects/SkBlurMask.h index 354fa84f6b1b..eb67d4c9f8b0 100644 --- a/gfx/skia/trunk/src/effects/SkBlurMask.h +++ b/gfx/skia/trunk/src/effects/SkBlurMask.h @@ -12,6 +12,7 @@ #include "SkShader.h" #include "SkMask.h" +#include "SkRRect.h" class SkBlurMask { public: @@ -34,6 +35,11 @@ public: SkIPoint *margin = NULL, SkMask::CreateMode createMode = SkMask::kComputeBoundsAndRenderImage_CreateMode); + static bool BlurRRect(SkScalar sigma, SkMask *dst, const SkRRect &src, + Style style, + SkIPoint *margin = NULL, + SkMask::CreateMode createMode = + SkMask::kComputeBoundsAndRenderImage_CreateMode); static bool BoxBlur(SkMask* dst, const SkMask& src, SkScalar sigma, Style style, Quality quality, SkIPoint* margin = NULL); @@ -44,23 +50,6 @@ public: Style style, SkIPoint* margin = NULL); - SK_ATTR_DEPRECATED("use sigma version") - static bool BlurRect(SkMask *dst, const SkRect &src, - SkScalar radius, Style style, - SkIPoint *margin = NULL, - SkMask::CreateMode createMode = - SkMask::kComputeBoundsAndRenderImage_CreateMode); - - SK_ATTR_DEPRECATED("use sigma version") - static bool Blur(SkMask* dst, const SkMask& src, - SkScalar radius, Style style, Quality quality, - SkIPoint* margin = NULL); - - SK_ATTR_DEPRECATED("use sigma version") - static bool BlurGroundTruth(SkMask* dst, const SkMask& src, - SkScalar radius, Style style, - SkIPoint* margin = NULL); - static SkScalar ConvertRadiusToSigma(SkScalar radius); /* Helper functions for analytic rectangle blurs */ diff --git a/gfx/skia/trunk/src/effects/SkBlurMaskFilter.cpp b/gfx/skia/trunk/src/effects/SkBlurMaskFilter.cpp index 21731c4a31fb..a5cdc4f70399 100644 --- a/gfx/skia/trunk/src/effects/SkBlurMaskFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkBlurMaskFilter.cpp @@ -45,6 +45,10 @@ public: GrPaint* grp, const SkStrokeRec& strokeRec, const SkPath& path) const SK_OVERRIDE; + virtual bool directFilterRRectMaskGPU(GrContext* context, + GrPaint* grp, + const SkStrokeRec& strokeRec, + const SkRRect& rrect) const SK_OVERRIDE; virtual bool filterMaskGPU(GrTexture* src, const SkMatrix& ctm, @@ -55,7 +59,7 @@ public: virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE; - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurMaskFilterImpl) protected: @@ -69,6 +73,8 @@ protected: bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, SkIPoint* margin, SkMask::CreateMode createMode) const; + bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix, + SkIPoint* margin, SkMask::CreateMode createMode) const; private: // To avoid unseemly allocation requests (esp. for finite platforms like @@ -168,6 +174,15 @@ bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, margin, createMode); } +bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, + const SkMatrix& matrix, + SkIPoint* margin, SkMask::CreateMode createMode) const{ + SkScalar sigma = computeXformedSigma(matrix); + + return SkBlurMask::BlurRRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, + margin, createMode); +} + #include "SkCanvas.h" static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { @@ -195,10 +210,7 @@ static bool draw_rrect_into_mask(const SkRRect rrect, SkMask* mask) { // FIXME: This code duplicates code in draw_rects_into_mask, below. Is there a // clean way to share more code? SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kA8_Config, - mask->fBounds.width(), mask->fBounds.height(), - mask->fRowBytes); - bitmap.setPixels(mask->fImage); + bitmap.installMaskPixels(*mask); SkCanvas canvas(bitmap); canvas.translate(-SkIntToScalar(mask->fBounds.left()), @@ -216,10 +228,11 @@ static bool draw_rects_into_mask(const SkRect rects[], int count, SkMask* mask) } SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kA8_Config, - mask->fBounds.width(), mask->fBounds.height(), - mask->fRowBytes); - bitmap.setPixels(mask->fImage); + bitmap.installPixels(SkImageInfo::Make(mask->fBounds.width(), + mask->fBounds.height(), + kAlpha_8_SkColorType, + kPremul_SkAlphaType), + mask->fImage, mask->fRowBytes, NULL, NULL); SkCanvas canvas(bitmap); canvas.translate(-SkIntToScalar(mask->fBounds.left()), @@ -246,6 +259,12 @@ static bool rect_exceeds(const SkRect& r, SkScalar v) { r.width() > v || r.height() > v; } +#ifdef SK_IGNORE_FAST_RRECT_BLUR +SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticRRect", false, "Use the faster analytic blur approach for ninepatch rects" ); +#else +SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticRRect", true, "Use the faster analytic blur approach for ninepatch round rects" ); +#endif + SkMaskFilter::FilterReturn SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& matrix, const SkIRect& clipBounds, @@ -295,7 +314,19 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma srcM.fFormat = SkMask::kA8_Format; srcM.fRowBytes = 0; - if (!this->filterMask(&dstM, srcM, matrix, &margin)) { + bool filterResult = false; + if (c_analyticBlurRRect) { + // special case for fast round rect blur + // don't actually do the blur the first time, just compute the correct size + filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin, + SkMask::kJustComputeBounds_CreateMode); + } + + if (!filterResult) { + filterResult = this->filterMask(&dstM, srcM, matrix, &margin); + } + + if (!filterResult) { return kFalse_FilterReturn; } @@ -339,14 +370,23 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma radii[SkRRect::kLowerLeft_Corner] = LL; smallRR.setRectRadii(smallR, radii); - if (!draw_rrect_into_mask(smallRR, &srcM)) { - return kFalse_FilterReturn; + bool analyticBlurWorked = false; + if (c_analyticBlurRRect) { + analyticBlurWorked = + this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, + SkMask::kComputeBoundsAndRenderImage_CreateMode); } - SkAutoMaskFreeImage amf(srcM.fImage); + if (!analyticBlurWorked) { + if (!draw_rrect_into_mask(smallRR, &srcM)) { + return kFalse_FilterReturn; + } - if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { - return kFalse_FilterReturn; + SkAutoMaskFreeImage amf(srcM.fImage); + + if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { + return kFalse_FilterReturn; + } } patch->fMask.fBounds.offsetTo(0, 0); @@ -356,11 +396,7 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma return kTrue_FilterReturn; } -#ifdef SK_IGNORE_FAST_RECT_BLUR -SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", false, "Use the faster analytic blur approach for ninepatch rects" ); -#else SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); -#endif SkMaskFilter::FilterReturn SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, @@ -783,6 +819,13 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, return true; } +bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, + GrPaint* grp, + const SkStrokeRec& strokeRec, + const SkRRect& rrect) const { + return false; +} + bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds, const SkIRect& clipBounds, const SkMatrix& ctm, @@ -872,7 +915,7 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, #endif // SK_SUPPORT_GPU -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkBlurMaskFilterImpl::toString(SkString* str) const { str->append("SkBlurMaskFilterImpl: ("); diff --git a/gfx/skia/trunk/src/effects/SkColorFilterImageFilter.cpp b/gfx/skia/trunk/src/effects/SkColorFilterImageFilter.cpp index 1f92d1683d96..8cdd546b993b 100755 --- a/gfx/skia/trunk/src/effects/SkColorFilterImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkColorFilterImageFilter.cpp @@ -69,7 +69,7 @@ SkColorFilterImageFilter* SkColorFilterImageFilter::Create(SkColorFilter* cf, if (inputColorFilter->asColorMatrix(inputMatrix) && !matrix_needs_clamping(inputMatrix)) { SkScalar combinedMatrix[20]; mult_color_matrix(inputMatrix, colorMatrix, combinedMatrix); - SkAutoTUnref newCF(SkNEW_ARGS(SkColorMatrixFilter, (combinedMatrix))); + SkAutoTUnref newCF(SkColorMatrixFilter::Create(combinedMatrix)); return SkNEW_ARGS(SkColorFilterImageFilter, (newCF, input->getInput(0), cropRect)); } } @@ -99,19 +99,17 @@ SkColorFilterImageFilter::~SkColorFilterImageFilter() { } bool SkColorFilterImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, - const SkMatrix& matrix, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, &srcOffset)) { + if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } SkIRect bounds; - src.getBounds(&bounds); - bounds.offset(srcOffset); - if (!this->applyCropRect(&bounds, matrix)) { + if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) { return false; } diff --git a/gfx/skia/trunk/src/effects/SkColorFilters.cpp b/gfx/skia/trunk/src/effects/SkColorFilters.cpp index ab32bc66363b..a048abca6b96 100644 --- a/gfx/skia/trunk/src/effects/SkColorFilters.cpp +++ b/gfx/skia/trunk/src/effects/SkColorFilters.cpp @@ -77,7 +77,7 @@ public: } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING virtual void toString(SkString* str) const SK_OVERRIDE { str->append("SkModeColorFilter: color: 0x"); str->appendHex(fColor); @@ -557,7 +557,7 @@ SkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) { SkIntToScalar(SkColorGetG(add)), SkIntToScalar(SkColorGetB(add)), 0); - return SkNEW_ARGS(SkColorMatrixFilter, (matrix)); + return SkColorMatrixFilter::Create(matrix); } SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) diff --git a/gfx/skia/trunk/src/effects/SkColorMatrix.cpp b/gfx/skia/trunk/src/effects/SkColorMatrix.cpp index b07f3d50f9ed..3842285bf404 100644 --- a/gfx/skia/trunk/src/effects/SkColorMatrix.cpp +++ b/gfx/skia/trunk/src/effects/SkColorMatrix.cpp @@ -1,4 +1,3 @@ - /* * Copyright 2011 Google Inc. * @@ -6,8 +5,6 @@ * found in the LICENSE file. */ #include "SkColorMatrix.h" -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" void SkColorMatrix::setIdentity() { memset(fMat, 0, sizeof(fMat)); diff --git a/gfx/skia/trunk/src/effects/SkColorMatrixFilter.cpp b/gfx/skia/trunk/src/effects/SkColorMatrixFilter.cpp index bb8548505081..b60fa84b68d4 100644 --- a/gfx/skia/trunk/src/effects/SkColorMatrixFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkColorMatrixFilter.cpp @@ -424,6 +424,7 @@ public: builder->getUniformCStr(fMatrixHandle), inputColor, builder->getUniformCStr(fVectorHandle)); + builder->fsCodeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor); builder->fsCodeAppendf("\t%s.rgb *= %s.a;\n", outputColor, outputColor); } @@ -483,7 +484,7 @@ GrEffectRef* SkColorMatrixFilter::asNewEffect(GrContext*) const { #endif -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkColorMatrixFilter::toString(SkString* str) const { str->append("SkColorMatrixFilter: "); diff --git a/gfx/skia/trunk/src/effects/SkComposeImageFilter.cpp b/gfx/skia/trunk/src/effects/SkComposeImageFilter.cpp index 842ff48b82e3..645d63372a0c 100644 --- a/gfx/skia/trunk/src/effects/SkComposeImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkComposeImageFilter.cpp @@ -15,7 +15,7 @@ SkComposeImageFilter::~SkComposeImageFilter() { bool SkComposeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkImageFilter* outer = getInput(0); @@ -26,12 +26,12 @@ bool SkComposeImageFilter::onFilterImage(Proxy* proxy, } if (!outer || !inner) { - return (outer ? outer : inner)->filterImage(proxy, src, ctm, result, offset); + return (outer ? outer : inner)->filterImage(proxy, src, ctx, result, offset); } SkBitmap tmp; - return inner->filterImage(proxy, src, ctm, &tmp, offset) && - outer->filterImage(proxy, tmp, ctm, result, offset); + return inner->filterImage(proxy, src, ctx, &tmp, offset) && + outer->filterImage(proxy, tmp, ctx, result, offset); } bool SkComposeImageFilter::onFilterBounds(const SkIRect& src, diff --git a/gfx/skia/trunk/src/effects/SkDashPathEffect.cpp b/gfx/skia/trunk/src/effects/SkDashPathEffect.cpp index 8be5f1d08673..58706c5b78f5 100644 --- a/gfx/skia/trunk/src/effects/SkDashPathEffect.cpp +++ b/gfx/skia/trunk/src/effects/SkDashPathEffect.cpp @@ -530,12 +530,10 @@ bool SkDashPathEffect::asPoints(PointData* results, } SkFlattenable::Factory SkDashPathEffect::getFactory() const { - return fInitialDashLength < 0 ? NULL : CreateProc; + return CreateProc; } void SkDashPathEffect::flatten(SkWriteBuffer& buffer) const { - SkASSERT(fInitialDashLength >= 0); - this->INHERITED::flatten(buffer); buffer.writeInt(fInitialDashIndex); buffer.writeScalar(fInitialDashLength); diff --git a/gfx/skia/trunk/src/effects/SkDisplacementMapEffect.cpp b/gfx/skia/trunk/src/effects/SkDisplacementMapEffect.cpp index a563a6ef8593..4b26a5f84608 100644 --- a/gfx/skia/trunk/src/effects/SkDisplacementMapEffect.cpp +++ b/gfx/skia/trunk/src/effects/SkDisplacementMapEffect.cpp @@ -15,11 +15,12 @@ #include "GrCoordTransform.h" #include "gl/GrGLEffect.h" #include "GrTBackendEffectFactory.h" -#include "SkImageFilterUtils.h" #endif namespace { +#define kChannelSelectorKeyBits 3; // Max value is 4, so 3 bits are required at most + template uint32_t getValue(SkColor, const SkUnPreMultiply::Scale*) { SkDEBUGFAIL("Unknown channel selector"); @@ -193,41 +194,38 @@ void SkDisplacementMapEffect::flatten(SkWriteBuffer& buffer) const { bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { SkBitmap displ = src, color = src; const SkImageFilter* colorInput = getColorInput(); const SkImageFilter* displInput = getDisplacementInput(); SkIPoint colorOffset = SkIPoint::Make(0, 0), displOffset = SkIPoint::Make(0, 0); - if ((colorInput && !colorInput->filterImage(proxy, src, ctm, &color, &colorOffset)) || - (displInput && !displInput->filterImage(proxy, src, ctm, &displ, &displOffset))) { + if ((colorInput && !colorInput->filterImage(proxy, src, ctx, &color, &colorOffset)) || + (displInput && !displInput->filterImage(proxy, src, ctx, &displ, &displOffset))) { return false; } - if ((displ.config() != SkBitmap::kARGB_8888_Config) || - (color.config() != SkBitmap::kARGB_8888_Config)) { - return false; - } - - SkAutoLockPixels alp_displacement(displ), alp_color(color); - if (!displ.getPixels() || !color.getPixels()) { + if ((displ.colorType() != kPMColor_SkColorType) || + (color.colorType() != kPMColor_SkColorType)) { return false; } SkIRect bounds; - color.getBounds(&bounds); - bounds.offset(colorOffset); - if (!this->applyCropRect(&bounds, ctm)) { + // Since computeDisplacement does bounds checking on color pixel access, we don't need to pad + // the color bitmap to bounds here. + if (!this->applyCropRect(ctx, color, colorOffset, &bounds)) { return false; } SkIRect displBounds; - displ.getBounds(&displBounds); - displBounds.offset(displOffset); - if (!this->applyCropRect(&displBounds, ctm)) { + if (!this->applyCropRect(ctx, proxy, displ, &displOffset, &displBounds, &displ)) { return false; } if (!bounds.intersect(displBounds)) { return false; } + SkAutoLockPixels alp_displacement(displ), alp_color(color); + if (!displ.getPixels() || !color.getPixels()) { + return false; + } dst->setConfig(color.config(), bounds.width(), bounds.height()); if (!dst->allocPixels()) { @@ -235,7 +233,7 @@ bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, } SkVector scale = SkVector::Make(fScale, fScale); - ctm.mapVectors(&scale, 1); + ctx.ctm().mapVectors(&scale, 1); SkIRect colorBounds = bounds; colorBounds.offset(-colorOffset); @@ -253,14 +251,18 @@ void SkDisplacementMapEffect::computeFastBounds(const SkRect& src, SkRect* dst) } else { *dst = src; } + dst->outset(fScale * SK_ScalarHalf, fScale * SK_ScalarHalf); } bool SkDisplacementMapEffect::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const { - if (getColorInput()) { - return getColorInput()->filterBounds(src, ctm, dst); + SkIRect bounds = src; + if (getColorInput() && !getColorInput()->filterBounds(src, ctm, &bounds)) { + return false; } - *dst = src; + bounds.outset(SkScalarCeilToInt(fScale * SK_ScalarHalf), + SkScalarCeilToInt(fScale * SK_ScalarHalf)); + *dst = bounds; return true; } @@ -347,21 +349,36 @@ private: typedef GrEffect INHERITED; }; -bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, +bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { - SkBitmap colorBM; + SkBitmap colorBM = src; SkIPoint colorOffset = SkIPoint::Make(0, 0); - if (!SkImageFilterUtils::GetInputResultGPU(getColorInput(), proxy, src, ctm, &colorBM, - &colorOffset)) { + if (getColorInput() && !getColorInput()->getInputResultGPU(proxy, src, ctx, &colorBM, + &colorOffset)) { + return false; + } + SkBitmap displacementBM = src; + SkIPoint displacementOffset = SkIPoint::Make(0, 0); + if (getDisplacementInput() && + !getDisplacementInput()->getInputResultGPU(proxy, src, ctx, &displacementBM, + &displacementOffset)) { + return false; + } + SkIRect bounds; + // Since GrDisplacementMapEffect does bounds checking on color pixel access, we don't need to + // pad the color bitmap to bounds here. + if (!this->applyCropRect(ctx, colorBM, colorOffset, &bounds)) { + return false; + } + SkIRect displBounds; + if (!this->applyCropRect(ctx, proxy, displacementBM, + &displacementOffset, &displBounds, &displacementBM)) { + return false; + } + if (!bounds.intersect(displBounds)) { return false; } GrTexture* color = colorBM.getTexture(); - SkBitmap displacementBM; - SkIPoint displacementOffset = SkIPoint::Make(0, 0); - if (!SkImageFilterUtils::GetInputResultGPU(getDisplacementInput(), proxy, src, ctm, - &displacementBM, &displacementOffset)) { - return false; - } GrTexture* displacement = displacementBM.getTexture(); GrContext* context = color->getContext(); @@ -377,22 +394,7 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, GrContext::AutoRenderTarget art(context, dst->asRenderTarget()); SkVector scale = SkVector::Make(fScale, fScale); - ctm.mapVectors(&scale, 1); - SkIRect bounds; - colorBM.getBounds(&bounds); - bounds.offset(colorOffset); - if (!this->applyCropRect(&bounds, ctm)) { - return false; - } - SkIRect displBounds; - displacementBM.getBounds(&displBounds); - displBounds.offset(displacementOffset); - if (!this->applyCropRect(&displBounds, ctm)) { - return false; - } - if (!bounds.intersect(displBounds)) { - return false; - } + ctx.ctm().mapVectors(&scale, 1); GrPaint paint; SkMatrix offsetMatrix = GrEffect::MakeDivByTextureWHMatrix(displacement); @@ -415,7 +417,8 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, context->drawRect(paint, SkRect::Make(colorBounds)); offset->fX = bounds.left(); offset->fY = bounds.top(); - return SkImageFilterUtils::WrapTexture(dst, bounds.width(), bounds.height(), result); + WrapTexture(dst, bounds.width(), bounds.height(), result); + return true; } /////////////////////////////////////////////////////////////////////////////// @@ -601,7 +604,7 @@ GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrDrawEffect& draw drawEffect.castEffect(); EffectKey xKey = displacementMap.xChannelSelector(); - EffectKey yKey = displacementMap.yChannelSelector() << SkDisplacementMapEffect::kKeyBits; + EffectKey yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBits; return xKey | yKey; } diff --git a/gfx/skia/trunk/src/effects/SkDropShadowImageFilter.cpp b/gfx/skia/trunk/src/effects/SkDropShadowImageFilter.cpp index 6d68a24d43b8..40ab8cf64154 100644 --- a/gfx/skia/trunk/src/effects/SkDropShadowImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkDropShadowImageFilter.cpp @@ -58,17 +58,15 @@ void SkDropShadowImageFilter::flatten(SkWriteBuffer& buffer) const buffer.writeColor(fColor); } -bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, const SkMatrix& matrix, SkBitmap* result, SkIPoint* offset) const +bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, &srcOffset)) + if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) return false; SkIRect bounds; - src.getBounds(&bounds); - bounds.offset(srcOffset); - if (!this->applyCropRect(&bounds, matrix)) { + if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) { return false; } @@ -79,18 +77,19 @@ bool SkDropShadowImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source SkCanvas canvas(device.get()); SkVector sigma, localSigma = SkVector::Make(fSigmaX, fSigmaY); - matrix.mapVectors(&sigma, &localSigma, 1); + ctx.ctm().mapVectors(&sigma, &localSigma, 1); sigma.fX = SkMaxScalar(0, sigma.fX); sigma.fY = SkMaxScalar(0, sigma.fY); - SkAutoTUnref blurFilter(new SkBlurImageFilter(sigma.fX, sigma.fY)); + SkAutoTUnref blurFilter(SkBlurImageFilter::Create(sigma.fX, sigma.fY)); SkAutoTUnref colorFilter(SkColorFilter::CreateModeFilter(fColor, SkXfermode::kSrcIn_Mode)); SkPaint paint; paint.setImageFilter(blurFilter.get()); paint.setColorFilter(colorFilter.get()); paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); SkVector offsetVec, localOffsetVec = SkVector::Make(fDx, fDy); - matrix.mapVectors(&offsetVec, &localOffsetVec, 1); - canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop)); + ctx.ctm().mapVectors(&offsetVec, &localOffsetVec, 1); + canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft), + SkIntToScalar(srcOffset.fY - bounds.fTop)); canvas.drawBitmap(src, offsetVec.fX, offsetVec.fY, &paint); canvas.drawBitmap(src, 0, 0); *result = device->accessBitmap(false); diff --git a/gfx/skia/trunk/src/effects/SkEmbossMaskFilter.cpp b/gfx/skia/trunk/src/effects/SkEmbossMaskFilter.cpp index 6747bf5b388a..19725f1a2e86 100644 --- a/gfx/skia/trunk/src/effects/SkEmbossMaskFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkEmbossMaskFilter.cpp @@ -49,7 +49,7 @@ SkMaskFilter* SkBlurMaskFilter::CreateEmboss(SkScalar blurSigma, const SkScalar light.fAmbient = SkToU8(am); light.fSpecular = SkToU8(sp); - return SkNEW_ARGS(SkEmbossMaskFilter, (blurSigma, light)); + return SkEmbossMaskFilter::Create(blurSigma, light); } /////////////////////////////////////////////////////////////////////////////// @@ -68,13 +68,6 @@ SkEmbossMaskFilter::SkEmbossMaskFilter(SkScalar blurSigma, const Light& light) normalize(fLight.fDirection); } -SkEmbossMaskFilter::SkEmbossMaskFilter(const Light& light, SkScalar blurRadius) - : fLight(light) { - normalize(fLight.fDirection); - - fBlurSigma = SkBlurMask::ConvertRadiusToSigma(blurRadius); -} - SkMask::Format SkEmbossMaskFilter::getFormat() const { return SkMask::k3D_Format; } @@ -147,7 +140,7 @@ void SkEmbossMaskFilter::flatten(SkWriteBuffer& buffer) const { buffer.writeScalar(fBlurSigma); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkEmbossMaskFilter::toString(SkString* str) const { str->append("SkEmbossMaskFilter: ("); diff --git a/gfx/skia/trunk/src/effects/SkKernel33MaskFilter.cpp b/gfx/skia/trunk/src/effects/SkKernel33MaskFilter.cpp index 353661de25db..438e81b03192 100644 --- a/gfx/skia/trunk/src/effects/SkKernel33MaskFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkKernel33MaskFilter.cpp @@ -86,7 +86,7 @@ SkKernel33ProcMaskFilter::SkKernel33ProcMaskFilter(SkReadBuffer& rb) fPercent256 = rb.readInt(); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkKernel33ProcMaskFilter::toString(SkString* str) const { str->appendf("percent256: %d, ", fPercent256); } @@ -126,7 +126,7 @@ SkKernel33MaskFilter::SkKernel33MaskFilter(SkReadBuffer& rb) fShift = rb.readInt(); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkKernel33MaskFilter::toString(SkString* str) const { str->append("SkKernel33MaskFilter: ("); diff --git a/gfx/skia/trunk/src/effects/SkLayerDrawLooper.cpp b/gfx/skia/trunk/src/effects/SkLayerDrawLooper.cpp index 6c7c3cef0cb0..962ca293d841 100644 --- a/gfx/skia/trunk/src/effects/SkLayerDrawLooper.cpp +++ b/gfx/skia/trunk/src/effects/SkLayerDrawLooper.cpp @@ -15,7 +15,6 @@ #include "SkUnPreMultiply.h" SkLayerDrawLooper::LayerInfo::LayerInfo() { - fFlagsMask = 0; // ignore our paint flags fPaintBits = 0; // ignore our paint fields fColorMode = SkXfermode::kDst_Mode; // ignore our color fOffset.set(0, 0); @@ -25,8 +24,7 @@ SkLayerDrawLooper::LayerInfo::LayerInfo() { SkLayerDrawLooper::SkLayerDrawLooper() : fRecs(NULL), fTopRec(NULL), - fCount(0), - fCurrRec(NULL) { + fCount(0) { } SkLayerDrawLooper::~SkLayerDrawLooper() { @@ -76,9 +74,9 @@ SkPaint* SkLayerDrawLooper::addLayerOnTop(const LayerInfo& info) { return &rec->fPaint; } -void SkLayerDrawLooper::init(SkCanvas* canvas) { - fCurrRec = fRecs; +SkLayerDrawLooper::Context* SkLayerDrawLooper::createContext(SkCanvas* canvas, void* storage) const { canvas->save(SkCanvas::kMatrix_SaveFlag); + return SkNEW_PLACEMENT_ARGS(storage, LayerDrawLooperContext, (this)); } static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) { @@ -99,11 +97,9 @@ static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) { // Even with kEntirePaint_Bits, we always ensure that the master paint's // text-encoding is respected, since that controls how we interpret the // text/length parameters of a draw[Pos]Text call. -void SkLayerDrawLooper::ApplyInfo(SkPaint* dst, const SkPaint& src, - const LayerInfo& info) { +void SkLayerDrawLooper::LayerDrawLooperContext::ApplyInfo( + SkPaint* dst, const SkPaint& src, const LayerInfo& info) { - uint32_t mask = info.fFlagsMask; - dst->setFlags((dst->getFlags() & ~mask) | (src.getFlags() & mask)); dst->setColor(xferColor(src.getColor(), dst->getColor(), info.fColorMode)); BitFlags bits = info.fPaintBits; @@ -170,7 +166,11 @@ static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) { canvas->setMatrix(m); } -bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { +SkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext( + const SkLayerDrawLooper* looper) : fCurrRec(looper->fRecs) {} + +bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas, + SkPaint* paint) { canvas->restore(); if (NULL == fCurrRec) { return false; @@ -183,7 +183,8 @@ bool SkLayerDrawLooper::next(SkCanvas* canvas, SkPaint* paint) { postTranslate(canvas, fCurrRec->fInfo.fOffset.fX, fCurrRec->fInfo.fOffset.fY); } else { - canvas->translate(fCurrRec->fInfo.fOffset.fX, fCurrRec->fInfo.fOffset.fY); + canvas->translate(fCurrRec->fInfo.fOffset.fX, + fCurrRec->fInfo.fOffset.fY); } fCurrRec = fCurrRec->fNext; @@ -211,7 +212,9 @@ void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const { Rec* rec = fRecs; for (int i = 0; i < fCount; i++) { - buffer.writeInt(rec->fInfo.fFlagsMask); + // Legacy "flagsmask" field -- now ignored, remove when we bump version + buffer.writeInt(0); + buffer.writeInt(rec->fInfo.fPaintBits); buffer.writeInt(rec->fInfo.fColorMode); buffer.writePoint(rec->fInfo.fOffset); @@ -221,28 +224,27 @@ void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const { } } -SkLayerDrawLooper::SkLayerDrawLooper(SkReadBuffer& buffer) - : INHERITED(buffer), - fRecs(NULL), - fTopRec(NULL), - fCount(0), - fCurrRec(NULL) { +SkFlattenable* SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) { int count = buffer.readInt(); + Builder builder; for (int i = 0; i < count; i++) { LayerInfo info; - info.fFlagsMask = buffer.readInt(); + // Legacy "flagsmask" field -- now ignored, remove when we bump version + (void)buffer.readInt(); + info.fPaintBits = buffer.readInt(); info.fColorMode = (SkXfermode::Mode)buffer.readInt(); buffer.readPoint(&info.fOffset); info.fPostTranslate = buffer.readBool(); - buffer.readPaint(this->addLayerOnTop(info)); + buffer.readPaint(builder.addLayerOnTop(info)); } - SkASSERT(count == fCount); + SkLayerDrawLooper* looper = builder.detachLooper(); + SkASSERT(count == looper->fCount); #ifdef SK_DEBUG { - Rec* rec = fRecs; + Rec* rec = looper->fRecs; int n = 0; while (rec) { rec = rec->fNext; @@ -251,52 +253,17 @@ SkLayerDrawLooper::SkLayerDrawLooper(SkReadBuffer& buffer) SkASSERT(count == n); } #endif + + return looper; } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkLayerDrawLooper::toString(SkString* str) const { str->appendf("SkLayerDrawLooper (%d): ", fCount); Rec* rec = fRecs; for (int i = 0; i < fCount; i++) { - str->appendf("%d: ", i); - - str->append("flagsMask: ("); - if (0 == rec->fInfo.fFlagsMask) { - str->append("None"); - } else { - bool needSeparator = false; - SkAddFlagToString(str, SkToBool(SkPaint::kAntiAlias_Flag & rec->fInfo.fFlagsMask), - "AntiAlias", &needSeparator); -// SkAddFlagToString(str, SkToBool(SkPaint::kFilterBitmap_Flag & rec->fInfo.fFlagsMask), "FilterBitmap", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kDither_Flag & rec->fInfo.fFlagsMask), - "Dither", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kUnderlineText_Flag & rec->fInfo.fFlagsMask), - "UnderlineText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kStrikeThruText_Flag & rec->fInfo.fFlagsMask), - "StrikeThruText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kFakeBoldText_Flag & rec->fInfo.fFlagsMask), - "FakeBoldText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kLinearText_Flag & rec->fInfo.fFlagsMask), - "LinearText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kSubpixelText_Flag & rec->fInfo.fFlagsMask), - "SubpixelText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kDevKernText_Flag & rec->fInfo.fFlagsMask), - "DevKernText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kLCDRenderText_Flag & rec->fInfo.fFlagsMask), - "LCDRenderText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kEmbeddedBitmapText_Flag & rec->fInfo.fFlagsMask), - "EmbeddedBitmapText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kAutoHinting_Flag & rec->fInfo.fFlagsMask), - "Autohinted", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kVerticalText_Flag & rec->fInfo.fFlagsMask), - "VerticalText", &needSeparator); - SkAddFlagToString(str, SkToBool(SkPaint::kGenA8FromLCD_Flag & rec->fInfo.fFlagsMask), - "GenA8FromLCD", &needSeparator); - } - str->append(") "); - - str->append("paintBits: ("); + str->appendf("%d: paintBits: (", i); if (0 == rec->fInfo.fPaintBits) { str->append("None"); } else if (kEntirePaint_Bits == rec->fInfo.fPaintBits) { @@ -347,3 +314,68 @@ void SkLayerDrawLooper::toString(SkString* str) const { } } #endif + +SkLayerDrawLooper::Builder::Builder() + : fRecs(NULL), + fTopRec(NULL), + fCount(0) { +} + +SkLayerDrawLooper::Builder::~Builder() { + Rec* rec = fRecs; + while (rec) { + Rec* next = rec->fNext; + SkDELETE(rec); + rec = next; + } +} + +SkPaint* SkLayerDrawLooper::Builder::addLayer(const LayerInfo& info) { + fCount += 1; + + Rec* rec = SkNEW(Rec); + rec->fNext = fRecs; + rec->fInfo = info; + fRecs = rec; + if (NULL == fTopRec) { + fTopRec = rec; + } + + return &rec->fPaint; +} + +void SkLayerDrawLooper::Builder::addLayer(SkScalar dx, SkScalar dy) { + LayerInfo info; + + info.fOffset.set(dx, dy); + (void)this->addLayer(info); +} + +SkPaint* SkLayerDrawLooper::Builder::addLayerOnTop(const LayerInfo& info) { + fCount += 1; + + Rec* rec = SkNEW(Rec); + rec->fNext = NULL; + rec->fInfo = info; + if (NULL == fRecs) { + fRecs = rec; + } else { + SkASSERT(NULL != fTopRec); + fTopRec->fNext = rec; + } + fTopRec = rec; + + return &rec->fPaint; +} + +SkLayerDrawLooper* SkLayerDrawLooper::Builder::detachLooper() { + SkLayerDrawLooper* looper = SkNEW(SkLayerDrawLooper); + looper->fCount = fCount; + looper->fRecs = fRecs; + + fCount = 0; + fRecs = NULL; + fTopRec = NULL; + + return looper; +} diff --git a/gfx/skia/trunk/src/effects/SkLayerRasterizer.cpp b/gfx/skia/trunk/src/effects/SkLayerRasterizer.cpp index 6381c4d69445..e35c5e828fb2 100644 --- a/gfx/skia/trunk/src/effects/SkLayerRasterizer.cpp +++ b/gfx/skia/trunk/src/effects/SkLayerRasterizer.cpp @@ -25,25 +25,36 @@ struct SkLayerRasterizer_Rec { SkVector fOffset; }; -SkLayerRasterizer::SkLayerRasterizer() : fLayers(sizeof(SkLayerRasterizer_Rec)) +SkLayerRasterizer::SkLayerRasterizer() + : fLayers(SkNEW_ARGS(SkDeque, (sizeof(SkLayerRasterizer_Rec)))) +{ +} + +SkLayerRasterizer::SkLayerRasterizer(SkDeque* layers) : fLayers(layers) { } SkLayerRasterizer::~SkLayerRasterizer() { - SkDeque::F2BIter iter(fLayers); + SkASSERT(fLayers); + SkDeque::F2BIter iter(*fLayers); SkLayerRasterizer_Rec* rec; while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) rec->fPaint.~SkPaint(); + + SkDELETE(fLayers); } +#ifdef SK_SUPPORT_LEGACY_LAYERRASTERIZER_API void SkLayerRasterizer::addLayer(const SkPaint& paint, SkScalar dx, SkScalar dy) { - SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers.push_back(); + SkASSERT(fLayers); + SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers->push_back(); SkNEW_PLACEMENT_ARGS(&rec->fPaint, SkPaint, (paint)); rec->fOffset.set(dx, dy); } +#endif static bool compute_bounds(const SkDeque& layers, const SkPath& path, const SkMatrix& matrix, @@ -89,12 +100,13 @@ static bool compute_bounds(const SkDeque& layers, const SkPath& path, bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, const SkIRect* clipBounds, SkMask* mask, SkMask::CreateMode mode) const { - if (fLayers.empty()) { + SkASSERT(fLayers); + if (fLayers->empty()) { return false; } if (SkMask::kJustRenderImage_CreateMode != mode) { - if (!compute_bounds(fLayers, path, matrix, clipBounds, &mask->fBounds)) + if (!compute_bounds(*fLayers, path, matrix, clipBounds, &mask->fBounds)) return false; } @@ -122,8 +134,7 @@ bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, translatedMatrix.postTranslate(-SkIntToScalar(mask->fBounds.fLeft), -SkIntToScalar(mask->fBounds.fTop)); - device.setConfig(SkBitmap::kA8_Config, mask->fBounds.width(), mask->fBounds.height(), mask->fRowBytes); - device.setPixels(mask->fImage); + device.installMaskPixels(*mask); draw.fBitmap = &device; draw.fMatrix = &drawMatrix; @@ -132,7 +143,7 @@ bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, // we set the matrixproc in the loop, as the matrix changes each time (potentially) draw.fBounder = NULL; - SkDeque::F2BIter iter(fLayers); + SkDeque::F2BIter iter(*fLayers); SkLayerRasterizer_Rec* rec; while ((rec = (SkLayerRasterizer_Rec*)iter.next()) != NULL) { @@ -145,24 +156,29 @@ bool SkLayerRasterizer::onRasterize(const SkPath& path, const SkMatrix& matrix, } SkLayerRasterizer::SkLayerRasterizer(SkReadBuffer& buffer) - : SkRasterizer(buffer), fLayers(sizeof(SkLayerRasterizer_Rec)) { + : SkRasterizer(buffer), fLayers(ReadLayers(buffer)) {} + +SkDeque* SkLayerRasterizer::ReadLayers(SkReadBuffer& buffer) { int count = buffer.readInt(); + SkDeque* layers = SkNEW_ARGS(SkDeque, (sizeof(SkLayerRasterizer_Rec))); for (int i = 0; i < count; i++) { - SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers.push_back(); + SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)layers->push_back(); SkNEW_PLACEMENT(&rec->fPaint, SkPaint); buffer.readPaint(&rec->fPaint); buffer.readPoint(&rec->fOffset); } + return layers; } void SkLayerRasterizer::flatten(SkWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); - buffer.writeInt(fLayers.count()); + SkASSERT(fLayers); + buffer.writeInt(fLayers->count()); - SkDeque::F2BIter iter(fLayers); + SkDeque::F2BIter iter(*fLayers); const SkLayerRasterizer_Rec* rec; while ((rec = (const SkLayerRasterizer_Rec*)iter.next()) != NULL) { @@ -170,3 +186,28 @@ void SkLayerRasterizer::flatten(SkWriteBuffer& buffer) const { buffer.writePoint(rec->fOffset); } } + +SkLayerRasterizer::Builder::Builder() + : fLayers(SkNEW_ARGS(SkDeque, (sizeof(SkLayerRasterizer_Rec)))) +{ +} + +SkLayerRasterizer::Builder::~Builder() +{ + SkDELETE(fLayers); +} + +void SkLayerRasterizer::Builder::addLayer(const SkPaint& paint, SkScalar dx, + SkScalar dy) { + SkASSERT(fLayers); + SkLayerRasterizer_Rec* rec = (SkLayerRasterizer_Rec*)fLayers->push_back(); + + SkNEW_PLACEMENT_ARGS(&rec->fPaint, SkPaint, (paint)); + rec->fOffset.set(dx, dy); +} + +SkLayerRasterizer* SkLayerRasterizer::Builder::detachRasterizer() { + SkLayerRasterizer* rasterizer = SkNEW_ARGS(SkLayerRasterizer, (fLayers)); + fLayers = NULL; + return rasterizer; +} diff --git a/gfx/skia/trunk/src/effects/SkLerpXfermode.cpp b/gfx/skia/trunk/src/effects/SkLerpXfermode.cpp index 505ada0b9a02..c8389fea799c 100644 --- a/gfx/skia/trunk/src/effects/SkLerpXfermode.cpp +++ b/gfx/skia/trunk/src/effects/SkLerpXfermode.cpp @@ -104,7 +104,7 @@ void SkLerpXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkLerpXfermode::toString(SkString* str) const { str->printf("SkLerpXfermode: scale: %g", fScale256 / 256.0); } diff --git a/gfx/skia/trunk/src/effects/SkLightingImageFilter.cpp b/gfx/skia/trunk/src/effects/SkLightingImageFilter.cpp index f4f1ae170748..54bb1c890beb 100644 --- a/gfx/skia/trunk/src/effects/SkLightingImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkLightingImageFilter.cpp @@ -271,7 +271,7 @@ public: protected: explicit SkDiffuseLightingImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool asNewEffect(GrEffectRef** effect, GrTexture*, const SkMatrix& matrix, const SkIRect& bounds) const SK_OVERRIDE; @@ -293,7 +293,7 @@ public: protected: explicit SkSpecularLightingImageFilter(SkReadBuffer& buffer); virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE; - virtual bool onFilterImage(Proxy*, const SkBitmap& src, const SkMatrix&, + virtual bool onFilterImage(Proxy*, const SkBitmap& src, const Context&, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE; #if SK_SUPPORT_GPU virtual bool asNewEffect(GrEffectRef** effect, GrTexture*, const SkMatrix& matrix, const SkIRect& bounds) const SK_OVERRIDE; @@ -641,7 +641,10 @@ public: virtual SkLight* transform(const SkMatrix& matrix) const { SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY); matrix.mapPoints(&location2, 1); - SkPoint3 location(location2.fX, location2.fY, fLocation.fZ); + // Use X scale and Y scale on Z and average the result + SkPoint locationZ = SkPoint::Make(fLocation.fZ, fLocation.fZ); + matrix.mapVectors(&locationZ, 1); + SkPoint3 location(location2.fX, location2.fY, SkScalarAve(locationZ.fX, locationZ.fY)); return new SkPointLight(location, color()); } @@ -682,11 +685,18 @@ public: virtual SkLight* transform(const SkMatrix& matrix) const { SkPoint location2 = SkPoint::Make(fLocation.fX, fLocation.fY); matrix.mapPoints(&location2, 1); - SkPoint3 location(location2.fX, location2.fY, fLocation.fZ); + // Use X scale and Y scale on Z and average the result + SkPoint locationZ = SkPoint::Make(fLocation.fZ, fLocation.fZ); + matrix.mapVectors(&locationZ, 1); + SkPoint3 location(location2.fX, location2.fY, SkScalarAve(locationZ.fX, locationZ.fY)); SkPoint target2 = SkPoint::Make(fTarget.fX, fTarget.fY); matrix.mapPoints(&target2, 1); - SkPoint3 target(target2.fX, target2.fY, fTarget.fZ); - return new SkSpotLight(location, target, fSpecularExponent, fCosOuterConeAngle, fCosInnerConeAngle, fConeScale, fS, color()); + SkPoint targetZ = SkPoint::Make(fTarget.fZ, fTarget.fZ); + matrix.mapVectors(&targetZ, 1); + SkPoint3 target(target2.fX, target2.fY, SkScalarAve(targetZ.fX, targetZ.fY)); + SkPoint3 s = target - location; + s.normalize(); + return new SkSpotLight(location, target, fSpecularExponent, fCosOuterConeAngle, fCosInnerConeAngle, fConeScale, s, color()); } SkPoint3 surfaceToLight(int x, int y, int z, SkScalar surfaceScale) const { @@ -923,28 +933,21 @@ void SkDiffuseLightingImageFilter::flatten(SkWriteBuffer& buffer) const { bool SkDiffuseLightingImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { SkImageFilter* input = getInput(0); SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (input && !input->filterImage(proxy, source, ctm, &src, &srcOffset)) { + if (input && !input->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } - if (src.config() != SkBitmap::kARGB_8888_Config) { + if (src.colorType() != kPMColor_SkColorType) { return false; } - SkAutoLockPixels alp(src); - if (!src.getPixels()) { - return false; - } - SkIRect bounds; - src.getBounds(&bounds); - bounds.offset(srcOffset); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { return false; } @@ -952,12 +955,17 @@ bool SkDiffuseLightingImageFilter::onFilterImage(Proxy* proxy, return false; } + SkAutoLockPixels alp(src); + if (!src.getPixels()) { + return false; + } + dst->setConfig(src.config(), bounds.width(), bounds.height()); if (!dst->allocPixels()) { return false; } - SkAutoTUnref transformedLight(light()->transform(ctm)); + SkAutoTUnref transformedLight(light()->transform(ctx.ctm())); DiffuseLightingType lightingType(fKD); offset->fX = bounds.left(); @@ -1016,28 +1024,22 @@ void SkSpecularLightingImageFilter::flatten(SkWriteBuffer& buffer) const { bool SkSpecularLightingImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { SkImageFilter* input = getInput(0); SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (input && !input->filterImage(proxy, source, ctm, &src, &srcOffset)) { + if (input && !input->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } - if (src.config() != SkBitmap::kARGB_8888_Config) { - return false; - } - SkAutoLockPixels alp(src); - if (!src.getPixels()) { + if (src.colorType() != kPMColor_SkColorType) { return false; } SkIRect bounds; - src.getBounds(&bounds); - bounds.offset(srcOffset); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { return false; } @@ -1045,6 +1047,11 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy* proxy, return false; } + SkAutoLockPixels alp(src); + if (!src.getPixels()) { + return false; + } + dst->setConfig(src.config(), bounds.width(), bounds.height()); dst->allocPixels(); if (!dst->getPixels()) { @@ -1055,7 +1062,7 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy* proxy, offset->fX = bounds.left(); offset->fY = bounds.top(); bounds.offset(-srcOffset); - SkAutoTUnref transformedLight(light()->transform(ctm)); + SkAutoTUnref transformedLight(light()->transform(ctx.ctm())); switch (transformedLight->type()) { case SkLight::kDistant_LightType: lightBitmap(lightingType, transformedLight, src, dst, surfaceScale(), bounds); diff --git a/gfx/skia/trunk/src/effects/SkLumaColorFilter.cpp b/gfx/skia/trunk/src/effects/SkLumaColorFilter.cpp index 669af6702610..ae8b90564517 100644 --- a/gfx/skia/trunk/src/effects/SkLumaColorFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkLumaColorFilter.cpp @@ -51,7 +51,7 @@ SkLumaColorFilter::SkLumaColorFilter(SkReadBuffer& buffer) void SkLumaColorFilter::flatten(SkWriteBuffer&) const { } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkLumaColorFilter::toString(SkString* str) const { str->append("SkLumaColorFilter "); } diff --git a/gfx/skia/trunk/src/effects/SkMagnifierImageFilter.cpp b/gfx/skia/trunk/src/effects/SkMagnifierImageFilter.cpp index 2fed24dc7430..51ade99e34ef 100644 --- a/gfx/skia/trunk/src/effects/SkMagnifierImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkMagnifierImageFilter.cpp @@ -247,7 +247,7 @@ SkMagnifierImageFilter::SkMagnifierImageFilter(SkReadBuffer& buffer) } // FIXME: implement single-input semantics -SkMagnifierImageFilter::SkMagnifierImageFilter(SkRect srcRect, SkScalar inset) +SkMagnifierImageFilter::SkMagnifierImageFilter(const SkRect& srcRect, SkScalar inset) : INHERITED(0), fSrcRect(srcRect), fInset(inset) { SkASSERT(srcRect.x() >= 0 && srcRect.y() >= 0 && inset >= 0); } @@ -280,13 +280,13 @@ void SkMagnifierImageFilter::flatten(SkWriteBuffer& buffer) const { } bool SkMagnifierImageFilter::onFilterImage(Proxy*, const SkBitmap& src, - const SkMatrix&, SkBitmap* dst, + const Context&, SkBitmap* dst, SkIPoint* offset) const { - SkASSERT(src.config() == SkBitmap::kARGB_8888_Config); + SkASSERT(src.colorType() == kPMColor_SkColorType); SkASSERT(fSrcRect.width() < src.width()); SkASSERT(fSrcRect.height() < src.height()); - if ((src.config() != SkBitmap::kARGB_8888_Config) || + if ((src.colorType() != kPMColor_SkColorType) || (fSrcRect.width() >= src.width()) || (fSrcRect.height() >= src.height())) { return false; diff --git a/gfx/skia/trunk/src/effects/SkMatrixConvolutionImageFilter.cpp b/gfx/skia/trunk/src/effects/SkMatrixConvolutionImageFilter.cpp index 43ebc6ce66b2..7b9812ddbc30 100644 --- a/gfx/skia/trunk/src/effects/SkMatrixConvolutionImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkMatrixConvolutionImageFilter.cpp @@ -38,7 +38,7 @@ SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( const SkScalar* kernel, SkScalar gain, SkScalar bias, - const SkIPoint& target, + const SkIPoint& kernelOffset, TileMode tileMode, bool convolveAlpha, SkImageFilter* input, @@ -47,15 +47,15 @@ SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter( fKernelSize(kernelSize), fGain(gain), fBias(bias), - fTarget(target), + fKernelOffset(kernelOffset), fTileMode(tileMode), fConvolveAlpha(convolveAlpha) { uint32_t size = fKernelSize.fWidth * fKernelSize.fHeight; fKernel = SkNEW_ARRAY(SkScalar, size); memcpy(fKernel, kernel, size * sizeof(SkScalar)); SkASSERT(kernelSize.fWidth >= 1 && kernelSize.fHeight >= 1); - SkASSERT(target.fX >= 0 && target.fX < kernelSize.fWidth); - SkASSERT(target.fY >= 0 && target.fY < kernelSize.fHeight); + SkASSERT(kernelOffset.fX >= 0 && kernelOffset.fX < kernelSize.fWidth); + SkASSERT(kernelOffset.fY >= 0 && kernelOffset.fY < kernelSize.fHeight); } SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(SkReadBuffer& buffer) @@ -79,8 +79,8 @@ SkMatrixConvolutionImageFilter::SkMatrixConvolutionImageFilter(SkReadBuffer& buf } fGain = buffer.readScalar(); fBias = buffer.readScalar(); - fTarget.fX = buffer.readInt(); - fTarget.fY = buffer.readInt(); + fKernelOffset.fX = buffer.readInt(); + fKernelOffset.fY = buffer.readInt(); fTileMode = (TileMode) buffer.readInt(); fConvolveAlpha = buffer.readBool(); buffer.validate((fKernel != 0) && @@ -96,8 +96,8 @@ void SkMatrixConvolutionImageFilter::flatten(SkWriteBuffer& buffer) const { buffer.writeScalarArray(fKernel, fKernelSize.fWidth * fKernelSize.fHeight); buffer.writeScalar(fGain); buffer.writeScalar(fBias); - buffer.writeInt(fTarget.fX); - buffer.writeInt(fTarget.fY); + buffer.writeInt(fKernelOffset.fX); + buffer.writeInt(fKernelOffset.fY); buffer.writeInt((int) fTileMode); buffer.writeBool(fConvolveAlpha); } @@ -160,8 +160,8 @@ void SkMatrixConvolutionImageFilter::filterPixels(const SkBitmap& src, for (int cy = 0; cy < fKernelSize.fHeight; cy++) { for (int cx = 0; cx < fKernelSize.fWidth; cx++) { SkPMColor s = PixelFetcher::fetch(src, - x + cx - fTarget.fX, - y + cy - fTarget.fY, + x + cx - fKernelOffset.fX, + y + cy - fKernelOffset.fY, bounds); SkScalar k = fKernel[cy * fKernelSize.fWidth + cx]; if (convolveAlpha) { @@ -251,23 +251,21 @@ static SkBitmap unpremultiplyBitmap(const SkBitmap& src) bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, - const SkMatrix& matrix, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, &srcOffset)) { + if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } - if (src.config() != SkBitmap::kARGB_8888_Config) { + if (src.colorType() != kPMColor_SkColorType) { return false; } SkIRect bounds; - src.getBounds(&bounds); - bounds.offset(srcOffset); - if (!this->applyCropRect(&bounds, matrix)) { + if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { return false; } @@ -289,8 +287,8 @@ bool SkMatrixConvolutionImageFilter::onFilterImage(Proxy* proxy, offset->fX = bounds.fLeft; offset->fY = bounds.fTop; bounds.offset(-srcOffset); - SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fTarget.fX, - bounds.top() + fTarget.fY, + SkIRect interior = SkIRect::MakeXYWH(bounds.left() + fKernelOffset.fX, + bounds.top() + fKernelOffset.fY, bounds.width() - fKernelSize.fWidth + 1, bounds.height() - fKernelSize.fHeight + 1); SkIRect top = SkIRect::MakeLTRB(bounds.left(), bounds.top(), bounds.right(), interior.top()); @@ -323,7 +321,7 @@ public: const SkScalar* kernel, SkScalar gain, SkScalar bias, - const SkIPoint& target, + const SkIPoint& kernelOffset, TileMode tileMode, bool convolveAlpha) { AutoEffectUnref effect(SkNEW_ARGS(GrMatrixConvolutionEffect, (texture, @@ -332,7 +330,7 @@ public: kernel, gain, bias, - target, + kernelOffset, tileMode, convolveAlpha))); return CreateEffectRef(effect); @@ -348,7 +346,7 @@ public: static const char* Name() { return "MatrixConvolution"; } const SkIRect& bounds() const { return fBounds; } const SkISize& kernelSize() const { return fKernelSize; } - const float* target() const { return fTarget; } + const float* kernelOffset() const { return fKernelOffset; } const float* kernel() const { return fKernel; } float gain() const { return fGain; } float bias() const { return fBias; } @@ -366,7 +364,7 @@ private: const SkScalar* kernel, SkScalar gain, SkScalar bias, - const SkIPoint& target, + const SkIPoint& kernelOffset, TileMode tileMode, bool convolveAlpha); @@ -377,7 +375,7 @@ private: float *fKernel; float fGain; float fBias; - float fTarget[2]; + float fKernelOffset[2]; TileMode fTileMode; bool fConvolveAlpha; @@ -412,7 +410,7 @@ private: UniformHandle fBoundsUni; UniformHandle fKernelUni; UniformHandle fImageIncrementUni; - UniformHandle fTargetUni; + UniformHandle fKernelOffsetUni; UniformHandle fGainUni; UniformHandle fBiasUni; @@ -467,15 +465,15 @@ void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder, kFloat_GrSLType, "Kernel", fKernelSize.width() * fKernelSize.height()); - fTargetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kVec2f_GrSLType, "Target"); + fKernelOffsetUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec2f_GrSLType, "KernelOffset"); fGainUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, kFloat_GrSLType, "Gain"); fBiasUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, kFloat_GrSLType, "Bias"); const char* bounds = builder->getUniformCStr(fBoundsUni); - const char* target = builder->getUniformCStr(fTargetUni); + const char* kernelOffset = builder->getUniformCStr(fKernelOffsetUni); const char* imgInc = builder->getUniformCStr(fImageIncrementUni); const char* kernel = builder->getUniformCStr(fKernelUni); const char* gain = builder->getUniformCStr(fGainUni); @@ -484,7 +482,7 @@ void GrGLMatrixConvolutionEffect::emitCode(GrGLShaderBuilder* builder, int kHeight = fKernelSize.height(); builder->fsCodeAppend("\t\tvec4 sum = vec4(0, 0, 0, 0);\n"); - builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), target, imgInc); + builder->fsCodeAppendf("\t\tvec2 coord = %s - %s * %s;\n", coords2D.c_str(), kernelOffset, imgInc); builder->fsCodeAppendf("\t\tfor (int y = 0; y < %d; y++) {\n", kHeight); builder->fsCodeAppendf("\t\t\tfor (int x = 0; x < %d; x++) {\n", kWidth); builder->fsCodeAppendf("\t\t\t\tfloat k = %s[y * %d + x];\n", kernel, kWidth); @@ -545,7 +543,7 @@ void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman, imageIncrement[0] = 1.0f / texture.width(); imageIncrement[1] = ySign / texture.height(); uman.set2fv(fImageIncrementUni, 1, imageIncrement); - uman.set2fv(fTargetUni, 1, conv.target()); + uman.set2fv(fKernelOffsetUni, 1, conv.kernelOffset()); uman.set1fv(fKernelUni, fKernelSize.width() * fKernelSize.height(), conv.kernel()); uman.set1f(fGainUni, conv.gain()); uman.set1f(fBiasUni, conv.bias()); @@ -567,7 +565,7 @@ GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, const SkScalar* kernel, SkScalar gain, SkScalar bias, - const SkIPoint& target, + const SkIPoint& kernelOffset, TileMode tileMode, bool convolveAlpha) : INHERITED(texture, MakeDivByTextureWHMatrix(texture)), @@ -581,8 +579,8 @@ GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, for (int i = 0; i < kernelSize.width() * kernelSize.height(); i++) { fKernel[i] = SkScalarToFloat(kernel[i]); } - fTarget[0] = static_cast(target.x()); - fTarget[1] = static_cast(target.y()); + fKernelOffset[0] = static_cast(kernelOffset.x()); + fKernelOffset[1] = static_cast(kernelOffset.y()); this->setWillNotUseInputColor(); } @@ -602,7 +600,7 @@ bool GrMatrixConvolutionEffect::onIsEqual(const GrEffect& sBase) const { fKernelSize.width() * fKernelSize.height() * sizeof(float)) && fGain == s.gain() && fBias == s.bias() && - fTarget == s.target() && + fKernelOffset == s.kernelOffset() && fTileMode == s.tileMode() && fConvolveAlpha == s.convolveAlpha(); } @@ -628,8 +626,8 @@ GrEffectRef* GrMatrixConvolutionEffect::TestCreate(SkRandom* random, } SkScalar gain = random->nextSScalar1(); SkScalar bias = random->nextSScalar1(); - SkIPoint target = SkIPoint::Make(random->nextRangeU(0, kernelSize.width()), - random->nextRangeU(0, kernelSize.height())); + SkIPoint kernelOffset = SkIPoint::Make(random->nextRangeU(0, kernelSize.width()), + random->nextRangeU(0, kernelSize.height())); SkIRect bounds = SkIRect::MakeXYWH(random->nextRangeU(0, textures[texIdx]->width()), random->nextRangeU(0, textures[texIdx]->height()), random->nextRangeU(0, textures[texIdx]->width()), @@ -642,7 +640,7 @@ GrEffectRef* GrMatrixConvolutionEffect::TestCreate(SkRandom* random, kernel.get(), gain, bias, - target, + kernelOffset, tileMode, convolveAlpha); } @@ -662,7 +660,7 @@ bool SkMatrixConvolutionImageFilter::asNewEffect(GrEffectRef** effect, fKernel, fGain, fBias, - fTarget, + fKernelOffset, fTileMode, fConvolveAlpha); return true; diff --git a/gfx/skia/trunk/src/effects/SkMergeImageFilter.cpp b/gfx/skia/trunk/src/effects/SkMergeImageFilter.cpp index 5f662440840c..adf9afe9b3dd 100755 --- a/gfx/skia/trunk/src/effects/SkMergeImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkMergeImageFilter.cpp @@ -66,15 +66,14 @@ SkMergeImageFilter::~SkMergeImageFilter() { } bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { if (countInputs() < 1) { return false; } SkIRect bounds; - src.getBounds(&bounds); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, src, SkIPoint::Make(0, 0), &bounds)) { return false; } @@ -95,7 +94,7 @@ bool SkMergeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, SkIPoint pos = SkIPoint::Make(0, 0); SkImageFilter* filter = getInput(i); if (filter) { - if (!filter->filterImage(proxy, src, ctm, &tmp, &pos)) { + if (!filter->filterImage(proxy, src, ctx, &tmp, &pos)) { return false; } srcPtr = &tmp; diff --git a/gfx/skia/trunk/src/effects/SkMorphologyImageFilter.cpp b/gfx/skia/trunk/src/effects/SkMorphologyImageFilter.cpp index f2eeb2d6ffa3..fb69758edddb 100644 --- a/gfx/skia/trunk/src/effects/SkMorphologyImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkMorphologyImageFilter.cpp @@ -18,7 +18,6 @@ #include "GrTBackendEffectFactory.h" #include "gl/GrGLEffect.h" #include "effects/Gr1DKernelEffect.h" -#include "SkImageFilterUtils.h" #endif SkMorphologyImageFilter::SkMorphologyImageFilter(SkReadBuffer& buffer) @@ -141,23 +140,21 @@ bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc p SkMorphologyImageFilter::Proc procY, Proxy* proxy, const SkBitmap& source, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, &srcOffset)) { + if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } - if (src.config() != SkBitmap::kARGB_8888_Config) { + if (src.colorType() != kPMColor_SkColorType) { return false; } SkIRect bounds; - src.getBounds(&bounds); - bounds.offset(srcOffset); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { return false; } @@ -174,7 +171,7 @@ bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc p SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), SkIntToScalar(this->radius().height())); - ctm.mapVectors(&radius, 1); + ctx.ctm().mapVectors(&radius, 1); int width = SkScalarFloorToInt(radius.fX); int height = SkScalarFloorToInt(radius.fY); @@ -213,7 +210,7 @@ bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc p } bool SkErodeImageFilter::onFilterImage(Proxy* proxy, - const SkBitmap& source, const SkMatrix& ctm, + const SkBitmap& source, const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { Proc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType); if (!erodeXProc) { @@ -223,11 +220,11 @@ bool SkErodeImageFilter::onFilterImage(Proxy* proxy, if (!erodeYProc) { erodeYProc = erode; } - return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctm, dst, offset); + return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctx, dst, offset); } bool SkDilateImageFilter::onFilterImage(Proxy* proxy, - const SkBitmap& source, const SkMatrix& ctm, + const SkBitmap& source, const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { Proc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType); if (!dilateXProc) { @@ -237,7 +234,7 @@ bool SkDilateImageFilter::onFilterImage(Proxy* proxy, if (!dilateYProc) { dilateYProc = dilate; } - return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctm, dst, offset); + return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctx, dst, offset); } void SkMorphologyImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { @@ -530,7 +527,8 @@ bool apply_morphology(const SkBitmap& input, morphType, Gr1DKernelEffect::kY_Direction); src.reset(ast.detach()); } - return SkImageFilterUtils::WrapTexture(src, rect.width(), rect.height(), dst); + SkImageFilter::WrapTexture(src, rect.width(), rect.height(), dst); + return true; } }; @@ -538,23 +536,21 @@ bool apply_morphology(const SkBitmap& input, bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { - SkBitmap input; + SkBitmap input = src; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &input, &srcOffset)) { + if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { return false; } SkIRect bounds; - input.getBounds(&bounds); - bounds.offset(srcOffset); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { return false; } SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), SkIntToScalar(this->radius().height())); - ctm.mapVectors(&radius, 1); + ctx.ctm().mapVectors(&radius, 1); int width = SkScalarFloorToInt(radius.fX); int height = SkScalarFloorToInt(radius.fY); @@ -581,14 +577,14 @@ bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, return true; } -bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, +bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { - return this->filterImageGPUGeneric(true, proxy, src, ctm, result, offset); + return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); } -bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, +bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { - return this->filterImageGPUGeneric(false, proxy, src, ctm, result, offset); + return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); } #endif diff --git a/gfx/skia/trunk/src/effects/SkOffsetImageFilter.cpp b/gfx/skia/trunk/src/effects/SkOffsetImageFilter.cpp index b36ef8a3ed68..ae35a4ca2f78 100644 --- a/gfx/skia/trunk/src/effects/SkOffsetImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkOffsetImageFilter.cpp @@ -15,7 +15,7 @@ #include "SkPaint.h" bool SkOffsetImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, - const SkMatrix& matrix, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkImageFilter* input = getInput(0); @@ -26,26 +26,23 @@ bool SkOffsetImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, #else if (!cropRectIsSet()) { #endif - if (input && !input->filterImage(proxy, source, matrix, &src, &srcOffset)) { + if (input && !input->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } SkVector vec; - matrix.mapVectors(&vec, &fOffset, 1); + ctx.ctm().mapVectors(&vec, &fOffset, 1); offset->fX = srcOffset.fX + SkScalarRoundToInt(vec.fX); offset->fY = srcOffset.fY + SkScalarRoundToInt(vec.fY); *result = src; } else { - if (input && !input->filterImage(proxy, source, matrix, &src, &srcOffset)) { + if (input && !input->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } SkIRect bounds; - src.getBounds(&bounds); - bounds.offset(srcOffset); - - if (!applyCropRect(&bounds, matrix)) { + if (!this->applyCropRect(ctx, src, srcOffset, &bounds)) { return false; } @@ -58,7 +55,9 @@ bool SkOffsetImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, paint.setXfermodeMode(SkXfermode::kSrc_Mode); canvas.translate(SkIntToScalar(srcOffset.fX - bounds.fLeft), SkIntToScalar(srcOffset.fY - bounds.fTop)); - canvas.drawBitmap(src, fOffset.x(), fOffset.y(), &paint); + SkVector vec; + ctx.ctm().mapVectors(&vec, &fOffset, 1); + canvas.drawBitmap(src, vec.x(), vec.y(), &paint); *result = device->accessBitmap(false); offset->fX = bounds.fLeft; offset->fY = bounds.fTop; @@ -82,9 +81,10 @@ bool SkOffsetImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm SkVector vec; ctm.mapVectors(&vec, &fOffset, 1); - *dst = src; - dst->offset(-SkScalarCeilToInt(vec.fX), -SkScalarCeilToInt(vec.fY)); - dst->join(src); + SkIRect bounds = src; + bounds.offset(-SkScalarCeilToInt(vec.fX), -SkScalarCeilToInt(vec.fY)); + bounds.join(src); + *dst = bounds; return true; } diff --git a/gfx/skia/trunk/src/effects/SkPerlinNoiseShader.cpp b/gfx/skia/trunk/src/effects/SkPerlinNoiseShader.cpp index 48a25f9a5b92..8abbdbd16b87 100644 --- a/gfx/skia/trunk/src/effects/SkPerlinNoiseShader.cpp +++ b/gfx/skia/trunk/src/effects/SkPerlinNoiseShader.cpp @@ -81,17 +81,23 @@ struct SkPerlinNoiseShader::StitchData { }; struct SkPerlinNoiseShader::PaintingData { - PaintingData(const SkISize& tileSize) - : fSeed(0) - , fTileSize(tileSize) - , fPermutationsBitmap(NULL) - , fNoiseBitmap(NULL) - {} - - ~PaintingData() + PaintingData(const SkISize& tileSize, SkScalar seed, + SkScalar baseFrequencyX, SkScalar baseFrequencyY) + : fTileSize(tileSize) + , fBaseFrequency(SkPoint::Make(baseFrequencyX, baseFrequencyY)) { - SkDELETE(fPermutationsBitmap); - SkDELETE(fNoiseBitmap); + this->init(seed); + if (!fTileSize.isEmpty()) { + this->stitch(); + } + +#if SK_SUPPORT_GPU && !defined(SK_USE_SIMPLEX_NOISE) + fPermutationsBitmap.setConfig(SkImageInfo::MakeA8(kBlockSize, 1)); + fPermutationsBitmap.setPixels(fLatticeSelector); + + fNoiseBitmap.setConfig(SkImageInfo::MakeN32Premul(kBlockSize, 4)); + fNoiseBitmap.setPixels(fNoise[0][0]); +#endif } int fSeed; @@ -104,10 +110,10 @@ struct SkPerlinNoiseShader::PaintingData { private: - SkBitmap* fPermutationsBitmap; - SkBitmap* fNoiseBitmap; - -public: +#if SK_SUPPORT_GPU && !defined(SK_USE_SIMPLEX_NOISE) + SkBitmap fPermutationsBitmap; + SkBitmap fNoiseBitmap; +#endif inline int random() { static const int gRandAmplitude = 16807; // 7**5; primitive root of m @@ -121,6 +127,7 @@ public: return result; } + // Only called once. Could be part of the constructor. void init(SkScalar seed) { static const SkScalar gInvBlockSizef = SkScalarInvert(SkIntToScalar(kBlockSize)); @@ -190,14 +197,9 @@ public: fGradient[channel][i].fY + SK_Scalar1, gHalfMax16bits)); } } - - // Invalidate bitmaps - SkDELETE(fPermutationsBitmap); - fPermutationsBitmap = NULL; - SkDELETE(fNoiseBitmap); - fNoiseBitmap = NULL; } + // Only called once. Could be part of the constructor. void stitch() { SkScalar tileWidth = SkIntToScalar(fTileSize.width()); SkScalar tileHeight = SkIntToScalar(fTileSize.height()); @@ -238,27 +240,13 @@ public: fStitchDataInit.fWrapY = kPerlinNoise + fStitchDataInit.fHeight; } - SkBitmap* getPermutationsBitmap() - { - if (!fPermutationsBitmap) { - fPermutationsBitmap = SkNEW(SkBitmap); - fPermutationsBitmap->allocPixels(SkImageInfo::MakeA8(kBlockSize, 1)); - uint8_t* bitmapPixels = fPermutationsBitmap->getAddr8(0, 0); - memcpy(bitmapPixels, fLatticeSelector, sizeof(uint8_t) * kBlockSize); - } - return fPermutationsBitmap; - } +public: - SkBitmap* getNoiseBitmap() - { - if (!fNoiseBitmap) { - fNoiseBitmap = SkNEW(SkBitmap); - fNoiseBitmap->allocPixels(SkImageInfo::MakeN32Premul(kBlockSize, 4)); - uint32_t* bitmapPixels = fNoiseBitmap->getAddr32(0, 0); - memcpy(bitmapPixels, fNoise[0][0], sizeof(uint16_t) * kBlockSize * 4 * 2); - } - return fNoiseBitmap; - } +#if SK_SUPPORT_GPU && !defined(SK_USE_SIMPLEX_NOISE) + const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap; } + + const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; } +#endif }; SkShader* SkPerlinNoiseShader::CreateFractalNoise(SkScalar baseFrequencyX, SkScalar baseFrequencyY, @@ -286,16 +274,17 @@ SkPerlinNoiseShader::SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, , fBaseFrequencyY(baseFrequencyY) , fNumOctaves(numOctaves > 255 ? 255 : numOctaves/*[0,255] octaves allowed*/) , fSeed(seed) - , fStitchTiles((tileSize != NULL) && !tileSize->isEmpty()) - , fPaintingData(NULL) + , fTileSize(NULL == tileSize ? SkISize::Make(0, 0) : *tileSize) + , fStitchTiles(!fTileSize.isEmpty()) { SkASSERT(numOctaves >= 0 && numOctaves < 256); - setTileSize(fStitchTiles ? *tileSize : SkISize::Make(0,0)); fMatrix.reset(); + fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY)); } -SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) : - INHERITED(buffer), fPaintingData(NULL) { +SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) + : INHERITED(buffer) +{ fType = (SkPerlinNoiseShader::Type) buffer.readInt(); fBaseFrequencyX = buffer.readScalar(); fBaseFrequencyY = buffer.readScalar(); @@ -304,10 +293,11 @@ SkPerlinNoiseShader::SkPerlinNoiseShader(SkReadBuffer& buffer) : fStitchTiles = buffer.readBool(); fTileSize.fWidth = buffer.readInt(); fTileSize.fHeight = buffer.readInt(); - setTileSize(fTileSize); fMatrix.reset(); + fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize, fSeed, fBaseFrequencyX, fBaseFrequencyY)); buffer.validate(perlin_noise_type_is_valid(fType) && - (fNumOctaves >= 0) && (fNumOctaves <= 255)); + (fNumOctaves >= 0) && (fNumOctaves <= 255) && + (fStitchTiles != fTileSize.isEmpty())); } SkPerlinNoiseShader::~SkPerlinNoiseShader() { @@ -327,39 +317,9 @@ void SkPerlinNoiseShader::flatten(SkWriteBuffer& buffer) const { buffer.writeInt(fTileSize.fHeight); } -void SkPerlinNoiseShader::initPaint(PaintingData& paintingData) -{ - paintingData.init(fSeed); - - // Set frequencies to original values - paintingData.fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY); - // Adjust frequecies based on size if stitching is enabled - if (fStitchTiles) { - paintingData.stitch(); - } -} - -void SkPerlinNoiseShader::setTileSize(const SkISize& tileSize) { - fTileSize = tileSize; - - if (NULL == fPaintingData) { - fPaintingData = SkNEW_ARGS(PaintingData, (fTileSize)); - initPaint(*fPaintingData); - } else { - // Set Size - fPaintingData->fTileSize = fTileSize; - // Set frequencies to original values - fPaintingData->fBaseFrequency.set(fBaseFrequencyX, fBaseFrequencyY); - // Adjust frequecies based on size if stitching is enabled - if (fStitchTiles) { - fPaintingData->stitch(); - } - } -} - SkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingData, - const StitchData& stitchData, const SkPoint& noiseVector) -{ + const StitchData& stitchData, + const SkPoint& noiseVector) const { struct Noise { int noisePositionIntegerValue; SkScalar noisePositionFractionValue; @@ -405,9 +365,10 @@ SkScalar SkPerlinNoiseShader::noise2D(int channel, const PaintingData& paintingD return SkScalarInterp(a, b, sy); } -SkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint( - int channel, const PaintingData& paintingData, StitchData& stitchData, const SkPoint& point) -{ +SkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint(int channel, + const PaintingData& paintingData, + StitchData& stitchData, + const SkPoint& point) const { if (fStitchTiles) { // Set up TurbulenceInitial stitch values. stitchData = paintingData.fStitchDataInit; @@ -448,8 +409,9 @@ SkScalar SkPerlinNoiseShader::calculateTurbulenceValueForPoint( return SkScalarPin(turbulenceFunctionResult, 0, SK_Scalar1); } -SkPMColor SkPerlinNoiseShader::shade(const SkPoint& point, StitchData& stitchData) { +SkPMColor SkPerlinNoiseShader::shade(const SkPoint& point, StitchData& stitchData) const { SkMatrix matrix = fMatrix; + matrix.postConcat(getLocalMatrix()); SkMatrix invMatrix; if (!matrix.invert(&invMatrix)) { invMatrix.reset(); @@ -1325,9 +1287,9 @@ GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& this->getLocalMatrix(), paint.getAlpha()); #else GrTexture* permutationsTexture = GrLockAndRefCachedBitmapTexture( - context, *fPaintingData->getPermutationsBitmap(), NULL); + context, fPaintingData->getPermutationsBitmap(), NULL); GrTexture* noiseTexture = GrLockAndRefCachedBitmapTexture( - context, *fPaintingData->getNoiseBitmap(), NULL); + context, fPaintingData->getNoiseBitmap(), NULL); GrEffectRef* effect = (NULL != permutationsTexture) && (NULL != noiseTexture) ? GrPerlinNoiseEffect::Create(fType, fPaintingData->fBaseFrequency, @@ -1360,7 +1322,7 @@ GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext*, const SkPaint&) const #endif -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkPerlinNoiseShader::toString(SkString* str) const { str->append("SkPerlinNoiseShader: ("); diff --git a/gfx/skia/trunk/src/effects/SkPictureImageFilter.cpp b/gfx/skia/trunk/src/effects/SkPictureImageFilter.cpp index 6e76231867e7..0b36b1d0464b 100644 --- a/gfx/skia/trunk/src/effects/SkPictureImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkPictureImageFilter.cpp @@ -15,15 +15,15 @@ SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture) : INHERITED(0, 0), fPicture(picture), - fRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0, - picture ? SkIntToScalar(picture->height()) : 0)) { + fCropRect(SkRect::MakeWH(picture ? SkIntToScalar(picture->width()) : 0, + picture ? SkIntToScalar(picture->height()) : 0)) { SkSafeRef(fPicture); } -SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture, const SkRect& rect) +SkPictureImageFilter::SkPictureImageFilter(SkPicture* picture, const SkRect& cropRect) : INHERITED(0, 0), fPicture(picture), - fRect(rect) { + fCropRect(cropRect) { SkSafeRef(fPicture); } @@ -41,7 +41,7 @@ SkPictureImageFilter::SkPictureImageFilter(SkReadBuffer& buffer) #else buffer.readBool(); #endif - buffer.readRect(&fRect); + buffer.readRect(&fCropRect); } void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const { @@ -55,11 +55,11 @@ void SkPictureImageFilter::flatten(SkWriteBuffer& buffer) const { #else buffer.writeBool(false); #endif - buffer.writeRect(fRect); + buffer.writeRect(fCropRect); } -bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const SkMatrix& matrix, - SkBitmap* result, SkIPoint* offset) const { +bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Context& ctx, + SkBitmap* result, SkIPoint* offset) const { if (!fPicture) { offset->fX = offset->fY = 0; return true; @@ -67,7 +67,7 @@ bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Sk SkRect floatBounds; SkIRect bounds; - matrix.mapRect(&floatBounds, fRect); + ctx.ctm().mapRect(&floatBounds, fCropRect); floatBounds.roundOut(&bounds); if (bounds.isEmpty()) { @@ -84,7 +84,7 @@ bool SkPictureImageFilter::onFilterImage(Proxy* proxy, const SkBitmap&, const Sk SkPaint paint; canvas.translate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop)); - canvas.concat(matrix); + canvas.concat(ctx.ctm()); canvas.drawPicture(*fPicture); *result = device.get()->accessBitmap(false); diff --git a/gfx/skia/trunk/src/effects/SkPixelXorXfermode.cpp b/gfx/skia/trunk/src/effects/SkPixelXorXfermode.cpp index eaf775745354..129f1823d5fc 100644 --- a/gfx/skia/trunk/src/effects/SkPixelXorXfermode.cpp +++ b/gfx/skia/trunk/src/effects/SkPixelXorXfermode.cpp @@ -31,7 +31,7 @@ SkPixelXorXfermode::SkPixelXorXfermode(SkReadBuffer& rb) fOpColor = rb.readColor(); } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkPixelXorXfermode::toString(SkString* str) const { str->append("SkPixelXorXfermode: "); str->appendHex(fOpColor); diff --git a/gfx/skia/trunk/src/effects/SkRectShaderImageFilter.cpp b/gfx/skia/trunk/src/effects/SkRectShaderImageFilter.cpp index 18e38470bc9b..13e59c2c2781 100644 --- a/gfx/skia/trunk/src/effects/SkRectShaderImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkRectShaderImageFilter.cpp @@ -52,12 +52,11 @@ SkRectShaderImageFilter::~SkRectShaderImageFilter() { bool SkRectShaderImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkIRect bounds; - source.getBounds(&bounds); - if (!this->applyCropRect(&bounds, ctm)) { + if (!this->applyCropRect(ctx, source, SkIPoint::Make(0, 0), &bounds)) { return false; } @@ -69,8 +68,8 @@ bool SkRectShaderImageFilter::onFilterImage(Proxy* proxy, SkCanvas canvas(device.get()); SkPaint paint; paint.setShader(fShader); - SkMatrix matrix; - matrix.setTranslate(-SkIntToScalar(bounds.fLeft), -SkIntToScalar(bounds.fTop)); + SkMatrix matrix(ctx.ctm()); + matrix.postTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top())); fShader->setLocalMatrix(matrix); SkRect rect = SkRect::MakeWH(SkIntToScalar(bounds.width()), SkIntToScalar(bounds.height())); canvas.drawRect(rect, paint); diff --git a/gfx/skia/trunk/src/effects/SkResizeImageFilter.cpp b/gfx/skia/trunk/src/effects/SkResizeImageFilter.cpp index 4a3f4b56ee62..87c30c6e808f 100644 --- a/gfx/skia/trunk/src/effects/SkResizeImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkResizeImageFilter.cpp @@ -42,12 +42,12 @@ SkResizeImageFilter::~SkResizeImageFilter() { bool SkResizeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& source, - const SkMatrix& matrix, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkBitmap src = source; SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (getInput(0) && !getInput(0)->filterImage(proxy, source, matrix, &src, &srcOffset)) { + if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcOffset)) { return false; } @@ -56,9 +56,13 @@ bool SkResizeImageFilter::onFilterImage(Proxy* proxy, src.getBounds(&srcBounds); srcBounds.offset(srcOffset); SkRect srcRect = SkRect::Make(srcBounds); - SkMatrix dstMatrix; - dstMatrix.setScale(fSx, fSy); - dstMatrix.mapRect(&dstRect, srcRect); + SkMatrix matrix; + if (!ctx.ctm().invert(&matrix)) { + return false; + } + matrix.postScale(fSx, fSy); + matrix.postConcat(ctx.ctm()); + matrix.mapRect(&dstRect, srcRect); dstRect.roundOut(&dstBounds); SkAutoTUnref device(proxy->createDevice(dstBounds.width(), dstBounds.height())); @@ -67,12 +71,11 @@ bool SkResizeImageFilter::onFilterImage(Proxy* proxy, } SkCanvas canvas(device.get()); - canvas.translate(-SkIntToScalar(dstBounds.fLeft), -SkIntToScalar(dstBounds.fTop)); + canvas.scale(fSx, fSy); SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); paint.setFilterLevel(fFilterLevel); - canvas.concat(dstMatrix); canvas.drawBitmap(src, srcRect.left(), srcRect.top(), &paint); *result = device.get()->accessBitmap(false); @@ -80,3 +83,31 @@ bool SkResizeImageFilter::onFilterImage(Proxy* proxy, offset->fY = dstBounds.fTop; return true; } + +void SkResizeImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const { + SkRect bounds = src; + if (getInput(0)) { + getInput(0)->computeFastBounds(src, &bounds); + } + dst->setXYWH(bounds.x(), bounds.y(), bounds.width() * fSx, bounds.height() * fSy); +} + +bool SkResizeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, + SkIRect* dst) const { + SkMatrix matrix; + if (!ctm.invert(&matrix)) { + return false; + } + matrix.postScale(SkScalarInvert(fSx), SkScalarInvert(fSy)); + matrix.postConcat(ctm); + SkRect floatBounds; + matrix.mapRect(&floatBounds, SkRect::Make(src)); + SkIRect bounds; + floatBounds.roundOut(&bounds); + if (getInput(0) && !getInput(0)->filterBounds(bounds, ctm, &bounds)) { + return false; + } + + *dst = bounds; + return true; +} diff --git a/gfx/skia/trunk/src/effects/SkStippleMaskFilter.cpp b/gfx/skia/trunk/src/effects/SkStippleMaskFilter.cpp index 14f30ec6510b..4aceb110662d 100644 --- a/gfx/skia/trunk/src/effects/SkStippleMaskFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkStippleMaskFilter.cpp @@ -45,7 +45,7 @@ bool SkStippleMaskFilter::filterMask(SkMask* dst, return true; } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkStippleMaskFilter::toString(SkString* str) const { str->append("SkStippleMaskFilter: ()"); } diff --git a/gfx/skia/trunk/src/effects/SkTableColorFilter.cpp b/gfx/skia/trunk/src/effects/SkTableColorFilter.cpp index eb3dbc3587b2..6a9ab1079547 100644 --- a/gfx/skia/trunk/src/effects/SkTableColorFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkTableColorFilter.cpp @@ -49,7 +49,7 @@ public: virtual void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const SK_OVERRIDE; - SkDEVCODE(virtual void toString(SkString* str) const SK_OVERRIDE;) + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTable_ColorFilter) @@ -152,7 +152,7 @@ void SkTable_ColorFilter::filterSpan(const SkPMColor src[], int count, } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkTable_ColorFilter::toString(SkString* str) const { str->append("SkTable_ColorFilter"); } diff --git a/gfx/skia/trunk/src/effects/SkTableMaskFilter.cpp b/gfx/skia/trunk/src/effects/SkTableMaskFilter.cpp index 27280d336401..602302e503c0 100644 --- a/gfx/skia/trunk/src/effects/SkTableMaskFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkTableMaskFilter.cpp @@ -129,7 +129,7 @@ void SkTableMaskFilter::MakeClipTable(uint8_t table[256], uint8_t min, #endif } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkTableMaskFilter::toString(SkString* str) const { str->append("SkTableMaskFilter: ("); diff --git a/gfx/skia/trunk/src/effects/SkTestImageFilters.cpp b/gfx/skia/trunk/src/effects/SkTestImageFilters.cpp index 69279324cab5..da88316654ab 100755 --- a/gfx/skia/trunk/src/effects/SkTestImageFilters.cpp +++ b/gfx/skia/trunk/src/effects/SkTestImageFilters.cpp @@ -22,7 +22,7 @@ public: /////////////////////////////////////////////////////////////////////////////// bool SkDownSampleImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, - const SkMatrix&, + const Context&, SkBitmap* result, SkIPoint*) const { SkScalar scale = fScale; if (scale > SK_Scalar1 || scale <= 0) { diff --git a/gfx/skia/trunk/src/effects/SkTileImageFilter.cpp b/gfx/skia/trunk/src/effects/SkTileImageFilter.cpp index f17e2eac93cc..b35d85262307 100644 --- a/gfx/skia/trunk/src/effects/SkTileImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkTileImageFilter.cpp @@ -16,17 +16,17 @@ #include "SkShader.h" #include "SkValidationUtils.h" -bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm, +bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, const SkImageFilter::Context& ctx, SkBitmap* dst, SkIPoint* offset) const { SkBitmap source = src; SkImageFilter* input = getInput(0); SkIPoint srcOffset = SkIPoint::Make(0, 0); - if (input && !input->filterImage(proxy, src, ctm, &source, &srcOffset)) { + if (input && !input->filterImage(proxy, src, ctx, &source, &srcOffset)) { return false; } SkRect dstRect; - ctm.mapRect(&dstRect, fDstRect); + ctx.ctm().mapRect(&dstRect, fDstRect); SkIRect dstIRect; dstRect.roundOut(&dstIRect); int w = dstIRect.width(); @@ -36,7 +36,7 @@ bool SkTileImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, const S } SkRect srcRect; - ctm.mapRect(&srcRect, fSrcRect); + ctx.ctm().mapRect(&srcRect, fSrcRect); SkIRect srcIRect; srcRect.roundOut(&srcIRect); srcIRect.offset(-srcOffset); diff --git a/gfx/skia/trunk/src/effects/SkTransparentShader.cpp b/gfx/skia/trunk/src/effects/SkTransparentShader.cpp index 1d7e80877e16..b6a5e1edea98 100644 --- a/gfx/skia/trunk/src/effects/SkTransparentShader.cpp +++ b/gfx/skia/trunk/src/effects/SkTransparentShader.cpp @@ -23,13 +23,13 @@ bool SkTransparentShader::setContext(const SkBitmap& device, uint32_t SkTransparentShader::getFlags() { uint32_t flags = this->INHERITED::getFlags(); - switch (fDevice->config()) { - case SkBitmap::kRGB_565_Config: + switch (fDevice->colorType()) { + case kRGB_565_SkColorType: flags |= kHasSpan16_Flag; if (fAlpha == 255) flags |= kOpaqueAlpha_Flag; break; - case SkBitmap::kARGB_8888_Config: + case kPMColor_SkColorType: if (fAlpha == 255 && fDevice->isOpaque()) flags |= kOpaqueAlpha_Flag; break; @@ -42,8 +42,8 @@ uint32_t SkTransparentShader::getFlags() { void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) { unsigned scale = SkAlpha255To256(fAlpha); - switch (fDevice->config()) { - case SkBitmap::kARGB_8888_Config: + switch (fDevice->colorType()) { + case kPMColor_SkColorType: if (scale == 256) { SkPMColor* src = fDevice->getAddr32(x, y); if (src != span) { @@ -56,7 +56,7 @@ void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) { } } break; - case SkBitmap::kRGB_565_Config: { + case kRGB_565_SkColorType: { const uint16_t* src = fDevice->getAddr16(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { @@ -78,10 +78,7 @@ void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) { } break; } - case SkBitmap::kIndex8_Config: - SkDEBUGFAIL("index8 not supported as a destination device"); - break; - case SkBitmap::kA8_Config: { + case kAlpha_8_SkColorType: { const uint8_t* src = fDevice->getAddr8(x, y); if (scale == 256) { for (int i = count - 1; i >= 0; --i) { @@ -94,13 +91,14 @@ void SkTransparentShader::shadeSpan(int x, int y, SkPMColor span[], int count) { } break; } - default: // to avoid warnings + default: + SkDEBUGFAIL("colorType not supported as a destination device"); break; } } void SkTransparentShader::shadeSpan16(int x, int y, uint16_t span[], int count) { - SkASSERT(fDevice->config() == SkBitmap::kRGB_565_Config); + SkASSERT(fDevice->colorType() == kRGB_565_SkColorType); uint16_t* src = fDevice->getAddr16(x, y); if (src != span) { @@ -108,7 +106,7 @@ void SkTransparentShader::shadeSpan16(int x, int y, uint16_t span[], int count) } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkTransparentShader::toString(SkString* str) const { str->append("SkTransparentShader: ("); diff --git a/gfx/skia/trunk/src/effects/SkXfermodeImageFilter.cpp b/gfx/skia/trunk/src/effects/SkXfermodeImageFilter.cpp index d43699db6435..901353fabe7f 100644 --- a/gfx/skia/trunk/src/effects/SkXfermodeImageFilter.cpp +++ b/gfx/skia/trunk/src/effects/SkXfermodeImageFilter.cpp @@ -16,7 +16,6 @@ #include "GrContext.h" #include "effects/GrSimpleTextureEffect.h" #include "SkGr.h" -#include "SkImageFilterUtils.h" #endif /////////////////////////////////////////////////////////////////////////////// @@ -45,7 +44,7 @@ void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* dst, SkIPoint* offset) const { SkBitmap background = src, foreground = src; @@ -53,24 +52,23 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, SkImageFilter* foregroundInput = getInput(1); SkIPoint backgroundOffset = SkIPoint::Make(0, 0); if (backgroundInput && - !backgroundInput->filterImage(proxy, src, ctm, &background, &backgroundOffset)) { + !backgroundInput->filterImage(proxy, src, ctx, &background, &backgroundOffset)) { return false; } SkIPoint foregroundOffset = SkIPoint::Make(0, 0); if (foregroundInput && - !foregroundInput->filterImage(proxy, src, ctm, &foreground, &foregroundOffset)) { + !foregroundInput->filterImage(proxy, src, ctx, &foreground, &foregroundOffset)) { return false; } SkIRect bounds, foregroundBounds; - background.getBounds(&bounds); - bounds.offset(backgroundOffset); - foreground.getBounds(&foregroundBounds); - foregroundBounds.offset(foregroundOffset); - bounds.join(foregroundBounds); - if (!applyCropRect(&bounds, ctm)) { + if (!applyCropRect(ctx, foreground, foregroundOffset, &foregroundBounds)) { return false; } + if (!applyCropRect(ctx, background, backgroundOffset, &bounds)) { + return false; + } + bounds.join(foregroundBounds); SkAutoTUnref device(proxy->createDevice(bounds.width(), bounds.height())); if (NULL == device.get()) { @@ -98,20 +96,20 @@ bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, - const SkMatrix& ctm, + const Context& ctx, SkBitmap* result, SkIPoint* offset) const { - SkBitmap background; + SkBitmap background = src; SkIPoint backgroundOffset = SkIPoint::Make(0, 0); - if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &background, - &backgroundOffset)) { + if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &background, + &backgroundOffset)) { return false; } GrTexture* backgroundTex = background.getTexture(); - SkBitmap foreground; + SkBitmap foreground = src; SkIPoint foregroundOffset = SkIPoint::Make(0, 0); - if (!SkImageFilterUtils::GetInputResultGPU(getInput(1), proxy, src, ctm, &foreground, - &foregroundOffset)) { + if (getInput(1) && !getInput(1)->getInputResultGPU(proxy, src, ctx, &foreground, + &foregroundOffset)) { return false; } GrTexture* foregroundTex = foreground.getTexture(); @@ -160,7 +158,8 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, } offset->fX = backgroundOffset.fX; offset->fY = backgroundOffset.fY; - return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), result); + WrapTexture(dst, src.width(), src.height(), result); + return true; } #endif diff --git a/gfx/skia/trunk/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/trunk/src/effects/gradients/SkGradientShader.cpp index 1da259afe187..cd448b9cb89f 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkGradientShader.cpp +++ b/gfx/skia/trunk/src/effects/gradients/SkGradientShader.cpp @@ -583,7 +583,7 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const { if (fMapper) { // force our cahce32pixelref to be built (void)this->getCache32(); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1); + bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); bitmap->setPixelRef(fCache32PixelRef); return; } @@ -624,7 +624,7 @@ void SkGradientShaderBase::getGradientTableBitmap(SkBitmap* bitmap) const { if (!gCache->find(storage.get(), size, bitmap)) { // force our cahce32pixelref to be built (void)this->getCache32(); - bitmap->setConfig(SkBitmap::kARGB_8888_Config, kCache32Count, 1); + bitmap->setConfig(SkImageInfo::MakeN32Premul(kCache32Count, 1)); bitmap->setPixelRef(fCache32PixelRef); gCache->add(storage.get(), size, *bitmap); @@ -654,7 +654,7 @@ void SkGradientShaderBase::commonAsAGradient(GradientInfo* info) const { } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkGradientShaderBase::toString(SkString* str) const { str->appendf("%d colors: ", fColorCount); @@ -1043,7 +1043,7 @@ GrGradientEffect::GrGradientEffect(GrContext* ctx, desc.fHeight = 32; desc.fRowHeight = bitmap.height(); desc.fContext = ctx; - desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config()); + desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.colorType(), bitmap.alphaType()); fAtlas = GrTextureStripAtlas::GetAtlas(desc); SkASSERT(NULL != fAtlas); diff --git a/gfx/skia/trunk/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/trunk/src/effects/gradients/SkGradientShaderPriv.h index 184ef8e88375..83e078985318 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkGradientShaderPriv.h +++ b/gfx/skia/trunk/src/effects/gradients/SkGradientShaderPriv.h @@ -132,7 +132,7 @@ public: protected: SkGradientShaderBase(SkReadBuffer& ); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SkUnitMapper* fMapper; SkMatrix fPtsToUnit; // set by subclass diff --git a/gfx/skia/trunk/src/effects/gradients/SkLinearGradient.cpp b/gfx/skia/trunk/src/effects/gradients/SkLinearGradient.cpp index bd66f7ca8496..b24a6349c73c 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkLinearGradient.cpp +++ b/gfx/skia/trunk/src/effects/gradients/SkLinearGradient.cpp @@ -556,7 +556,7 @@ GrEffectRef* SkLinearGradient::asNewEffect(GrContext*, const SkPaint&) const { #endif -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkLinearGradient::toString(SkString* str) const { str->append("SkLinearGradient ("); diff --git a/gfx/skia/trunk/src/effects/gradients/SkLinearGradient.h b/gfx/skia/trunk/src/effects/gradients/SkLinearGradient.h index ed0c70b75584..013c4499b0c3 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkLinearGradient.h +++ b/gfx/skia/trunk/src/effects/gradients/SkLinearGradient.h @@ -22,7 +22,7 @@ public: virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLinearGradient) protected: diff --git a/gfx/skia/trunk/src/effects/gradients/SkRadialGradient.cpp b/gfx/skia/trunk/src/effects/gradients/SkRadialGradient.cpp index efa82f49bf3a..1b9e7258c4f5 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkRadialGradient.cpp +++ b/gfx/skia/trunk/src/effects/gradients/SkRadialGradient.cpp @@ -563,7 +563,7 @@ GrEffectRef* SkRadialGradient::asNewEffect(GrContext*, const SkPaint&) const { #endif -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkRadialGradient::toString(SkString* str) const { str->append("SkRadialGradient: ("); diff --git a/gfx/skia/trunk/src/effects/gradients/SkRadialGradient.h b/gfx/skia/trunk/src/effects/gradients/SkRadialGradient.h index 4ff3951b907f..4a725145b030 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkRadialGradient.h +++ b/gfx/skia/trunk/src/effects/gradients/SkRadialGradient.h @@ -24,7 +24,7 @@ public: virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRadialGradient) protected: diff --git a/gfx/skia/trunk/src/effects/gradients/SkSweepGradient.cpp b/gfx/skia/trunk/src/effects/gradients/SkSweepGradient.cpp index 494569df5dc2..7024945bf0a0 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkSweepGradient.cpp +++ b/gfx/skia/trunk/src/effects/gradients/SkSweepGradient.cpp @@ -249,8 +249,18 @@ void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder, const TextureSamplerArray& samplers) { this->emitUniforms(builder, key); SkString coords2D = builder->ensureFSCoords2D(coords, 0); + const GrGLContextInfo ctxInfo = builder->ctxInfo(); SkString t; - t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", coords2D.c_str(), coords2D.c_str()); + // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi] + // On Intel GPU there is an issue where it reads the second arguement to atan "- %s.x" as an int + // thus must us -1.0 * %s.x to work correctly + if (kIntel_GrGLVendor != ctxInfo.vendor()){ + t.printf("atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5", + coords2D.c_str(), coords2D.c_str()); + } else { + t.printf("atan(- %s.y, -1.0 * %s.x) * 0.1591549430918 + 0.5", + coords2D.c_str(), coords2D.c_str()); + } this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers); } @@ -275,7 +285,7 @@ GrEffectRef* SkSweepGradient::asNewEffect(GrContext*, const SkPaint&) const { #endif -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkSweepGradient::toString(SkString* str) const { str->append("SkSweepGradient: ("); diff --git a/gfx/skia/trunk/src/effects/gradients/SkSweepGradient.h b/gfx/skia/trunk/src/effects/gradients/SkSweepGradient.h index 18d5ddc0ef64..ca19da25baf7 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkSweepGradient.h +++ b/gfx/skia/trunk/src/effects/gradients/SkSweepGradient.h @@ -25,7 +25,7 @@ public: virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSweepGradient) protected: diff --git a/gfx/skia/trunk/src/effects/gradients/SkTwoPointConicalGradient.cpp b/gfx/skia/trunk/src/effects/gradients/SkTwoPointConicalGradient.cpp index 6a503d2fb7be..434339cde761 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkTwoPointConicalGradient.cpp +++ b/gfx/skia/trunk/src/effects/gradients/SkTwoPointConicalGradient.cpp @@ -710,7 +710,7 @@ GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext*, const SkPaint&) #endif -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkTwoPointConicalGradient::toString(SkString* str) const { str->append("SkTwoPointConicalGradient: ("); diff --git a/gfx/skia/trunk/src/effects/gradients/SkTwoPointConicalGradient.h b/gfx/skia/trunk/src/effects/gradients/SkTwoPointConicalGradient.h index 20a3da8b2e82..dd77299c7ddf 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkTwoPointConicalGradient.h +++ b/gfx/skia/trunk/src/effects/gradients/SkTwoPointConicalGradient.h @@ -66,7 +66,7 @@ public: SkScalar getStartRadius() const { return fRadius1; } SkScalar getDiffRadius() const { return fRadius2 - fRadius1; } - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTwoPointConicalGradient) protected: diff --git a/gfx/skia/trunk/src/effects/gradients/SkTwoPointRadialGradient.cpp b/gfx/skia/trunk/src/effects/gradients/SkTwoPointRadialGradient.cpp index 103e7d41c9ca..e1359b12ddce 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkTwoPointRadialGradient.cpp +++ b/gfx/skia/trunk/src/effects/gradients/SkTwoPointRadialGradient.cpp @@ -307,7 +307,7 @@ bool SkTwoPointRadialGradient::setContext( const SkBitmap& device, return true; } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkTwoPointRadialGradient::toString(SkString* str) const { str->append("SkTwoPointRadialGradient: ("); diff --git a/gfx/skia/trunk/src/effects/gradients/SkTwoPointRadialGradient.h b/gfx/skia/trunk/src/effects/gradients/SkTwoPointRadialGradient.h index e050804b4654..ee1b49ee952c 100644 --- a/gfx/skia/trunk/src/effects/gradients/SkTwoPointRadialGradient.h +++ b/gfx/skia/trunk/src/effects/gradients/SkTwoPointRadialGradient.h @@ -33,7 +33,7 @@ public: SkScalar getStartRadius() const { return fStartRadius; } SkScalar getDiffRadius() const { return fDiffRadius; } - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTwoPointRadialGradient) protected: diff --git a/gfx/skia/trunk/src/gpu/GrAAHairLinePathRenderer.cpp b/gfx/skia/trunk/src/gpu/GrAAHairLinePathRenderer.cpp index 830f513e6cf8..60be5be9079e 100644 --- a/gfx/skia/trunk/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/gfx/skia/trunk/src/gpu/GrAAHairLinePathRenderer.cpp @@ -997,7 +997,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path, kVertsPerQuad * quadCnt + kVertsPerQuad * conicCnt)); if (quadCnt > 0) { - GrEffectRef* hairQuadEffect = GrQuadEffect::Create(kHairAA_GrBezierEdgeType, + GrEffectRef* hairQuadEffect = GrQuadEffect::Create(kHairlineAA_GrEffectEdgeType, *target->caps()); SkASSERT(NULL != hairQuadEffect); GrDrawState::AutoRestoreEffects are(drawState); @@ -1018,7 +1018,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path, if (conicCnt > 0) { GrDrawState::AutoRestoreEffects are(drawState); - GrEffectRef* hairConicEffect = GrConicEffect::Create(kHairAA_GrBezierEdgeType, + GrEffectRef* hairConicEffect = GrConicEffect::Create(kHairlineAA_GrEffectEdgeType, *target->caps()); SkASSERT(NULL != hairConicEffect); drawState->addCoverageEffect(hairConicEffect, 1, 2)->unref(); diff --git a/gfx/skia/trunk/src/gpu/GrAllocator.h b/gfx/skia/trunk/src/gpu/GrAllocator.h old mode 100755 new mode 100644 diff --git a/gfx/skia/trunk/src/gpu/GrAtlas.cpp b/gfx/skia/trunk/src/gpu/GrAtlas.cpp index dd362908d3fe..349b47f62062 100644 --- a/gfx/skia/trunk/src/gpu/GrAtlas.cpp +++ b/gfx/skia/trunk/src/gpu/GrAtlas.cpp @@ -35,12 +35,6 @@ /////////////////////////////////////////////////////////////////////////////// -#define BORDER 1 - -#ifdef SK_DEBUG - static int gCounter; -#endif - // for testing #define FONT_CACHE_STATS 0 #if FONT_CACHE_STATS @@ -48,13 +42,12 @@ static int g_UploadCount = 0; #endif GrPlot::GrPlot() : fDrawToken(NULL, 0) - , fNext(NULL) , fTexture(NULL) , fAtlasMgr(NULL) , fBytesPerPixel(1) { - fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER, - GR_ATLAS_HEIGHT - BORDER); + fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH, + GR_ATLAS_HEIGHT); fOffset.set(0, 0); } @@ -67,49 +60,23 @@ static inline void adjust_for_offset(GrIPoint16* loc, const GrIPoint16& offset) loc->fY += offset.fY * GR_ATLAS_HEIGHT; } -static inline uint8_t* zero_fill(uint8_t* ptr, size_t count) { - sk_bzero(ptr, count); - return ptr + count; -} - bool GrPlot::addSubImage(int width, int height, const void* image, GrIPoint16* loc) { - if (!fRects->addRect(width + BORDER, height + BORDER, loc)) { + if (!fRects->addRect(width, height, loc)) { return false; } SkAutoSMalloc<1024> storage; - int dstW = width + 2*BORDER; - int dstH = height + 2*BORDER; - if (BORDER) { - const size_t dstRB = dstW * fBytesPerPixel; - uint8_t* dst = (uint8_t*)storage.reset(dstH * dstRB); - sk_bzero(dst, dstRB); // zero top row - dst += dstRB; - for (int y = 0; y < height; y++) { - dst = zero_fill(dst, fBytesPerPixel); // zero left edge - memcpy(dst, image, width * fBytesPerPixel); - dst += width * fBytesPerPixel; - dst = zero_fill(dst, fBytesPerPixel); // zero right edge - image = (const void*)((const char*)image + width * fBytesPerPixel); - } - sk_bzero(dst, dstRB); // zero bottom row - image = storage.get(); - } adjust_for_offset(loc, fOffset); GrContext* context = fTexture->getContext(); // We pass the flag that does not force a flush. We assume our caller is // smart and hasn't referenced the part of the texture we're about to update // since the last flush. context->writeTexturePixels(fTexture, - loc->fX, loc->fY, dstW, dstH, + loc->fX, loc->fY, width, height, fTexture->config(), image, 0, GrContext::kDontFlush_PixelOpsFlag); - // now tell the caller to skip the top/left BORDER - loc->fX += BORDER; - loc->fY += BORDER; - #if FONT_CACHE_STATS ++g_UploadCount; #endif @@ -117,6 +84,11 @@ bool GrPlot::addSubImage(int width, int height, const void* image, return true; } +void GrPlot::resetRects() { + SkASSERT(NULL != fRects); + fRects->reset(); +} + /////////////////////////////////////////////////////////////////////////////// GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) { @@ -127,19 +99,17 @@ GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) { // set up allocated plots size_t bpp = GrBytesPerPixel(fPixelConfig); - fPlots = SkNEW_ARRAY(GrPlot, (GR_PLOT_WIDTH*GR_PLOT_HEIGHT)); - fFreePlots = NULL; - GrPlot* currPlot = fPlots; + fPlotArray = SkNEW_ARRAY(GrPlot, (GR_PLOT_WIDTH*GR_PLOT_HEIGHT)); + + GrPlot* currPlot = fPlotArray; for (int y = GR_PLOT_HEIGHT-1; y >= 0; --y) { for (int x = GR_PLOT_WIDTH-1; x >= 0; --x) { currPlot->fAtlasMgr = this; currPlot->fOffset.set(x, y); currPlot->fBytesPerPixel = bpp; - // add to free list - currPlot->fNext = fFreePlots; - fFreePlots = currPlot; - + // build LRU list + fPlotList.addToHead(currPlot); ++currPlot; } } @@ -147,7 +117,7 @@ GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) { GrAtlasMgr::~GrAtlasMgr() { SkSafeUnref(fTexture); - SkDELETE_ARRAY(fPlots); + SkDELETE_ARRAY(fPlotArray); fGpu->unref(); #if FONT_CACHE_STATS @@ -155,25 +125,29 @@ GrAtlasMgr::~GrAtlasMgr() { #endif } +void GrAtlasMgr::moveToHead(GrPlot* plot) { + if (fPlotList.head() == plot) { + return; + } + + fPlotList.remove(plot); + fPlotList.addToHead(plot); +}; + GrPlot* GrAtlasMgr::addToAtlas(GrAtlas* atlas, int width, int height, const void* image, GrIPoint16* loc) { - // iterate through entire plot list, see if we can find a hole - GrPlot* plotIter = atlas->fPlots; - while (plotIter) { - if (plotIter->addSubImage(width, height, image, loc)) { - return plotIter; + // iterate through entire plot list for this atlas, see if we can find a hole + // last one was most recently added and probably most empty + for (int i = atlas->fPlots.count()-1; i >= 0; --i) { + GrPlot* plot = atlas->fPlots[i]; + if (plot->addSubImage(width, height, image, loc)) { + this->moveToHead(plot); + return plot; } - plotIter = plotIter->fNext; - } - - // If the above fails, then either we have no starting plot, or the current - // plot list is full. Either way we need to allocate a new plot - GrPlot* newPlot = this->allocPlot(); - if (NULL == newPlot) { - return NULL; } + // before we get a new plot, make sure we have a backing texture if (NULL == fTexture) { // TODO: Update this to use the cache rather than directly creating a texture. GrTextureDesc desc; @@ -187,75 +161,55 @@ GrPlot* GrAtlasMgr::addToAtlas(GrAtlas* atlas, return NULL; } } - // be sure to set texture for fast lookup - newPlot->fTexture = fTexture; - if (!newPlot->addSubImage(width, height, image, loc)) { - this->freePlot(newPlot); - return NULL; + // now look through all allocated plots for one we can share, in MRU order + GrPlotList::Iter plotIter; + plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart); + GrPlot* plot; + while (NULL != (plot = plotIter.get())) { + // make sure texture is set for quick lookup + plot->fTexture = fTexture; + if (plot->addSubImage(width, height, image, loc)) { + this->moveToHead(plot); + // new plot for atlas, put at end of array + *(atlas->fPlots.append()) = plot; + return plot; + } + plotIter.next(); } - // new plot, put at head - newPlot->fNext = atlas->fPlots; - atlas->fPlots = newPlot; - - return newPlot; + // If the above fails, then the current plot list has no room + return NULL; } -bool GrAtlasMgr::removeUnusedPlots(GrAtlas* atlas) { - - // GrPlot** is used so that the head element can be easily - // modified when the first element is deleted - GrPlot** plotRef = &atlas->fPlots; - GrPlot* plot = atlas->fPlots; - bool removed = false; - while (NULL != plot) { - if (plot->drawToken().isIssued()) { - *plotRef = plot->fNext; - this->freePlot(plot); - plot = *plotRef; - removed = true; - } else { - plotRef = &plot->fNext; - plot = plot->fNext; +bool GrAtlasMgr::removePlot(GrAtlas* atlas, const GrPlot* plot) { + // iterate through plot list for this atlas + int count = atlas->fPlots.count(); + for (int i = 0; i < count; ++i) { + if (plot == atlas->fPlots[i]) { + atlas->fPlots.remove(i); + return true; } } - return removed; + return false; } -void GrAtlasMgr::deletePlotList(GrPlot* plot) { - while (NULL != plot) { - GrPlot* next = plot->fNext; - this->freePlot(plot); - plot = next; - } -} - -GrPlot* GrAtlasMgr::allocPlot() { - if (NULL == fFreePlots) { - return NULL; - } else { - GrPlot* alloc = fFreePlots; - fFreePlots = alloc->fNext; -#ifdef SK_DEBUG -// GrPrintf(" GrPlot %p [%d %d] %d\n", this, alloc->fOffset.fX, alloc->fOffset.fY, gCounter); - gCounter += 1; -#endif - return alloc; +// get a plot that's not being used by the current draw +GrPlot* GrAtlasMgr::getUnusedPlot() { + GrPlotList::Iter plotIter; + plotIter.init(fPlotList, GrPlotList::Iter::kTail_IterStart); + GrPlot* plot; + while (NULL != (plot = plotIter.get())) { + if (plot->drawToken().isIssued()) { + return plot; + } + plotIter.prev(); } + return NULL; } -void GrAtlasMgr::freePlot(GrPlot* plot) { - SkASSERT(this == plot->fAtlasMgr); - - plot->fRects->reset(); - plot->fNext = fFreePlots; - fFreePlots = plot; - -#ifdef SK_DEBUG - --gCounter; -// GrPrintf("~GrPlot %p [%d %d] %d\n", this, plot->fOffset.fX, plot->fOffset.fY, gCounter); -#endif +SkISize GrAtlas::getSize() const { + return SkISize::Make(GR_ATLAS_TEXTURE_WIDTH, GR_ATLAS_TEXTURE_HEIGHT); } diff --git a/gfx/skia/trunk/src/gpu/GrAtlas.h b/gfx/skia/trunk/src/gpu/GrAtlas.h index 3d6869817d2a..7219ab24c25d 100644 --- a/gfx/skia/trunk/src/gpu/GrAtlas.h +++ b/gfx/skia/trunk/src/gpu/GrAtlas.h @@ -31,6 +31,8 @@ class GrAtlas; class GrPlot { public: + SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrPlot); + int getOffsetX() const { return fOffset.fX; } int getOffsetY() const { return fOffset.fY; } @@ -41,6 +43,8 @@ public: GrDrawTarget::DrawToken drawToken() const { return fDrawToken; } void setDrawToken(GrDrawTarget::DrawToken draw) { fDrawToken = draw; } + void resetRects(); + private: GrPlot(); ~GrPlot(); // does not try to delete the fNext field @@ -48,8 +52,6 @@ private: // for recycling GrDrawTarget::DrawToken fDrawToken; - GrPlot* fNext; - GrTexture* fTexture; GrRectanizer* fRects; GrAtlasMgr* fAtlasMgr; @@ -59,6 +61,8 @@ private: friend class GrAtlasMgr; }; +typedef SkTInternalLList GrPlotList; + class GrAtlasMgr { public: GrAtlasMgr(GrGpu*, GrPixelConfig); @@ -68,40 +72,41 @@ public: // returns the containing GrPlot and location relative to the backing texture GrPlot* addToAtlas(GrAtlas*, int width, int height, const void*, GrIPoint16*); - // free up any plots that are not waiting on a draw call - bool removeUnusedPlots(GrAtlas* atlas); + // remove reference to this plot + bool removePlot(GrAtlas* atlas, const GrPlot* plot); - // to be called by ~GrAtlas() - void deletePlotList(GrPlot* plot); + // get a plot that's not being used by the current draw + // this allows us to overwrite this plot without flushing + GrPlot* getUnusedPlot(); GrTexture* getTexture() const { return fTexture; } private: - GrPlot* allocPlot(); - void freePlot(GrPlot* plot); + void moveToHead(GrPlot* plot); GrGpu* fGpu; GrPixelConfig fPixelConfig; GrTexture* fTexture; // allocated array of GrPlots - GrPlot* fPlots; - // linked list of free GrPlots - GrPlot* fFreePlots; + GrPlot* fPlotArray; + // LRU list of GrPlots + GrPlotList fPlotList; }; class GrAtlas { public: - GrAtlas(GrAtlasMgr* mgr) : fPlots(NULL), fAtlasMgr(mgr) { } - ~GrAtlas() { fAtlasMgr->deletePlotList(fPlots); } + GrAtlas() { } + ~GrAtlas() { } - bool isEmpty() { return NULL == fPlots; } + bool isEmpty() { return 0 == fPlots.count(); } + + SkISize getSize() const; private: - GrPlot* fPlots; - GrAtlasMgr* fAtlasMgr; + SkTDArray fPlots; friend class GrAtlasMgr; }; diff --git a/gfx/skia/trunk/src/gpu/GrBitmapTextContext.cpp b/gfx/skia/trunk/src/gpu/GrBitmapTextContext.cpp index 4f43c758992e..3683e9720188 100755 --- a/gfx/skia/trunk/src/gpu/GrBitmapTextContext.cpp +++ b/gfx/skia/trunk/src/gpu/GrBitmapTextContext.cpp @@ -488,11 +488,7 @@ void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed, } if (NULL == fStrike) { -#if SK_DISTANCEFIELD_FONTS fStrike = fContext->getFontCache()->getStrike(scaler, false); -#else - fStrike = fContext->getFontCache()->getStrike(scaler); -#endif } GrGlyph* glyph = fStrike->getGlyph(packed, scaler); @@ -518,13 +514,13 @@ void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed, } if (NULL == glyph->fPlot) { - if (fStrike->getGlyphAtlas(glyph, scaler)) { + if (fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } // try to clear out an unused plot before we flush - fContext->getFontCache()->freePlotExceptFor(fStrike); - if (fStrike->getGlyphAtlas(glyph, scaler)) { + if (fContext->getFontCache()->freeUnusedPlot(fStrike) && + fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } @@ -534,14 +530,13 @@ void GrBitmapTextContext::drawPackedGlyph(GrGlyph::PackedID packed, #endif } - // before we purge the cache, we must flush any accumulated draws + // flush any accumulated draws to allow us to free up a plot this->flushGlyphs(); fContext->flush(); - // try to purge - fContext->getFontCache()->purgeExceptFor(fStrike); - // need to use new flush count here - if (fStrike->getGlyphAtlas(glyph, scaler)) { + // we should have an unused plot now + if (fContext->getFontCache()->freeUnusedPlot(fStrike) && + fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } diff --git a/gfx/skia/trunk/src/gpu/GrClipMaskManager.cpp b/gfx/skia/trunk/src/gpu/GrClipMaskManager.cpp index 83b3b01159b9..96f4b209e385 100644 --- a/gfx/skia/trunk/src/gpu/GrClipMaskManager.cpp +++ b/gfx/skia/trunk/src/gpu/GrClipMaskManager.cpp @@ -19,6 +19,7 @@ #include "GrSWMaskHelper.h" #include "effects/GrTextureDomain.h" #include "effects/GrConvexPolyEffect.h" +#include "effects/GrRRectEffect.h" #include "SkRasterClip.h" #include "SkStrokeRec.h" #include "SkTLazy.h" @@ -94,18 +95,118 @@ bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { const Element* element = iter.get(); // rects can always be drawn directly w/o using the software path - // so only paths need to be checked - if (Element::kPath_Type == element->getType() && - path_needs_SW_renderer(this->getContext(), fGpu, - element->getPath(), - stroke, - element->isAA())) { - return true; + // Skip rrects once we're drawing them directly. + if (Element::kRect_Type != element->getType()) { + SkPath path; + element->asPath(&path); + if (path_needs_SW_renderer(this->getContext(), fGpu, path, stroke, element->isAA())) { + return true; + } } } return false; } +bool GrClipMaskManager::installClipEffects(const ElementList& elements, + GrDrawState::AutoRestoreEffects* are, + const SkVector& clipToRTOffset, + const SkRect* drawBounds) { + + GrDrawState* drawState = fGpu->drawState(); + SkRect boundsInClipSpace; + if (NULL != drawBounds) { + boundsInClipSpace = *drawBounds; + boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); + } + + are->set(drawState); + GrRenderTarget* rt = drawState->getRenderTarget(); + ElementList::Iter iter(elements); + + bool setARE = false; + bool failed = false; + + while (NULL != iter.get()) { + SkRegion::Op op = iter.get()->getOp(); + bool invert; + bool skip = false; + switch (op) { + case SkRegion::kReplace_Op: + SkASSERT(iter.get() == elements.head()); + // Fallthrough, handled same as intersect. + case SkRegion::kIntersect_Op: + invert = false; + if (NULL != drawBounds && iter.get()->contains(boundsInClipSpace)) { + skip = true; + } + break; + case SkRegion::kDifference_Op: + invert = true; + // We don't currently have a cheap test for whether a rect is fully outside an + // element's primitive, so don't attempt to set skip. + break; + default: + failed = true; + break; + } + if (failed) { + break; + } + + if (!skip) { + GrEffectEdgeType edgeType; + if (GR_AA_CLIP && iter.get()->isAA()) { + if (rt->isMultisampled()) { + // Coverage based AA clips don't place nicely with MSAA. + failed = true; + break; + } + edgeType = invert ? kInverseFillAA_GrEffectEdgeType : kFillAA_GrEffectEdgeType; + } else { + edgeType = invert ? kInverseFillBW_GrEffectEdgeType : kFillBW_GrEffectEdgeType; + } + SkAutoTUnref effect; + switch (iter.get()->getType()) { + case SkClipStack::Element::kPath_Type: + effect.reset(GrConvexPolyEffect::Create(edgeType, iter.get()->getPath(), + &clipToRTOffset)); + break; + case SkClipStack::Element::kRRect_Type: { + SkRRect rrect = iter.get()->getRRect(); + rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY); + effect.reset(GrRRectEffect::Create(edgeType, rrect)); + break; + } + case SkClipStack::Element::kRect_Type: { + SkRect rect = iter.get()->getRect(); + rect.offset(clipToRTOffset.fX, clipToRTOffset.fY); + effect.reset(GrConvexPolyEffect::Create(edgeType, rect)); + break; + } + default: + break; + } + if (effect) { + if (!setARE) { + are->set(fGpu->drawState()); + setARE = true; + } + fGpu->drawState()->addCoverageEffect(effect); + } else { + failed = true; + break; + } + } + iter.next(); + } + + if (failed) { + are->set(NULL); + } + + return !failed; +} + //////////////////////////////////////////////////////////////////////////////// // sort out what kind of clip mask needs to be created: alpha, stencil, // scissor, or entirely software @@ -155,57 +256,27 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, return true; } - // If there is only one clip element we check whether the draw's bounds are contained - // fully within the clip. If not, we install an effect that handles the clip for some - // cases. - if (1 == elements.count() && SkRegion::kReplace_Op == elements.tail()->getOp()) { - if (NULL != devBounds) { - SkRect boundsInClipSpace = *devBounds; - boundsInClipSpace.offset(SkIntToScalar(clipDataIn->fOrigin.fX), - SkIntToScalar(clipDataIn->fOrigin.fY)); - if (elements.tail()->contains(boundsInClipSpace)) { - fGpu->disableScissor(); - this->setGpuStencil(); - return true; - } - } - SkAutoTUnref effect; - if (SkClipStack::Element::kPath_Type == elements.tail()->getType()) { - const SkPath& path = elements.tail()->getPath(); - bool isAA = GR_AA_CLIP && elements.tail()->isAA(); - if (rt->isMultisampled()) { - // A coverage effect for AA clipping won't play nicely with MSAA. - if (!isAA) { - SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX), - SkIntToScalar(-clipDataIn->fOrigin.fY) }; - effect.reset(GrConvexPolyEffect::Create(GrConvexPolyEffect::kFillNoAA_EdgeType, - path, &offset)); - } - } else { - SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX), + // An element count of 4 was chosen because of the common pattern in Blink of: + // isect RR + // diff RR + // isect convex_poly + // isect convex_poly + // when drawing rounded div borders. This could probably be tuned based on a + // configuration's relative costs of switching RTs to generate a mask vs + // longer shaders. + if (elements.count() <= 4) { + SkVector clipToRTOffset = { SkIntToScalar(-clipDataIn->fOrigin.fX), SkIntToScalar(-clipDataIn->fOrigin.fY) }; - GrConvexPolyEffect::EdgeType type = isAA ? GrConvexPolyEffect::kFillAA_EdgeType : - GrConvexPolyEffect::kFillNoAA_EdgeType; - effect.reset(GrConvexPolyEffect::Create(type, path, &offset)); - } - } else if (GR_AA_CLIP && elements.tail()->isAA() && !rt->isMultisampled()) { - // We only handle AA/non-MSAA rects here. Coverage effect AA isn't MSAA friendly and - // non-AA rect clips are handled by the scissor. - SkASSERT(SkClipStack::Element::kRect_Type == elements.tail()->getType()); - SkRect rect = elements.tail()->getRect(); - SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX), - SkIntToScalar(-clipDataIn->fOrigin.fY) }; - rect.offset(offset); - effect.reset(GrConvexPolyEffect::CreateForAAFillRect(rect)); - // This should never fail. - SkASSERT(effect); - } - if (effect) { - are->set(fGpu->drawState()); - fGpu->drawState()->addCoverageEffect(effect); + if (elements.isEmpty() || + this->installClipEffects(elements, are, clipToRTOffset, devBounds)) { SkIRect scissorSpaceIBounds(clipSpaceIBounds); scissorSpaceIBounds.offset(-clipDataIn->fOrigin); - fGpu->enableScissor(scissorSpaceIBounds); + if (NULL == devBounds || + !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { + fGpu->enableScissor(scissorSpaceIBounds); + } else { + fGpu->disableScissor(); + } this->setGpuStencil(); return true; } @@ -332,7 +403,11 @@ bool GrClipMaskManager::drawElement(GrTexture* target, drawState->setRenderTarget(target->asRenderTarget()); + // TODO: Draw rrects directly here. switch (element->getType()) { + case Element::kEmpty_Type: + SkDEBUGFAIL("Should never get here with an empty element."); + break; case Element::kRect_Type: // TODO: Do rects directly to the accumulator using a aa-rect GrEffect that covers the // entire mask bounds and writes 0 outside the rect. @@ -347,28 +422,25 @@ bool GrClipMaskManager::drawElement(GrTexture* target, fGpu->drawSimpleRect(element->getRect(), NULL); } return true; - case Element::kPath_Type: { - SkTCopyOnFirstWrite path(element->getPath()); - if (path->isInverseFillType()) { - path.writable()->toggleInverseFillType(); + default: { + SkPath path; + element->asPath(&path); + if (path.isInverseFillType()) { + path.toggleInverseFillType(); } SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); if (NULL == pr) { GrPathRendererChain::DrawType type; type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType : GrPathRendererChain::kColor_DrawType; - pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false, type); + pr = this->getContext()->getPathRenderer(path, stroke, fGpu, false, type); } if (NULL == pr) { return false; } - pr->drawPath(element->getPath(), stroke, fGpu, element->isAA()); + pr->drawPath(path, stroke, fGpu, element->isAA()); break; } - default: - // something is wrong if we're trying to draw an empty element. - GrCrash("Unexpected element type"); - return false; } return true; } @@ -379,25 +451,22 @@ bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, GrDrawState* drawState = fGpu->drawState(); drawState->setRenderTarget(target->asRenderTarget()); - switch (element->getType()) { - case Element::kRect_Type: - return true; - case Element::kPath_Type: { - SkTCopyOnFirstWrite path(element->getPath()); - if (path->isInverseFillType()) { - path.writable()->toggleInverseFillType(); - } - SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); - GrPathRendererChain::DrawType type = element->isAA() ? - GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : - GrPathRendererChain::kStencilAndColor_DrawType; - *pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false, type); - return NULL != *pr; + if (Element::kRect_Type == element->getType()) { + return true; + } else { + // We shouldn't get here with an empty clip element. + SkASSERT(Element::kEmpty_Type != element->getType()); + SkPath path; + element->asPath(&path); + if (path.isInverseFillType()) { + path.toggleInverseFillType(); } - default: - // something is wrong if we're trying to draw an empty element. - GrCrash("Unexpected element type"); - return false; + SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); + GrPathRendererChain::DrawType type = element->isAA() ? + GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : + GrPathRendererChain::kStencilAndColor_DrawType; + *pr = this->getContext()->getPathRenderer(path, stroke, fGpu, false, type); + return NULL != *pr; } } @@ -700,18 +769,17 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, SkRegion::Op op = element->getOp(); GrPathRenderer* pr = NULL; - SkTCopyOnFirstWrite clipPath; + SkPath clipPath; if (Element::kRect_Type == element->getType()) { stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; fillInverted = false; } else { - SkASSERT(Element::kPath_Type == element->getType()); - clipPath.init(element->getPath()); - fillInverted = clipPath->isInverseFillType(); + element->asPath(&clipPath); + fillInverted = clipPath.isInverseFillType(); if (fillInverted) { - clipPath.writable()->toggleInverseFillType(); + clipPath.toggleInverseFillType(); } - pr = this->getContext()->getPathRenderer(*clipPath, + pr = this->getContext()->getPathRenderer(clipPath, stroke, fGpu, false, @@ -752,13 +820,12 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, *drawState->stencil() = gDrawToStencil; fGpu->drawSimpleRect(element->getRect(), NULL); } else { - SkASSERT(Element::kPath_Type == element->getType()); - if (!clipPath->isEmpty()) { + if (!clipPath.isEmpty()) { if (canRenderDirectToStencil) { *drawState->stencil() = gDrawToStencil; - pr->drawPath(*clipPath, stroke, fGpu, false); + pr->drawPath(clipPath, stroke, fGpu, false); } else { - pr->stencilPath(*clipPath, stroke, fGpu); + pr->stencilPath(clipPath, stroke, fGpu); } } } @@ -774,9 +841,8 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, SET_RANDOM_COLOR fGpu->drawSimpleRect(element->getRect(), NULL); } else { - SkASSERT(Element::kPath_Type == element->getType()); SET_RANDOM_COLOR - pr->drawPath(*clipPath, stroke, fGpu, false); + pr->drawPath(clipPath, stroke, fGpu, false); } } else { SET_RANDOM_COLOR @@ -1026,24 +1092,10 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, helper.draw(temp, SkRegion::kXOR_Op, false, 0xFF); } - if (Element::kRect_Type == element->getType()) { - // convert the rect to a path so we can invert the fill - SkPath temp; - temp.addRect(element->getRect()); - temp.setFillType(SkPath::kInverseEvenOdd_FillType); - - helper.draw(temp, stroke, SkRegion::kReplace_Op, - element->isAA(), - 0x00); - } else { - SkASSERT(Element::kPath_Type == element->getType()); - SkPath clipPath = element->getPath(); - clipPath.toggleInverseFillType(); - helper.draw(clipPath, stroke, - SkRegion::kReplace_Op, - element->isAA(), - 0x00); - } + SkPath clipPath; + element->asPath(&clipPath); + clipPath.toggleInverseFillType(); + helper.draw(clipPath, stroke, SkRegion::kReplace_Op, element->isAA(), 0x00); continue; } @@ -1053,8 +1105,9 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, if (Element::kRect_Type == element->getType()) { helper.draw(element->getRect(), op, element->isAA(), 0xFF); } else { - SkASSERT(Element::kPath_Type == element->getType()); - helper.draw(element->getPath(), stroke, op, element->isAA(), 0xFF); + SkPath path; + element->asPath(&path); + helper.draw(path, stroke, op, element->isAA(), 0xFF); } } diff --git a/gfx/skia/trunk/src/gpu/GrClipMaskManager.h b/gfx/skia/trunk/src/gpu/GrClipMaskManager.h index 3d34fb95558b..17329108b39a 100644 --- a/gfx/skia/trunk/src/gpu/GrClipMaskManager.h +++ b/gfx/skia/trunk/src/gpu/GrClipMaskManager.h @@ -105,6 +105,13 @@ private: GrClipMaskCache fAACache; // cache for the AA path + // Attempts to install a series of coverage effects to implement the clip. Return indicates + // whether the element list was successfully converted to effects. + bool installClipEffects(const GrReducedClip::ElementList&, + GrDrawState::AutoRestoreEffects*, + const SkVector& clipOffset, + const SkRect* devBounds); + // Draws the clip into the stencil buffer bool createStencilClipMask(int32_t elementsGenID, GrReducedClip::InitialState initialState, diff --git a/gfx/skia/trunk/src/gpu/GrContext.cpp b/gfx/skia/trunk/src/gpu/GrContext.cpp index bb0f4fa9fab3..c7e343393879 100644 --- a/gfx/skia/trunk/src/gpu/GrContext.cpp +++ b/gfx/skia/trunk/src/gpu/GrContext.cpp @@ -1703,6 +1703,23 @@ bool GrContext::isConfigRenderable(GrPixelConfig config, bool withMSAA) const { return fGpu->caps()->isConfigRenderable(config, withMSAA); } +int GrContext::getRecommendedSampleCount(GrPixelConfig config, + SkScalar dpi) const { + if (!this->isConfigRenderable(config, true)) { + return 0; + } + int chosenSampleCount = 0; + if (fGpu->caps()->pathRenderingSupport()) { + if (dpi >= 250.0f) { + chosenSampleCount = 4; + } else { + chosenSampleCount = 16; + } + } + return chosenSampleCount <= fGpu->caps()->maxSampleCount() ? + chosenSampleCount : 0; +} + void GrContext::setupDrawBuffer() { SkASSERT(NULL == fDrawBuffer); SkASSERT(NULL == fDrawBufferVBAllocPool); diff --git a/gfx/skia/trunk/src/gpu/GrDistanceFieldTextContext.cpp b/gfx/skia/trunk/src/gpu/GrDistanceFieldTextContext.cpp index bd3927c64883..2163e6404909 100755 --- a/gfx/skia/trunk/src/gpu/GrDistanceFieldTextContext.cpp +++ b/gfx/skia/trunk/src/gpu/GrDistanceFieldTextContext.cpp @@ -8,6 +8,7 @@ #include "GrDistanceFieldTextContext.h" #include "GrAtlas.h" #include "GrDrawTarget.h" +#include "GrDrawTargetCaps.h" #include "GrFontScaler.h" #include "SkGlyphCache.h" #include "GrIndexBuffer.h" @@ -27,6 +28,12 @@ static const int kBaseDFFontSize = 32; SK_CONF_DECLARE(bool, c_DumpFontCache, "gpu.dumpFontCache", false, "Dump the contents of the font cache before every purge."); +#if SK_FORCE_DISTANCEFIELD_FONTS +static const bool kForceDistanceFieldFonts = true; +#else +static const bool kForceDistanceFieldFonts = false; +#endif + GrDistanceFieldTextContext::GrDistanceFieldTextContext(GrContext* context, const SkDeviceProperties& properties) : GrTextContext(context, properties) { @@ -44,8 +51,10 @@ GrDistanceFieldTextContext::~GrDistanceFieldTextContext() { } bool GrDistanceFieldTextContext::canDraw(const SkPaint& paint) { - return !paint.getRasterizer() && !paint.getMaskFilter() && + return (kForceDistanceFieldFonts || paint.isDistanceFieldTextTEMP()) && + !paint.getRasterizer() && !paint.getMaskFilter() && paint.getStyle() == SkPaint::kFill_Style && + fContext->getTextTarget()->caps()->shaderDerivativeSupport() && !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix()); } @@ -72,8 +81,9 @@ void GrDistanceFieldTextContext::flushGlyphs() { GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode); // This effect could be stored with one of the cache objects (atlas?) + SkISize size = fStrike->getAtlasSize(); drawState->addCoverageEffect( - GrDistanceFieldTextureEffect::Create(fCurrTexture, params), + GrDistanceFieldTextureEffect::Create(fCurrTexture, params, size), kGlyphCoordsAttributeIndex)->unref(); if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) { @@ -158,13 +168,13 @@ void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, } */ if (NULL == glyph->fPlot) { - if (fStrike->getGlyphAtlas(glyph, scaler)) { + if (fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } // try to clear out an unused plot before we flush - fContext->getFontCache()->freePlotExceptFor(fStrike); - if (fStrike->getGlyphAtlas(glyph, scaler)) { + if (fContext->getFontCache()->freeUnusedPlot(fStrike) && + fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } @@ -178,10 +188,9 @@ void GrDistanceFieldTextContext::drawPackedGlyph(GrGlyph::PackedID packed, this->flushGlyphs(); fContext->flush(); - // try to purge - fContext->getFontCache()->purgeExceptFor(fStrike); - // need to use new flush count here - if (fStrike->getGlyphAtlas(glyph, scaler)) { + // we should have an unused plot now + if (fContext->getFontCache()->freeUnusedPlot(fStrike) && + fStrike->addGlyphToAtlas(glyph, scaler)) { goto HAS_ATLAS; } @@ -269,16 +278,17 @@ HAS_ATLAS: GrFixed tw = SkIntToFixed(glyph->fBounds.width()); GrFixed th = SkIntToFixed(glyph->fBounds.height()); + static const size_t kVertexSize = 2 * sizeof(SkPoint); fVertices[2*fCurrVertex].setRectFan(sx, sy, sx + width, sy + height, - 2 * sizeof(SkPoint)); + kVertexSize); fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)), SkFixedToFloat(texture->normalizeFixedY(ty)), SkFixedToFloat(texture->normalizeFixedX(tx + tw)), SkFixedToFloat(texture->normalizeFixedY(ty + th)), - 2 * sizeof(SkPoint)); + kVertexSize); fCurrVertex += 4; } @@ -298,7 +308,7 @@ inline void GrDistanceFieldTextContext::init(const GrPaint& paint, const SkPaint fSkPaint.setTextSize(SkIntToScalar(kBaseDFFontSize)); fSkPaint.setLCDRenderText(false); fSkPaint.setAutohinted(false); - fSkPaint.setSubpixelText(false); + fSkPaint.setSubpixelText(true); } inline void GrDistanceFieldTextContext::finish() { diff --git a/gfx/skia/trunk/src/gpu/GrDrawTarget.cpp b/gfx/skia/trunk/src/gpu/GrDrawTarget.cpp index 0909e08dc85c..fb4c9a1509a4 100644 --- a/gfx/skia/trunk/src/gpu/GrDrawTarget.cpp +++ b/gfx/skia/trunk/src/gpu/GrDrawTarget.cpp @@ -88,7 +88,8 @@ void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) { GrDrawTarget::GrDrawTarget(GrContext* context) : fClip(NULL) - , fContext(context) { + , fContext(context) + , fPushGpuTraceCount(0) { SkASSERT(NULL != context); fDrawState = &fDefaultDrawState; @@ -547,6 +548,28 @@ void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) { this->onDrawPath(path, fill, dstCopy.texture() ? &dstCopy : NULL); } +void GrDrawTarget::instantGpuTraceEvent(const char* marker) { + if (this->caps()->gpuTracingSupport()) { + this->onInstantGpuTraceEvent(marker); + } +} + +void GrDrawTarget::pushGpuTraceEvent(const char* marker) { + SkASSERT(fPushGpuTraceCount >= 0); + if (this->caps()->gpuTracingSupport()) { + this->onPushGpuTraceEvent(marker); + ++fPushGpuTraceCount; + } +} + +void GrDrawTarget::popGpuTraceEvent() { + SkASSERT(fPushGpuTraceCount >= 1); + if (this->caps()->gpuTracingSupport()) { + this->onPopGpuTraceEvent(); + --fPushGpuTraceCount; + } +} + //////////////////////////////////////////////////////////////////////////////// bool GrDrawTarget::willUseHWAALines() const { @@ -971,6 +994,7 @@ void GrDrawTargetCaps::reset() { fPathRenderingSupport = false; fDstReadInShaderSupport = false; fReuseScratchTextures = true; + fGpuTracingSupport = false; fMaxRenderTargetSize = 0; fMaxTextureSize = 0; @@ -993,6 +1017,7 @@ GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) { fPathRenderingSupport = other.fPathRenderingSupport; fDstReadInShaderSupport = other.fDstReadInShaderSupport; fReuseScratchTextures = other.fReuseScratchTextures; + fGpuTracingSupport = other.fGpuTracingSupport; fMaxRenderTargetSize = other.fMaxRenderTargetSize; fMaxTextureSize = other.fMaxTextureSize; @@ -1019,6 +1044,7 @@ SkString GrDrawTargetCaps::dump() const { r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]); r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]); r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]); + r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]); r.appendf("Max Texture Size : %d\n", fMaxTextureSize); r.appendf("Max Render Target Size : %d\n", fMaxRenderTargetSize); r.appendf("Max Sample Count : %d\n", fMaxSampleCount); diff --git a/gfx/skia/trunk/src/gpu/GrDrawTarget.h b/gfx/skia/trunk/src/gpu/GrDrawTarget.h index c5058699b5ef..19ce16f64a68 100644 --- a/gfx/skia/trunk/src/gpu/GrDrawTarget.h +++ b/gfx/skia/trunk/src/gpu/GrDrawTarget.h @@ -422,6 +422,20 @@ public: bool canIgnoreRect, GrRenderTarget* renderTarget = NULL) = 0; + /** + * instantGpuTraceEvent places a single "sign post" type marker into command stream. The + * argument marker will be the name of the annotation that is added. + */ + void instantGpuTraceEvent(const char* marker); + /** + * The following two functions are used for marking groups of commands. Use pushGpuTraceEvent + * to set the beginning of a command set, and popGpuTraceEvent is be called at end of the + * command set. The argument marker is the name for the annotation that is added. The push and + * pops can be used hierarchically, but every push must have a match pop. + */ + void pushGpuTraceEvent(const char* marker); + void popGpuTraceEvent(); + /** * Copies a pixel rectangle from one surface to another. This call may finalize * reserved vertex/index data (as though a draw call was made). The src pixels @@ -854,6 +868,10 @@ private: virtual void onDrawPath(const GrPath*, SkPath::FillType, const GrDeviceCoordTexture* dstCopy) = 0; + virtual void onInstantGpuTraceEvent(const char* marker) = 0; + virtual void onPushGpuTraceEvent(const char* marker) = 0; + virtual void onPopGpuTraceEvent() = 0; + // helpers for reserving vertex and index space. bool reserveVertexSpace(size_t vertexSize, int vertexCount, @@ -888,6 +906,8 @@ private: GrDrawState fDefaultDrawState; // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget. GrContext* fContext; + // To keep track that we always have at least as many debug marker pushes as pops + int fPushGpuTraceCount; typedef SkRefCnt INHERITED; }; diff --git a/gfx/skia/trunk/src/gpu/GrDrawTargetCaps.h b/gfx/skia/trunk/src/gpu/GrDrawTargetCaps.h index b316e491c196..b33217a125e5 100644 --- a/gfx/skia/trunk/src/gpu/GrDrawTargetCaps.h +++ b/gfx/skia/trunk/src/gpu/GrDrawTargetCaps.h @@ -40,6 +40,7 @@ public: bool bufferLockSupport() const { return fBufferLockSupport; } bool pathRenderingSupport() const { return fPathRenderingSupport; } bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; } + bool gpuTracingSupport() const { return fGpuTracingSupport; } // Scratch textures not being reused means that those scratch textures // that we upload to (i.e., don't have a render target) will not be @@ -71,6 +72,7 @@ protected: bool fPathRenderingSupport : 1; bool fDstReadInShaderSupport : 1; bool fReuseScratchTextures : 1; + bool fGpuTracingSupport : 1; int fMaxRenderTargetSize; int fMaxTextureSize; diff --git a/gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.cpp b/gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.cpp index 669167c419bb..44bf4edab7aa 100644 --- a/gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.cpp +++ b/gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.cpp @@ -441,6 +441,18 @@ void GrInOrderDrawBuffer::clear(const SkIRect* rect, GrColor color, renderTarget->ref(); } +void GrInOrderDrawBuffer::onInstantGpuTraceEvent(const char* marker) { + // TODO: adds command to buffer +} + +void GrInOrderDrawBuffer::onPushGpuTraceEvent(const char* marker) { + // TODO: adds command to buffer +} + +void GrInOrderDrawBuffer::onPopGpuTraceEvent() { + // TODO: adds command to buffer +} + void GrInOrderDrawBuffer::reset() { SkASSERT(1 == fGeoPoolStateStack.count()); this->resetVertexSource(); diff --git a/gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.h b/gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.h index 6b680b2d555e..60e01f01b970 100644 --- a/gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.h +++ b/gfx/skia/trunk/src/gpu/GrInOrderDrawBuffer.h @@ -168,6 +168,11 @@ private: bool quickInsideClip(const SkRect& devBounds); + virtual void onInstantGpuTraceEvent(const char* marker) SK_OVERRIDE; + virtual void onPushGpuTraceEvent(const char* marker) SK_OVERRIDE; + virtual void onPopGpuTraceEvent() SK_OVERRIDE; + + // Attempts to concat instances from info onto the previous draw. info must represent an // instanced draw. The caller must have already recorded a new draw state and clip if necessary. int concatInstancedDraw(const DrawInfo& info); diff --git a/gfx/skia/trunk/src/gpu/GrOrderedSet.h b/gfx/skia/trunk/src/gpu/GrOrderedSet.h new file mode 100644 index 000000000000..b149dfb0c50b --- /dev/null +++ b/gfx/skia/trunk/src/gpu/GrOrderedSet.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. + */ + +#ifndef GrOrderedSet_DEFINED +#define GrOrderedSet_DEFINED + +#include "GrRedBlackTree.h" + +template > +class GrOrderedSet : public SkNoncopyable { +public: + /** + * Creates an empty set + */ + GrOrderedSet() : fComp() {} + ~GrOrderedSet() {} + + class Iter; + + /** + * @return true if there are no items in the set, false otherwise. + */ + bool empty() const { return fRBTree.empty(); } + + /** + * @return the number of items in the set. + */ + int count() const { return fRBTree.count(); } + + /** + * Removes all items in the set + */ + void reset() { fRBTree.reset(); } + + /** + * Adds an element to set if it does not already exists in the set. + * @param t the item to add + * @return an iterator to added element or matching element already in set + */ + Iter insert(const T& t); + + /** + * Removes the item indicated by an iterator. The iterator will not be valid + * afterwards. + * @param iter iterator of item to remove. Must be valid (not end()). + */ + void remove(const Iter& iter); + + /** + * @return an iterator to the first item in sorted order, or end() if empty + */ + Iter begin(); + + /** + * Gets the last valid iterator. This is always valid, even on an empty. + * However, it can never be dereferenced. Useful as a loop terminator. + * @return an iterator that is just beyond the last item in sorted order. + */ + Iter end(); + + /** + * @return an iterator that to the last item in sorted order, or end() if + * empty. + */ + Iter last(); + + /** + * Finds an occurrence of an item. + * @param t the item to find. + * @return an iterator to a set element equal to t or end() if none exists. + */ + Iter find(const T& t); + +private: + GrRedBlackTree fRBTree; + + const C fComp; +}; + +template +class GrOrderedSet::Iter { +public: + Iter() {} + Iter(const Iter& i) { fTreeIter = i.fTreeIter; } + Iter& operator =(const Iter& i) { + fTreeIter = i.fTreeIter; + return *this; + } + const T& operator *() const { return *fTreeIter; } + bool operator ==(const Iter& i) const { + return fTreeIter == i.fTreeIter; + } + bool operator !=(const Iter& i) const { return !(*this == i); } + Iter& operator ++() { + ++fTreeIter; + return *this; + } + Iter& operator --() { + --fTreeIter; + return *this; + } + const typename GrRedBlackTree::Iter& getTreeIter() const { + return fTreeIter; + } + +private: + friend class GrOrderedSet; + explicit Iter(typename GrRedBlackTree::Iter iter) { + fTreeIter = iter; + } + typename GrRedBlackTree::Iter fTreeIter; +}; + +template +typename GrOrderedSet::Iter GrOrderedSet::begin() { + return Iter(fRBTree.begin()); +} + +template +typename GrOrderedSet::Iter GrOrderedSet::end() { + return Iter(fRBTree.end()); +} + +template +typename GrOrderedSet::Iter GrOrderedSet::last() { + return Iter(fRBTree.last()); +} + +template +typename GrOrderedSet::Iter GrOrderedSet::find(const T& t) { + return Iter(fRBTree.find(t)); +} + +template +typename GrOrderedSet::Iter GrOrderedSet::insert(const T& t) { + if (fRBTree.find(t) == fRBTree.end()) { + return Iter(fRBTree.insert(t)); + } else { + return Iter(fRBTree.find(t)); + } +} + +template +void GrOrderedSet::remove(const typename GrOrderedSet::Iter& iter) { + if (this->end() != iter) { + fRBTree.remove(iter.getTreeIter()); + } +} + +#endif diff --git a/gfx/skia/trunk/src/gpu/GrRedBlackTree.h b/gfx/skia/trunk/src/gpu/GrRedBlackTree.h index db36e32d0473..6f5775470801 100644 --- a/gfx/skia/trunk/src/gpu/GrRedBlackTree.h +++ b/gfx/skia/trunk/src/gpu/GrRedBlackTree.h @@ -23,6 +23,11 @@ public: bool operator()(const T* a, const T* b) const { return *a < *b; } }; +class GrStrLess { +public: + bool operator()(const char* a, const char* b) const { return strcmp(a,b) < 0; } +}; + /** * In debug build this will cause full traversals of the tree when the validate * is called on insert and remove. Useful for debugging but very slow. diff --git a/gfx/skia/trunk/src/gpu/GrReducedClip.cpp b/gfx/skia/trunk/src/gpu/GrReducedClip.cpp index 8480e041b8dd..6ad9cc6d8b84 100644 --- a/gfx/skia/trunk/src/gpu/GrReducedClip.cpp +++ b/gfx/skia/trunk/src/gpu/GrReducedClip.cpp @@ -72,6 +72,8 @@ void ReduceClipStack(const SkClipStack& stack, *requiresAA = false; } } else if (isectRect.intersect(stackBounds, scalarQueryBounds)) { + // If the caller asked for tighter integer bounds we may be able to + // return kAllIn and give the bounds with no elements if (NULL != tighterBounds) { isectRect.roundOut(tighterBounds); SkRect scalarTighterBounds = SkRect::Make(*tighterBounds); @@ -83,14 +85,14 @@ void ReduceClipStack(const SkClipStack& stack, *initialState = kAllIn_InitialState; return; } - *initialState = kAllOut_InitialState; - // iior should only be true if aa/non-aa status matches among all elements. - SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); - bool doAA = iter.prev()->isAA(); - SkNEW_INSERT_AT_LLIST_HEAD(result, Element, (isectRect, SkRegion::kReplace_Op, doAA)); - if (NULL != requiresAA) { - *requiresAA = doAA; - } + } + *initialState = kAllOut_InitialState; + // iior should only be true if aa/non-aa status matches among all elements. + SkClipStack::Iter iter(stack, SkClipStack::Iter::kTop_IterStart); + bool doAA = iter.prev()->isAA(); + SkNEW_INSERT_AT_LLIST_HEAD(result, Element, (isectRect, SkRegion::kReplace_Op, doAA)); + if (NULL != requiresAA) { + *requiresAA = doAA; } } else { *initialState = kAllOut_InitialState; diff --git a/gfx/skia/trunk/src/gpu/GrReducedClip.h b/gfx/skia/trunk/src/gpu/GrReducedClip.h index 0b79f2c7f56f..cbb03465fd00 100644 --- a/gfx/skia/trunk/src/gpu/GrReducedClip.h +++ b/gfx/skia/trunk/src/gpu/GrReducedClip.h @@ -30,13 +30,14 @@ enum InitialState { * required to process any of the elements in the result. * * This may become a member function of SkClipStack when its interface is determined to be stable. + * Marked SK_API so that SkLua can call this in a shared library build. */ -void ReduceClipStack(const SkClipStack& stack, - const SkIRect& queryBounds, - ElementList* result, - int32_t* resultGenID, - InitialState* initialState, - SkIRect* tighterBounds = NULL, - bool* requiresAA = NULL); +SK_API void ReduceClipStack(const SkClipStack& stack, + const SkIRect& queryBounds, + ElementList* result, + int32_t* resultGenID, + InitialState* initialState, + SkIRect* tighterBounds = NULL, + bool* requiresAA = NULL); } // namespace GrReducedClip diff --git a/gfx/skia/trunk/src/gpu/GrTextStrike.cpp b/gfx/skia/trunk/src/gpu/GrTextStrike.cpp index c70e822cd9bf..0a1fd1e71f76 100644 --- a/gfx/skia/trunk/src/gpu/GrTextStrike.cpp +++ b/gfx/skia/trunk/src/gpu/GrTextStrike.cpp @@ -12,9 +12,7 @@ #include "GrTextStrike_impl.h" #include "SkString.h" -#if SK_DISTANCEFIELD_FONTS -#include "edtaa3.h" -#endif +#include "SkDistanceFieldGen.h" /////////////////////////////////////////////////////////////////////////////// @@ -110,47 +108,39 @@ void GrFontCache::purgeStrike(GrTextStrike* strike) { delete strike; } -void GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) { +bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) { SkASSERT(NULL != preserveStrike); - GrTextStrike* strike = fTail; - bool purge = true; + + GrAtlasMgr* atlasMgr = preserveStrike->fAtlasMgr; + GrPlot* plot = atlasMgr->getUnusedPlot(); + if (NULL == plot) { + return false; + } + plot->resetRects(); + + GrTextStrike* strike = fHead; GrMaskFormat maskFormat = preserveStrike->fMaskFormat; while (strike) { - if (strike == preserveStrike || maskFormat != strike->fMaskFormat) { - strike = strike->fPrev; + if (maskFormat != strike->fMaskFormat) { + strike = strike->fNext; continue; } + GrTextStrike* strikeToPurge = strike; - strike = strikeToPurge->fPrev; - if (purge) { - // keep purging if we won't free up any atlases with this strike. - purge = strikeToPurge->fAtlas.isEmpty(); + strike = strikeToPurge->fNext; + strikeToPurge->removePlot(plot); + + // clear out any empty strikes (except this one) + if (strikeToPurge != preserveStrike && strikeToPurge->fAtlas.isEmpty()) { this->purgeStrike(strikeToPurge); } } + #if FONT_CACHE_STATS ++g_PurgeCount; #endif -} -void GrFontCache::freePlotExceptFor(GrTextStrike* preserveStrike) { - SkASSERT(NULL != preserveStrike); - GrTextStrike* strike = fTail; - GrMaskFormat maskFormat = preserveStrike->fMaskFormat; - while (strike) { - if (strike == preserveStrike || maskFormat != strike->fMaskFormat) { - strike = strike->fPrev; - continue; - } - GrTextStrike* strikeToPurge = strike; - strike = strikeToPurge->fPrev; - if (strikeToPurge->removeUnusedPlots()) { - if (strikeToPurge->fAtlas.isEmpty()) { - this->purgeStrike(strikeToPurge); - } - break; - } - } + return true; } #ifdef SK_DEBUG @@ -206,10 +196,9 @@ void GrFontCache::dump() const { static int gCounter; #endif -#if SK_DISTANCEFIELD_FONTS -#define DISTANCE_FIELD_PAD 4 -#define DISTANCE_FIELD_RANGE (4.0) -#endif +// this acts as the max magnitude for the distance field, +// as well as the pad we need around the glyph +#define DISTANCE_FIELD_RANGE 4 /* The text strike is specific to a given font/style/matrix setup, which is @@ -221,7 +210,7 @@ void GrFontCache::dump() const { GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, GrMaskFormat format, - GrAtlasMgr* atlasMgr) : fPool(64), fAtlas(atlasMgr) { + GrAtlasMgr* atlasMgr) : fPool(64) { fFontScalerKey = key; fFontScalerKey->ref(); @@ -236,16 +225,10 @@ GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key, #endif } -// these signatures are needed because they're used with -// SkTDArray::visitAll() (see destructor & removeUnusedAtlases()) +// this signature is needed because it's used with +// SkTDArray::visitAll() (see destructor) static void free_glyph(GrGlyph*& glyph) { glyph->free(); } -static void invalidate_glyph(GrGlyph*& glyph) { - if (glyph->fPlot && glyph->fPlot->drawToken().isIssued()) { - glyph->fPlot = NULL; - } -} - GrTextStrike::~GrTextStrike() { fFontScalerKey->unref(); fCache.getArray().visitAll(free_glyph); @@ -264,27 +247,31 @@ GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed, } GrGlyph* glyph = fPool.alloc(); -#if SK_DISTANCEFIELD_FONTS // expand bounds to hold full distance field data if (fUseDistanceField) { - bounds.fLeft -= DISTANCE_FIELD_PAD; - bounds.fRight += DISTANCE_FIELD_PAD; - bounds.fTop -= DISTANCE_FIELD_PAD; - bounds.fBottom += DISTANCE_FIELD_PAD; + bounds.fLeft -= DISTANCE_FIELD_RANGE; + bounds.fRight += DISTANCE_FIELD_RANGE; + bounds.fTop -= DISTANCE_FIELD_RANGE; + bounds.fBottom += DISTANCE_FIELD_RANGE; } -#endif glyph->init(packed, bounds); fCache.insert(packed, glyph); return glyph; } -bool GrTextStrike::removeUnusedPlots() { - fCache.getArray().visitAll(invalidate_glyph); - return fAtlasMgr->removeUnusedPlots(&fAtlas); +void GrTextStrike::removePlot(const GrPlot* plot) { + SkTDArray& glyphArray = fCache.getArray(); + for (int i = 0; i < glyphArray.count(); ++i) { + if (plot == glyphArray[i]->fPlot) { + glyphArray[i]->fPlot = NULL; + } + } + + fAtlasMgr->removePlot(&fAtlas, plot); } -bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { +bool GrTextStrike::addGlyphToAtlas(GrGlyph* glyph, GrFontScaler* scaler) { #if 0 // testing hack to force us to flush our cache often static int gCounter; if ((++gCounter % 10) == 0) return false; @@ -300,17 +287,14 @@ bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { int bytesPerPixel = GrMaskFormatBytesPerPixel(fMaskFormat); GrPlot* plot; -#if SK_DISTANCEFIELD_FONTS if (fUseDistanceField) { - SkASSERT(1 == bytesPerPixel); - // we've already expanded the glyph dimensions to match the final size // but must shrink back down to get the packed glyph data int dfWidth = glyph->width(); int dfHeight = glyph->height(); - int width = dfWidth - 2*DISTANCE_FIELD_PAD; - int height = dfHeight - 2*DISTANCE_FIELD_PAD; - size_t stride = width*bytesPerPixel; + int width = dfWidth - 2*DISTANCE_FIELD_RANGE; + int height = dfHeight - 2*DISTANCE_FIELD_RANGE; + int stride = width*bytesPerPixel; size_t size = width * height * bytesPerPixel; SkAutoSMalloc<1024> storage(size); @@ -322,70 +306,27 @@ bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { size_t dfSize = dfWidth * dfHeight * bytesPerPixel; SkAutoSMalloc<1024> dfStorage(dfSize); - // copy glyph into distance field storage - sk_bzero(dfStorage.get(), dfSize); + if (1 == bytesPerPixel) { + (void) SkGenerateDistanceFieldFromImage((unsigned char*)dfStorage.get(), + (unsigned char*)storage.get(), + width, height, DISTANCE_FIELD_RANGE); + } else { + // TODO: Fix color emoji + // for now, copy glyph into distance field storage + // this is not correct, but it won't crash + sk_bzero(dfStorage.get(), dfSize); + unsigned char* ptr = (unsigned char*) storage.get(); + unsigned char* dfPtr = (unsigned char*) dfStorage.get(); + size_t dfStride = dfWidth*bytesPerPixel; + dfPtr += DISTANCE_FIELD_RANGE*dfStride; + dfPtr += DISTANCE_FIELD_RANGE*bytesPerPixel; - unsigned char* ptr = (unsigned char*) storage.get(); - unsigned char* dfPtr = (unsigned char*) dfStorage.get(); - size_t dfStride = dfWidth*bytesPerPixel; - dfPtr += DISTANCE_FIELD_PAD*dfStride; - dfPtr += DISTANCE_FIELD_PAD*bytesPerPixel; + for (int i = 0; i < height; ++i) { + memcpy(dfPtr, ptr, stride); - for (int i = 0; i < height; ++i) { - memcpy(dfPtr, ptr, stride); - - dfPtr += dfStride; - ptr += stride; - } - - // generate distance field data - SkAutoSMalloc<1024> distXStorage(dfWidth*dfHeight*sizeof(short)); - SkAutoSMalloc<1024> distYStorage(dfWidth*dfHeight*sizeof(short)); - SkAutoSMalloc<1024> outerDistStorage(dfWidth*dfHeight*sizeof(double)); - SkAutoSMalloc<1024> innerDistStorage(dfWidth*dfHeight*sizeof(double)); - SkAutoSMalloc<1024> gxStorage(dfWidth*dfHeight*sizeof(double)); - SkAutoSMalloc<1024> gyStorage(dfWidth*dfHeight*sizeof(double)); - - short* distX = (short*) distXStorage.get(); - short* distY = (short*) distYStorage.get(); - double* outerDist = (double*) outerDistStorage.get(); - double* innerDist = (double*) innerDistStorage.get(); - double* gx = (double*) gxStorage.get(); - double* gy = (double*) gyStorage.get(); - - dfPtr = (unsigned char*) dfStorage.get(); - EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy); - EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, outerDist); - - for (int i = 0; i < dfWidth*dfHeight; ++i) { - *dfPtr = 255 - *dfPtr; - dfPtr++; - } - dfPtr = (unsigned char*) dfStorage.get(); - sk_bzero(gx, sizeof(double)*dfWidth*dfHeight); - sk_bzero(gy, sizeof(double)*dfWidth*dfHeight); - EDTAA::computegradient(dfPtr, dfWidth, dfHeight, gx, gy); - EDTAA::edtaa3(dfPtr, gx, gy, dfWidth, dfHeight, distX, distY, innerDist); - - for (int i = 0; i < dfWidth*dfHeight; ++i) { - unsigned char val; - double outerval = outerDist[i]; - if (outerval < 0.0) { - outerval = 0.0; + dfPtr += dfStride; + ptr += stride; } - double innerval = innerDist[i]; - if (innerval < 0.0) { - innerval = 0.0; - } - double dist = outerval - innerval; - if (dist <= -DISTANCE_FIELD_RANGE) { - val = 255; - } else if (dist > DISTANCE_FIELD_RANGE) { - val = 0; - } else { - val = (unsigned char)((DISTANCE_FIELD_RANGE-dist)*128.0/DISTANCE_FIELD_RANGE); - } - *dfPtr++ = val; } // copy to atlas @@ -393,7 +334,6 @@ bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { &glyph->fAtlasLocation); } else { -#endif size_t size = glyph->fBounds.area() * bytesPerPixel; SkAutoSMalloc<1024> storage(size); if (!scaler->getPackedGlyphImage(glyph->fPackedID, glyph->width(), @@ -406,9 +346,7 @@ bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) { plot = fAtlasMgr->addToAtlas(&fAtlas, glyph->width(), glyph->height(), storage.get(), &glyph->fAtlasLocation); -#if SK_DISTANCEFIELD_FONTS } -#endif if (NULL == plot) { return false; diff --git a/gfx/skia/trunk/src/gpu/GrTextStrike.h b/gfx/skia/trunk/src/gpu/GrTextStrike.h index c5a3f656251b..8036ec323a98 100644 --- a/gfx/skia/trunk/src/gpu/GrTextStrike.h +++ b/gfx/skia/trunk/src/gpu/GrTextStrike.h @@ -37,7 +37,9 @@ public: GrMaskFormat getMaskFormat() const { return fMaskFormat; } inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*); - bool getGlyphAtlas(GrGlyph*, GrFontScaler*); + bool addGlyphToAtlas(GrGlyph*, GrFontScaler*); + + SkISize getAtlasSize() const { return fAtlas.getSize(); } // testing int countGlyphs() const { return fCache.getArray().count(); } @@ -45,11 +47,11 @@ public: return fCache.getArray()[index]; } - // returns true if a plot was removed - bool removeUnusedPlots(); + // remove any references to this plot + void removePlot(const GrPlot* plot); public: - // for LRU + // for easy removal from list GrTextStrike* fPrev; GrTextStrike* fNext; @@ -62,9 +64,7 @@ private: GrFontCache* fFontCache; GrAtlasMgr* fAtlasMgr; GrMaskFormat fMaskFormat; -#if SK_DISTANCEFIELD_FONTS bool fUseDistanceField; -#endif GrAtlas fAtlas; @@ -78,18 +78,12 @@ public: GrFontCache(GrGpu*); ~GrFontCache(); -#if SK_DISTANCEFIELD_FONTS inline GrTextStrike* getStrike(GrFontScaler*, bool useDistanceField); -#else - inline GrTextStrike* getStrike(GrFontScaler*); -#endif void freeAll(); - void purgeExceptFor(GrTextStrike*); - - // remove an unused plot and its strike (if necessary) - void freePlotExceptFor(GrTextStrike*); + // make an unused plot available + bool freeUnusedPlot(GrTextStrike* preserveStrike); // testing int countStrikes() const { return fCache.getArray().count(); } diff --git a/gfx/skia/trunk/src/gpu/GrTextStrike_impl.h b/gfx/skia/trunk/src/gpu/GrTextStrike_impl.h index 0691eaa6432b..bc4f8dd81718 100644 --- a/gfx/skia/trunk/src/gpu/GrTextStrike_impl.h +++ b/gfx/skia/trunk/src/gpu/GrTextStrike_impl.h @@ -48,11 +48,7 @@ void GrFontCache::detachStrikeFromList(GrTextStrike* strike) { } } -#if SK_DISTANCEFIELD_FONTS GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler, bool useDistanceField) { -#else -GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler) { -#endif this->validate(); const Key key(scaler->getKey()); @@ -69,9 +65,7 @@ GrTextStrike* GrFontCache::getStrike(GrFontScaler* scaler) { strike->fPrev = NULL; fHead = strike; } -#if SK_DISTANCEFIELD_FONTS strike->fUseDistanceField = useDistanceField; -#endif this->validate(); return strike; } diff --git a/gfx/skia/trunk/src/gpu/SkGpuDevice.cpp b/gfx/skia/trunk/src/gpu/SkGpuDevice.cpp index a3af3c3d08ca..a86170b75e1a 100644 --- a/gfx/skia/trunk/src/gpu/SkGpuDevice.cpp +++ b/gfx/skia/trunk/src/gpu/SkGpuDevice.cpp @@ -13,18 +13,19 @@ #include "GrContext.h" #include "GrBitmapTextContext.h" -#if SK_DISTANCEFIELD_FONTS #include "GrDistanceFieldTextContext.h" -#endif #include "SkGrTexturePixelRef.h" +#include "SkBounder.h" #include "SkColorFilter.h" #include "SkDeviceImageFilterProxy.h" #include "SkDrawProcs.h" #include "SkGlyphCache.h" #include "SkImageFilter.h" +#include "SkMaskFilter.h" #include "SkPathEffect.h" +#include "SkPicture.h" #include "SkRRect.h" #include "SkStroke.h" #include "SkSurface.h" @@ -157,20 +158,6 @@ static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) { return bitmap; } -/* - * Calling SkBitmapDevice with individual params asks it to allocate pixel memory. - * We never want that, so we always need to call it with a bitmap argument - * (which says take my allocate (or lack thereof)). - * - * This is a REALLY good reason to finish the clean-up of SkBaseDevice, and have - * SkGpuDevice inherit from that instead of SkBitmapDevice. - */ -static SkBitmap make_bitmap(SkBitmap::Config config, int width, int height, bool isOpaque) { - SkBitmap bm; - bm.setConfig(config, width, height, isOpaque); - return bm; -} - SkGpuDevice* SkGpuDevice::Create(GrSurface* surface) { SkASSERT(NULL != surface); if (NULL == surface->asRenderTarget() || NULL == surface->getContext()) { @@ -201,13 +188,8 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context, fContext = context; fContext->ref(); -#if SK_DISTANCEFIELD_FONTS fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyProperties)); fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties)); -#else - fMainTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties)); - fFallbackTextContext = NULL; -#endif fRenderTarget = NULL; fNeedClear = false; @@ -232,25 +214,62 @@ void SkGpuDevice::initFromRenderTarget(GrContext* context, this->setPixelRef(pr)->unref(); } +SkGpuDevice* SkGpuDevice::Create(GrContext* context, const SkImageInfo& origInfo, + int sampleCount) { + if (kUnknown_SkColorType == origInfo.colorType() || + origInfo.width() < 0 || origInfo.height() < 0) { + return NULL; + } + + SkImageInfo info = origInfo; + // TODO: perhas we can loosen this check now that colortype is more detailed + // e.g. can we support both RGBA and BGRA here? + if (kRGB_565_SkColorType == info.colorType()) { + info.fAlphaType = kOpaque_SkAlphaType; // force this setting + } else { + info.fColorType = kPMColor_SkColorType; + if (kOpaque_SkAlphaType != info.alphaType()) { + info.fAlphaType = kPremul_SkAlphaType; // force this setting + } + } + + GrTextureDesc desc; + desc.fFlags = kRenderTarget_GrTextureFlagBit; + desc.fWidth = info.width(); + desc.fHeight = info.height(); + desc.fConfig = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType()); + desc.fSampleCnt = sampleCount; + + SkAutoTUnref texture(context->createUncachedTexture(desc, NULL, 0)); + if (!texture.get()) { + return NULL; + } + + return SkNEW_ARGS(SkGpuDevice, (context, texture.get())); +} + +#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG +static SkBitmap make_bitmap(SkBitmap::Config config, int width, int height) { + SkBitmap bm; + bm.setConfig(SkImageInfo::Make(width, height, + SkBitmapConfigToColorType(config), + kPremul_SkAlphaType)); + return bm; +} SkGpuDevice::SkGpuDevice(GrContext* context, SkBitmap::Config config, int width, int height, int sampleCount) - : SkBitmapDevice(make_bitmap(config, width, height, false /*isOpaque*/)) + : SkBitmapDevice(make_bitmap(config, width, height)) { fDrawProcs = NULL; fContext = context; fContext->ref(); -#if SK_DISTANCEFIELD_FONTS fMainTextContext = SkNEW_ARGS(GrDistanceFieldTextContext, (fContext, fLeakyProperties)); fFallbackTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties)); -#else - fMainTextContext = SkNEW_ARGS(GrBitmapTextContext, (fContext, fLeakyProperties)); - fFallbackTextContext = NULL; -#endif fRenderTarget = NULL; fNeedClear = false; @@ -291,6 +310,7 @@ SkGpuDevice::SkGpuDevice(GrContext* context, SkASSERT(false); } } +#endif SkGpuDevice::~SkGpuDevice() { if (fDrawProcs) { @@ -374,6 +394,7 @@ bool SkGpuDevice::onReadPixels(const SkBitmap& bitmap, flags); } +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { SkAutoLockPixels alp(bitmap); @@ -393,6 +414,26 @@ void SkGpuDevice::writePixels(const SkBitmap& bitmap, int x, int y, fRenderTarget->writePixels(x, y, bitmap.width(), bitmap.height(), config, bitmap.getPixels(), bitmap.rowBytes(), flags); } +#endif + +bool SkGpuDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, + int x, int y) { + // TODO: teach fRenderTarget to take ImageInfo directly to specify the src pixels + GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType()); + if (kUnknown_GrPixelConfig == config) { + return false; + } + uint32_t flags = 0; + if (kUnpremul_SkAlphaType == info.alphaType()) { + flags = GrContext::kUnpremul_PixelOpsFlag; + } + fRenderTarget->writePixels(x, y, info.width(), info.height(), config, pixels, rowBytes, flags); + + // need to bump our genID for compatibility with clients that "know" we have a bitmap + this->onAccessBitmap().notifyPixelsChanged(); + + return true; +} void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) { INHERITED::onAttachToCanvas(canvas); @@ -689,6 +730,44 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, CHECK_FOR_ANNOTATION(paint); CHECK_SHOULD_DRAW(draw, false); + GrPaint grPaint; + if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { + return; + } + + SkStrokeRec stroke(paint); + if (paint.getMaskFilter()) { + // try to hit the fast path for drawing filtered round rects + + SkRRect devRRect; + if (rect.transform(fContext->getMatrix(), &devRRect)) { + if (devRRect.allCornersCircular()) { + SkRect maskRect; + if (paint.getMaskFilter()->canFilterMaskGPU(devRRect.rect(), + draw.fClip->getBounds(), + fContext->getMatrix(), + &maskRect)) { + SkIRect finalIRect; + maskRect.roundOut(&finalIRect); + if (draw.fClip->quickReject(finalIRect)) { + // clipped out + return; + } + if (NULL != draw.fBounder && !draw.fBounder->doIRect(finalIRect)) { + // nothing to draw + return; + } + if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext, &grPaint, + stroke, devRRect)) { + return; + } + } + + } + } + + } + bool usePath = !rect.isSimple(); // another two reasons we might need to call drawPath... if (paint.getMaskFilter() || paint.getPathEffect()) { @@ -706,16 +785,10 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rect, return; } - GrPaint grPaint; - if (!skPaint2GrPaintShader(this, paint, true, &grPaint)) { - return; - } - - SkStrokeRec stroke(paint); fContext->drawRRect(grPaint, rect, stroke); } -/////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) { @@ -961,7 +1034,7 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath, } if (paint.getMaskFilter()->directFilterMaskGPU(fContext, &grPaint, - SkStrokeRec(paint), *devPathPtr)) { + stroke, *devPathPtr)) { // the mask filter was able to draw itself directly, so there's nothing // left to do. return; @@ -1516,8 +1589,8 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, static bool filter_texture(SkBaseDevice* device, GrContext* context, GrTexture* texture, const SkImageFilter* filter, - int w, int h, const SkMatrix& ctm, SkBitmap* result, - SkIPoint* offset) { + int w, int h, const SkImageFilter::Context& ctx, + SkBitmap* result, SkIPoint* offset) { SkASSERT(filter); SkDeviceImageFilterProxy proxy(device); @@ -1525,7 +1598,7 @@ static bool filter_texture(SkBaseDevice* device, GrContext* context, // Save the render target and set it to NULL, so we don't accidentally draw to it in the // filter. Also set the clip wide open and the matrix to identity. GrContext::AutoWideOpenIdentityDraw awo(context, NULL); - return filter->filterImageGPU(&proxy, wrap_texture(texture), ctm, result, offset); + return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result, offset); } else { return false; } @@ -1556,7 +1629,9 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap, SkIPoint offset = SkIPoint::Make(0, 0); SkMatrix matrix(*draw.fMatrix); matrix.postTranslate(SkIntToScalar(-left), SkIntToScalar(-top)); - if (filter_texture(this, fContext, texture, filter, w, h, matrix, &filteredBitmap, + SkIRect clipBounds = SkIRect::MakeWH(bitmap.width(), bitmap.height()); + SkImageFilter::Context ctx(matrix, clipBounds); + if (filter_texture(this, fContext, texture, filter, w, h, ctx, &filteredBitmap, &offset)) { texture = (GrTexture*) filteredBitmap.getTexture(); w = filteredBitmap.width(); @@ -1662,7 +1737,9 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device, SkIPoint offset = SkIPoint::Make(0, 0); SkMatrix matrix(*draw.fMatrix); matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); - if (filter_texture(this, fContext, devTex, filter, w, h, matrix, &filteredBitmap, + SkIRect clipBounds = SkIRect::MakeWH(devTex->width(), devTex->height()); + SkImageFilter::Context ctx(matrix, clipBounds); + if (filter_texture(this, fContext, devTex, filter, w, h, ctx, &filteredBitmap, &offset)) { devTex = filteredBitmap.getTexture(); w = filteredBitmap.width(); @@ -1699,7 +1776,7 @@ bool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) { } bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src, - const SkMatrix& ctm, + const SkImageFilter::Context& ctx, SkBitmap* result, SkIPoint* offset) { // want explicitly our impl, so guard against a subclass of us overriding it if (!this->SkGpuDevice::canHandleImageFilter(filter)) { @@ -1716,8 +1793,8 @@ bool SkGpuDevice::filterImage(const SkImageFilter* filter, const SkBitmap& src, // must be pushed upstack. SkAutoCachedTexture act(this, src, NULL, &texture); - return filter_texture(this, fContext, texture, filter, src.width(), src.height(), ctm, result, - offset); + return filter_texture(this, fContext, texture, filter, src.width(), src.height(), ctx, + result, offset); } /////////////////////////////////////////////////////////////////////////////// @@ -1881,20 +1958,17 @@ void SkGpuDevice::flush() { /////////////////////////////////////////////////////////////////////////////// -SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) { +SkBaseDevice* SkGpuDevice::onCreateDevice(const SkImageInfo& info, Usage usage) { GrTextureDesc desc; desc.fConfig = fRenderTarget->config(); desc.fFlags = kRenderTarget_GrTextureFlagBit; - desc.fWidth = width; - desc.fHeight = height; + desc.fWidth = info.width(); + desc.fHeight = info.height(); desc.fSampleCnt = fRenderTarget->numSamples(); SkAutoTUnref texture; // Skia's convention is to only clear a device if it is non-opaque. - bool needClear = !isOpaque; + bool needClear = !info.isOpaque(); #if CACHE_COMPATIBLE_DEVICE_TEXTURES // layers are never draw in repeat modes, so we can request an approx @@ -1909,7 +1983,8 @@ SkBaseDevice* SkGpuDevice::onCreateCompatibleDevice(SkBitmap::Config config, if (NULL != texture.get()) { return SkNEW_ARGS(SkGpuDevice,(fContext, texture, needClear)); } else { - GrPrintf("---- failed to create compatible device texture [%d %d]\n", width, height); + GrPrintf("---- failed to create compatible device texture [%d %d]\n", + info.width(), info.height()); return NULL; } } @@ -1924,8 +1999,49 @@ SkGpuDevice::SkGpuDevice(GrContext* context, : SkBitmapDevice(make_bitmap(context, texture->asRenderTarget())) { SkASSERT(texture && texture->asRenderTarget()); - // This constructor is called from onCreateCompatibleDevice. It has locked the RT in the texture + // This constructor is called from onCreateDevice. It has locked the RT in the texture // cache. We pass true for the third argument so that it will get unlocked. this->initFromRenderTarget(context, texture->asRenderTarget(), true); fNeedClear = needClear; } + +class GPUAccelData : public SkPicture::AccelData { +public: + GPUAccelData(Key key) : INHERITED(key) { } + +protected: + +private: + typedef SkPicture::AccelData INHERITED; +}; + +// In the future this may not be a static method if we need to incorporate the +// clip and matrix state into the key +SkPicture::AccelData::Key SkGpuDevice::ComputeAccelDataKey() { + static const SkPicture::AccelData::Key gGPUID = SkPicture::AccelData::GenerateDomain(); + + return gGPUID; +} + +void SkGpuDevice::EXPERIMENTAL_optimize(SkPicture* picture) { + SkPicture::AccelData::Key key = ComputeAccelDataKey(); + + GPUAccelData* data = SkNEW_ARGS(GPUAccelData, (key)); + + picture->EXPERIMENTAL_addAccelData(data); +} + +bool SkGpuDevice::EXPERIMENTAL_drawPicture(const SkPicture& picture) { + SkPicture::AccelData::Key key = ComputeAccelDataKey(); + + const SkPicture::AccelData* data = picture.EXPERIMENTAL_getAccelData(key); + if (NULL == data) { + return false; + } + +#if 0 + const GPUAccelData *gpuData = static_cast(data); +#endif + + return false; +} diff --git a/gfx/skia/trunk/src/gpu/SkGr.cpp b/gfx/skia/trunk/src/gpu/SkGr.cpp index fa9fa713269f..94e4c8c35dd4 100644 --- a/gfx/skia/trunk/src/gpu/SkGr.cpp +++ b/gfx/skia/trunk/src/gpu/SkGr.cpp @@ -155,7 +155,7 @@ static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx, return result; } } else { - origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config); + origBitmap.copyTo(&tmpBitmap, kPMColor_SkColorType); // now bitmap points to our temp, which has been promoted to 32bits bitmap = &tmpBitmap; desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap->config()); @@ -260,6 +260,29 @@ GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config config) { } } +// alphatype is ignore for now, but if GrPixelConfig is expanded to encompass +// alpha info, that will be considered. +GrPixelConfig SkImageInfo2GrPixelConfig(SkColorType ct, SkAlphaType) { + switch (ct) { + case kUnknown_SkColorType: + return kUnknown_GrPixelConfig; + case kAlpha_8_SkColorType: + return kAlpha_8_GrPixelConfig; + case kRGB_565_SkColorType: + return kRGB_565_GrPixelConfig; + case kARGB_4444_SkColorType: + return kRGBA_4444_GrPixelConfig; + case kRGBA_8888_SkColorType: + return kRGBA_8888_GrPixelConfig; + case kBGRA_8888_SkColorType: + return kBGRA_8888_GrPixelConfig; + case kIndex_8_SkColorType: + return kIndex_8_GrPixelConfig; + } + SkASSERT(0); // shouldn't get here + return kUnknown_GrPixelConfig; +} + bool GrPixelConfig2ColorType(GrPixelConfig config, SkColorType* ctOut) { SkColorType ct; switch (config) { diff --git a/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.cpp b/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.cpp index c9a2bea0522f..78633e59a874 100644 --- a/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.cpp +++ b/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.cpp @@ -29,7 +29,7 @@ public: virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} private: - GrBezierEdgeType fEdgeType; + GrEffectEdgeType fEdgeType; typedef GrGLVertexEffect INHERITED; }; @@ -59,7 +59,7 @@ void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder, builder->fsCodeAppend("\t\tfloat edgeAlpha;\n"); switch (fEdgeType) { - case kHairAA_GrBezierEdgeType: { + case kHairlineAA_GrEffectEdgeType: { SkAssertResult(builder->enableFeature( GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName); @@ -81,7 +81,7 @@ void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder, // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n"); break; } - case kFillAA_GrBezierEdgeType: { + case kFillAA_GrEffectEdgeType: { SkAssertResult(builder->enableFeature( GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName); @@ -102,12 +102,14 @@ void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder, // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n"); break; } - case kFillNoAA_GrBezierEdgeType: { + case kFillBW_GrEffectEdgeType: { builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName, fsName, fsName); builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n"); break; } + default: + GrCrash("Shouldn't get here"); } builder->fsCodeAppendf("\t%s = %s;\n", outputColor, @@ -127,7 +129,7 @@ const GrBackendEffectFactory& GrConicEffect::getFactory() const { return GrTBackendEffectFactory::getInstance(); } -GrConicEffect::GrConicEffect(GrBezierEdgeType edgeType) : GrVertexEffect() { +GrConicEffect::GrConicEffect(GrEffectEdgeType edgeType) : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); fEdgeType = edgeType; } @@ -145,8 +147,13 @@ GrEffectRef* GrConicEffect::TestCreate(SkRandom* random, GrContext*, const GrDrawTargetCaps& caps, GrTexture*[]) { - const GrBezierEdgeType edgeType = static_cast(random->nextULessThan(3)); - return GrConicEffect::Create(edgeType, caps); + GrEffectRef* effect; + do { + GrEffectEdgeType edgeType = static_cast( + random->nextULessThan(kGrEffectEdgeTypeCnt)); + effect = GrConicEffect::Create(edgeType, caps); + } while (NULL == effect); + return effect; } ////////////////////////////////////////////////////////////////////////////// @@ -170,7 +177,7 @@ public: virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} private: - GrBezierEdgeType fEdgeType; + GrEffectEdgeType fEdgeType; typedef GrGLVertexEffect INHERITED; }; @@ -198,7 +205,7 @@ void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder, builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName); switch (fEdgeType) { - case kHairAA_GrBezierEdgeType: { + case kHairlineAA_GrEffectEdgeType: { SkAssertResult(builder->enableFeature( GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); @@ -214,7 +221,7 @@ void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder, // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n"); break; } - case kFillAA_GrBezierEdgeType: { + case kFillAA_GrEffectEdgeType: { SkAssertResult(builder->enableFeature( GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); @@ -230,12 +237,14 @@ void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder, // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n"); break; } - case kFillNoAA_GrBezierEdgeType: { + case kFillBW_GrEffectEdgeType: { builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, fsName); builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n"); break; } + default: + GrCrash("Shouldn't get here"); } builder->fsCodeAppendf("\t%s = %s;\n", outputColor, @@ -258,7 +267,7 @@ const GrBackendEffectFactory& GrQuadEffect::getFactory() const { return GrTBackendEffectFactory::getInstance(); } -GrQuadEffect::GrQuadEffect(GrBezierEdgeType edgeType) : GrVertexEffect() { +GrQuadEffect::GrQuadEffect(GrEffectEdgeType edgeType) : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); fEdgeType = edgeType; } @@ -276,8 +285,13 @@ GrEffectRef* GrQuadEffect::TestCreate(SkRandom* random, GrContext*, const GrDrawTargetCaps& caps, GrTexture*[]) { - const GrBezierEdgeType edgeType = static_cast(random->nextULessThan(3)); - return GrQuadEffect::Create(edgeType, caps); + GrEffectRef* effect; + do { + GrEffectEdgeType edgeType = static_cast( + random->nextULessThan(kGrEffectEdgeTypeCnt)); + effect = GrQuadEffect::Create(edgeType, caps); + } while (NULL == effect); + return effect; } ////////////////////////////////////////////////////////////////////////////// @@ -301,7 +315,7 @@ public: virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} private: - GrBezierEdgeType fEdgeType; + GrEffectEdgeType fEdgeType; typedef GrGLVertexEffect INHERITED; }; @@ -331,7 +345,7 @@ void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder, builder->fsCodeAppend("\t\tfloat edgeAlpha;\n"); switch (fEdgeType) { - case kHairAA_GrBezierEdgeType: { + case kHairlineAA_GrEffectEdgeType: { SkAssertResult(builder->enableFeature( GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName); @@ -353,7 +367,7 @@ void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder, // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n"); break; } - case kFillAA_GrBezierEdgeType: { + case kFillAA_GrEffectEdgeType: { SkAssertResult(builder->enableFeature( GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName); @@ -374,12 +388,14 @@ void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder, // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n"); break; } - case kFillNoAA_GrBezierEdgeType: { + case kFillBW_GrEffectEdgeType: { builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x*%s.x - %s.y*%s.z;\n", fsName, fsName, fsName, fsName, fsName); builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n"); break; } + default: + GrCrash("Shouldn't get here"); } builder->fsCodeAppendf("\t%s = %s;\n", outputColor, @@ -399,7 +415,7 @@ const GrBackendEffectFactory& GrCubicEffect::getFactory() const { return GrTBackendEffectFactory::getInstance(); } -GrCubicEffect::GrCubicEffect(GrBezierEdgeType edgeType) : GrVertexEffect() { +GrCubicEffect::GrCubicEffect(GrEffectEdgeType edgeType) : GrVertexEffect() { this->addVertexAttrib(kVec4f_GrSLType); fEdgeType = edgeType; } @@ -417,6 +433,11 @@ GrEffectRef* GrCubicEffect::TestCreate(SkRandom* random, GrContext*, const GrDrawTargetCaps& caps, GrTexture*[]) { - const GrBezierEdgeType edgeType = static_cast(random->nextULessThan(3)); - return GrCubicEffect::Create(edgeType, caps); + GrEffectRef* effect; + do { + GrEffectEdgeType edgeType = static_cast( + random->nextULessThan(kGrEffectEdgeTypeCnt)); + effect = GrCubicEffect::Create(edgeType, caps); + } while (NULL == effect); + return effect; } diff --git a/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.h b/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.h index 5de7b80b7506..e2fc592bdc09 100644 --- a/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.h +++ b/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.h @@ -11,20 +11,7 @@ #include "GrDrawTargetCaps.h" #include "GrEffect.h" #include "GrVertexEffect.h" - -enum GrBezierEdgeType { - kFillAA_GrBezierEdgeType, - kHairAA_GrBezierEdgeType, - kFillNoAA_GrBezierEdgeType, -}; - -static inline bool GrBezierEdgeTypeIsFill(const GrBezierEdgeType edgeType) { - return (kHairAA_GrBezierEdgeType != edgeType); -} - -static inline bool GrBezierEdgeTypeIsAA(const GrBezierEdgeType edgeType) { - return (kFillNoAA_GrBezierEdgeType != edgeType); -} +#include "GrTypesPriv.h" /** * Shader is based off of Loop-Blinn Quadratic GPU Rendering @@ -70,25 +57,28 @@ class GrGLConicEffect; class GrConicEffect : public GrVertexEffect { public: - static GrEffectRef* Create(const GrBezierEdgeType edgeType, const GrDrawTargetCaps& caps) { - GR_CREATE_STATIC_EFFECT(gConicFillAA, GrConicEffect, (kFillAA_GrBezierEdgeType)); - GR_CREATE_STATIC_EFFECT(gConicHairAA, GrConicEffect, (kHairAA_GrBezierEdgeType)); - GR_CREATE_STATIC_EFFECT(gConicFillNoAA, GrConicEffect, (kFillNoAA_GrBezierEdgeType)); - if (kFillAA_GrBezierEdgeType == edgeType) { - if (!caps.shaderDerivativeSupport()) { + static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) { + GR_CREATE_STATIC_EFFECT(gConicFillAA, GrConicEffect, (kFillAA_GrEffectEdgeType)); + GR_CREATE_STATIC_EFFECT(gConicHairAA, GrConicEffect, (kHairlineAA_GrEffectEdgeType)); + GR_CREATE_STATIC_EFFECT(gConicFillBW, GrConicEffect, (kFillBW_GrEffectEdgeType)); + switch (edgeType) { + case kFillAA_GrEffectEdgeType: + if (!caps.shaderDerivativeSupport()) { + return NULL; + } + gConicFillAA->ref(); + return gConicFillAA; + case kHairlineAA_GrEffectEdgeType: + if (!caps.shaderDerivativeSupport()) { + return NULL; + } + gConicHairAA->ref(); + return gConicHairAA; + case kFillBW_GrEffectEdgeType: + gConicFillBW->ref(); + return gConicFillBW; + default: return NULL; - } - gConicFillAA->ref(); - return gConicFillAA; - } else if (kHairAA_GrBezierEdgeType == edgeType) { - if (!caps.shaderDerivativeSupport()) { - return NULL; - } - gConicHairAA->ref(); - return gConicHairAA; - } else { - gConicFillNoAA->ref(); - return gConicFillNoAA; } } @@ -96,9 +86,9 @@ public: static const char* Name() { return "Conic"; } - inline bool isAntiAliased() const { return GrBezierEdgeTypeIsAA(fEdgeType); } - inline bool isFilled() const { return GrBezierEdgeTypeIsFill(fEdgeType); } - inline GrBezierEdgeType getEdgeType() const { return fEdgeType; } + inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); } + inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); } + inline GrEffectEdgeType getEdgeType() const { return fEdgeType; } typedef GrGLConicEffect GLEffect; @@ -110,11 +100,11 @@ public: virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; private: - GrConicEffect(GrBezierEdgeType); + GrConicEffect(GrEffectEdgeType); virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; - GrBezierEdgeType fEdgeType; + GrEffectEdgeType fEdgeType; GR_DECLARE_EFFECT_TEST; @@ -134,25 +124,28 @@ class GrGLQuadEffect; class GrQuadEffect : public GrVertexEffect { public: - static GrEffectRef* Create(const GrBezierEdgeType edgeType, const GrDrawTargetCaps& caps) { - GR_CREATE_STATIC_EFFECT(gQuadFillAA, GrQuadEffect, (kFillAA_GrBezierEdgeType)); - GR_CREATE_STATIC_EFFECT(gQuadHairAA, GrQuadEffect, (kHairAA_GrBezierEdgeType)); - GR_CREATE_STATIC_EFFECT(gQuadFillNoAA, GrQuadEffect, (kFillNoAA_GrBezierEdgeType)); - if (kFillAA_GrBezierEdgeType == edgeType) { - if (!caps.shaderDerivativeSupport()) { + static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) { + GR_CREATE_STATIC_EFFECT(gQuadFillAA, GrQuadEffect, (kFillAA_GrEffectEdgeType)); + GR_CREATE_STATIC_EFFECT(gQuadHairAA, GrQuadEffect, (kHairlineAA_GrEffectEdgeType)); + GR_CREATE_STATIC_EFFECT(gQuadFillBW, GrQuadEffect, (kFillBW_GrEffectEdgeType)); + switch (edgeType) { + case kFillAA_GrEffectEdgeType: + if (!caps.shaderDerivativeSupport()) { + return NULL; + } + gQuadFillAA->ref(); + return gQuadFillAA; + case kHairlineAA_GrEffectEdgeType: + if (!caps.shaderDerivativeSupport()) { + return NULL; + } + gQuadHairAA->ref(); + return gQuadHairAA; + case kFillBW_GrEffectEdgeType: + gQuadFillBW->ref(); + return gQuadFillBW; + default: return NULL; - } - gQuadFillAA->ref(); - return gQuadFillAA; - } else if (kHairAA_GrBezierEdgeType == edgeType) { - if (!caps.shaderDerivativeSupport()) { - return NULL; - } - gQuadHairAA->ref(); - return gQuadHairAA; - } else { - gQuadFillNoAA->ref(); - return gQuadFillNoAA; } } @@ -160,9 +153,9 @@ public: static const char* Name() { return "Quad"; } - inline bool isAntiAliased() const { return GrBezierEdgeTypeIsAA(fEdgeType); } - inline bool isFilled() const { return GrBezierEdgeTypeIsFill(fEdgeType); } - inline GrBezierEdgeType getEdgeType() const { return fEdgeType; } + inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); } + inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); } + inline GrEffectEdgeType getEdgeType() const { return fEdgeType; } typedef GrGLQuadEffect GLEffect; @@ -174,11 +167,11 @@ public: virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; private: - GrQuadEffect(GrBezierEdgeType); + GrQuadEffect(GrEffectEdgeType); virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; - GrBezierEdgeType fEdgeType; + GrEffectEdgeType fEdgeType; GR_DECLARE_EFFECT_TEST; @@ -200,25 +193,28 @@ class GrGLCubicEffect; class GrCubicEffect : public GrVertexEffect { public: - static GrEffectRef* Create(const GrBezierEdgeType edgeType, const GrDrawTargetCaps& caps) { - GR_CREATE_STATIC_EFFECT(gCubicFillAA, GrCubicEffect, (kFillAA_GrBezierEdgeType)); - GR_CREATE_STATIC_EFFECT(gCubicHairAA, GrCubicEffect, (kHairAA_GrBezierEdgeType)); - GR_CREATE_STATIC_EFFECT(gCubicFillNoAA, GrCubicEffect, (kFillNoAA_GrBezierEdgeType)); - if (kFillAA_GrBezierEdgeType == edgeType) { - if (!caps.shaderDerivativeSupport()) { + static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) { + GR_CREATE_STATIC_EFFECT(gCubicFillAA, GrCubicEffect, (kFillAA_GrEffectEdgeType)); + GR_CREATE_STATIC_EFFECT(gCubicHairAA, GrCubicEffect, (kHairlineAA_GrEffectEdgeType)); + GR_CREATE_STATIC_EFFECT(gCubicFillBW, GrCubicEffect, (kFillBW_GrEffectEdgeType)); + switch (edgeType) { + case kFillAA_GrEffectEdgeType: + if (!caps.shaderDerivativeSupport()) { + return NULL; + } + gCubicFillAA->ref(); + return gCubicFillAA; + case kHairlineAA_GrEffectEdgeType: + if (!caps.shaderDerivativeSupport()) { + return NULL; + } + gCubicHairAA->ref(); + return gCubicHairAA; + case kFillBW_GrEffectEdgeType: + gCubicFillBW->ref(); + return gCubicFillBW; + default: return NULL; - } - gCubicFillAA->ref(); - return gCubicFillAA; - } else if (kHairAA_GrBezierEdgeType == edgeType) { - if (!caps.shaderDerivativeSupport()) { - return NULL; - } - gCubicHairAA->ref(); - return gCubicHairAA; - } else { - gCubicFillNoAA->ref(); - return gCubicFillNoAA; } } @@ -226,9 +222,9 @@ public: static const char* Name() { return "Cubic"; } - inline bool isAntiAliased() const { return GrBezierEdgeTypeIsAA(fEdgeType); } - inline bool isFilled() const { return GrBezierEdgeTypeIsFill(fEdgeType); } - inline GrBezierEdgeType getEdgeType() const { return fEdgeType; } + inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); } + inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); } + inline GrEffectEdgeType getEdgeType() const { return fEdgeType; } typedef GrGLCubicEffect GLEffect; @@ -240,11 +236,11 @@ public: virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; private: - GrCubicEffect(GrBezierEdgeType); + GrCubicEffect(GrEffectEdgeType); virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; - GrBezierEdgeType fEdgeType; + GrEffectEdgeType fEdgeType; GR_DECLARE_EFFECT_TEST; diff --git a/gfx/skia/trunk/src/gpu/effects/GrConvexPolyEffect.cpp b/gfx/skia/trunk/src/gpu/effects/GrConvexPolyEffect.cpp index eedc9c9b59f3..d24b45e10b58 100644 --- a/gfx/skia/trunk/src/gpu/effects/GrConvexPolyEffect.cpp +++ b/gfx/skia/trunk/src/gpu/effects/GrConvexPolyEffect.cpp @@ -9,7 +9,6 @@ #include "gl/GrGLEffect.h" #include "gl/GrGLSL.h" -#include "gl/GrGLVertexEffect.h" #include "GrTBackendEffectFactory.h" #include "SkPath.h" @@ -25,8 +24,8 @@ public: static const char* Name() { return "AARect"; } - static GrEffectRef* Create(const SkRect& rect) { - return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (rect)))); + static GrEffectRef* Create(GrEffectEdgeType edgeType, const SkRect& rect) { + return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (edgeType, rect)))); } virtual void getConstantColorComponents(GrColor* color, @@ -40,10 +39,12 @@ public: } } + GrEffectEdgeType getEdgeType() const { return fEdgeType; } + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; private: - AARectEffect(const SkRect& rect) : fRect(rect) { + AARectEffect(GrEffectEdgeType edgeType, const SkRect& rect) : fRect(rect), fEdgeType(edgeType) { this->setWillReadFragmentPosition(); } @@ -53,6 +54,8 @@ private: } SkRect fRect; + GrEffectEdgeType fEdgeType; + typedef GrEffect INHERITED; GR_DECLARE_EFFECT_TEST; @@ -69,7 +72,14 @@ GrEffectRef* AARectEffect::TestCreate(SkRandom* random, random->nextSScalar1(), random->nextSScalar1(), random->nextSScalar1()); - return AARectEffect::Create(rect); + GrEffectRef* effect; + do { + GrEffectEdgeType edgeType = static_cast(random->nextULessThan( + kGrEffectEdgeTypeCnt)); + + effect = AARectEffect::Create(edgeType, rect); + } while (NULL == effect); + return effect; } ////////////////////////////////////////////////////////////////////////////// @@ -86,7 +96,7 @@ public: const TransformedCoordsArray&, const TextureSamplerArray&) SK_OVERRIDE; - static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; } + static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; @@ -109,23 +119,37 @@ void GLAARectEffect::emitCode(GrGLShaderBuilder* builder, const char* inputColor, const TransformedCoordsArray&, const TextureSamplerArray& samplers) { + const AARectEffect& aare = drawEffect.castEffect(); const char *rectName; + // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), + // respectively. fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, kVec4f_GrSLType, "rect", &rectName); const char* fragmentPos = builder->fragmentPosition(); - // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), - // respectively. The amount of coverage removed in x and y by the edges is computed as a pair of - // negative numbers, xSub and ySub. - builder->fsCodeAppend("\t\tfloat xSub, ySub;\n"); - builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName); - builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos); - builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName); - builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos); - // Now compute coverage in x and y and multiply them to get the fraction of the pixel covered. - builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); + if (GrEffectEdgeTypeIsAA(aare.getEdgeType())) { + // The amount of coverage removed in x and y by the edges is computed as a pair of negative + // numbers, xSub and ySub. + builder->fsCodeAppend("\t\tfloat xSub, ySub;\n"); + builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName); + builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos); + builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName); + builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos); + // Now compute coverage in x and y and multiply them to get the fraction of the pixel + // covered. + builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); + } else { + builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n"); + builder->fsCodeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); + builder->fsCodeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); + builder->fsCodeAppendf("\t\talpha *= (%s.y - %s.y) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); + builder->fsCodeAppendf("\t\talpha *= (%s.w - %s.y) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); + } + if (GrEffectEdgeTypeIsInverseFill(aare.getEdgeType())) { + builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n"); + } builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); } @@ -140,6 +164,11 @@ void GLAARectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& } } +GrGLEffect::EffectKey GLAARectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { + const AARectEffect& aare = drawEffect.castEffect(); + return aare.getEdgeType(); +} + const GrBackendEffectFactory& AARectEffect::getFactory() const { return GrTBackendEffectFactory::getInstance(); } @@ -195,22 +224,22 @@ void GrGLConvexPolyEffect::emitCode(GrGLShaderBuilder* builder, for (int i = 0; i < cpe.getEdgeCount(); ++i) { builder->fsCodeAppendf("\t\tedge = dot(%s[%d], vec3(%s.x, %s.y, 1));\n", edgeArrayName, i, fragmentPos, fragmentPos); - switch (cpe.getEdgeType()) { - case GrConvexPolyEffect::kFillAA_EdgeType: - builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); - builder->fsCodeAppend("\t\talpha *= edge;\n"); - break; - case GrConvexPolyEffect::kFillNoAA_EdgeType: - builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); - builder->fsCodeAppend("\t\talpha *= edge;\n"); - break; + if (GrEffectEdgeTypeIsAA(cpe.getEdgeType())) { + builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); + } else { + builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); } + builder->fsCodeAppend("\t\talpha *= edge;\n"); } // Woe is me. See skbug.com/2149. if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) { builder->fsCodeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n"); } + + if (GrEffectEdgeTypeIsInverseFill(cpe.getEdgeType())) { + builder->fsCodeAppend("\talpha = 1.0 - alpha;\n"); + } builder->fsCodeAppendf("\t%s = %s;\n", outputColor, (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); } @@ -227,16 +256,18 @@ void GrGLConvexPolyEffect::setData(const GrGLUniformManager& uman, const GrDrawE GrGLEffect::EffectKey GrGLConvexPolyEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { const GrConvexPolyEffect& cpe = drawEffect.castEffect(); - GR_STATIC_ASSERT(GrConvexPolyEffect::kEdgeTypeCnt <= 4); - return (cpe.getEdgeCount() << 2) | cpe.getEdgeType(); + GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8); + return (cpe.getEdgeCount() << 3) | cpe.getEdgeType(); } ////////////////////////////////////////////////////////////////////////////// -GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkPath& path, const SkVector* offset) { +GrEffectRef* GrConvexPolyEffect::Create(GrEffectEdgeType type, const SkPath& path, const SkVector* offset) { + if (kHairlineAA_GrEffectEdgeType == type) { + return NULL; + } if (path.getSegmentMasks() != SkPath::kLine_SegmentMask || - !path.isConvex() || - path.isInverseFillType()) { + !path.isConvex()) { return NULL; } @@ -275,11 +306,17 @@ GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkPath& path, const ++n; } } + if (path.isInverseFillType()) { + type = GrInvertEffectEdgeType(type); + } return Create(type, n, edges); } -GrEffectRef* GrConvexPolyEffect::CreateForAAFillRect(const SkRect& rect) { - return AARectEffect::Create(rect); +GrEffectRef* GrConvexPolyEffect::Create(GrEffectEdgeType edgeType, const SkRect& rect) { + if (kHairlineAA_GrEffectEdgeType == edgeType){ + return NULL; + } + return AARectEffect::Create(edgeType, rect); } GrConvexPolyEffect::~GrConvexPolyEffect() {} @@ -292,7 +329,7 @@ const GrBackendEffectFactory& GrConvexPolyEffect::getFactory() const { return GrTBackendEffectFactory::getInstance(); } -GrConvexPolyEffect::GrConvexPolyEffect(EdgeType edgeType, int n, const SkScalar edges[]) +GrConvexPolyEffect::GrConvexPolyEffect(GrEffectEdgeType edgeType, int n, const SkScalar edges[]) : fEdgeType(edgeType) , fEdgeCount(n) { // Factory function should have already ensured this. @@ -321,12 +358,17 @@ GrEffectRef* GrConvexPolyEffect::TestCreate(SkRandom* random, GrContext*, const GrDrawTargetCaps& caps, GrTexture*[]) { - EdgeType edgeType = static_cast(random->nextULessThan(kEdgeTypeCnt)); int count = random->nextULessThan(kMaxEdges) + 1; SkScalar edges[kMaxEdges * 3]; for (int i = 0; i < 3 * count; ++i) { edges[i] = random->nextSScalar1(); } - return GrConvexPolyEffect::Create(edgeType, count, edges); + GrEffectRef* effect; + do { + GrEffectEdgeType edgeType = static_cast( + random->nextULessThan(kGrEffectEdgeTypeCnt)); + effect = GrConvexPolyEffect::Create(edgeType, count, edges); + } while (NULL == effect); + return effect; } diff --git a/gfx/skia/trunk/src/gpu/effects/GrConvexPolyEffect.h b/gfx/skia/trunk/src/gpu/effects/GrConvexPolyEffect.h index d7d17ab35ace..0e508c7c4877 100644 --- a/gfx/skia/trunk/src/gpu/effects/GrConvexPolyEffect.h +++ b/gfx/skia/trunk/src/gpu/effects/GrConvexPolyEffect.h @@ -10,7 +10,7 @@ #include "GrDrawTargetCaps.h" #include "GrEffect.h" -#include "GrVertexEffect.h" +#include "GrTypesPriv.h" class GrGLConvexPolyEffect; class SkPath; @@ -22,17 +22,7 @@ class SkPath; */ class GrConvexPolyEffect : public GrEffect { public: - /** This could be expanded to include a AA hairline mode. If so, unify with GrBezierEffect's - enum. */ - enum EdgeType { - kFillNoAA_EdgeType, - kFillAA_EdgeType, - - kLastEdgeType = kFillAA_EdgeType, - }; - enum { - kEdgeTypeCnt = kLastEdgeType + 1, kMaxEdges = 8, }; @@ -47,8 +37,8 @@ public: * have to modify the effect/shaderbuilder interface to make it possible (e.g. give access * to the view matrix or untransformed positions in the fragment shader). */ - static GrEffectRef* Create(EdgeType edgeType, int n, const SkScalar edges[]) { - if (n <= 0 || n > kMaxEdges) { + static GrEffectRef* Create(GrEffectEdgeType edgeType, int n, const SkScalar edges[]) { + if (n <= 0 || n > kMaxEdges || kHairlineAA_GrEffectEdgeType == edgeType) { return NULL; } return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrConvexPolyEffect, @@ -60,18 +50,18 @@ public: * inverse filled, or has too many edges, this will return NULL. If offset is non-NULL, then * the path is translated by the vector. */ - static GrEffectRef* Create(EdgeType, const SkPath&, const SkVector* offset= NULL); + static GrEffectRef* Create(GrEffectEdgeType, const SkPath&, const SkVector* offset = NULL); /** * Creates an effect that fills inside the rect with AA edges.. */ - static GrEffectRef* CreateForAAFillRect(const SkRect&); + static GrEffectRef* Create(GrEffectEdgeType, const SkRect&); virtual ~GrConvexPolyEffect(); static const char* Name() { return "ConvexPoly"; } - EdgeType getEdgeType() const { return fEdgeType; } + GrEffectEdgeType getEdgeType() const { return fEdgeType; } int getEdgeCount() const { return fEdgeCount; } @@ -84,13 +74,13 @@ public: virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; private: - GrConvexPolyEffect(EdgeType edgeType, int n, const SkScalar edges[]); + GrConvexPolyEffect(GrEffectEdgeType edgeType, int n, const SkScalar edges[]); virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; - EdgeType fEdgeType; - int fEdgeCount; - SkScalar fEdges[3 * kMaxEdges]; + GrEffectEdgeType fEdgeType; + int fEdgeCount; + SkScalar fEdges[3 * kMaxEdges]; GR_DECLARE_EFFECT_TEST; diff --git a/gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.cpp index 8c38f9bebf91..9159a701e32a 100755 --- a/gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.cpp +++ b/gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.cpp @@ -13,14 +13,17 @@ #include "GrTBackendEffectFactory.h" #include "GrTexture.h" -// The distance field is constructed as unsigned char values, so that the zero value is at 128. -// Hence our zero threshold is 128/255. +// The distance field is constructed as unsigned char values, so that the zero value is at 128, +// and the range is [-4, 4 - 1/255). Hence our multiplier is 8 - 1/32 and zero threshold is 128/255. +#define MULTIPLIER "7.96875" #define THRESHOLD "0.50196078431" class GrGLDistanceFieldTextureEffect : public GrGLVertexEffect { public: - GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, const GrDrawEffect& drawEffect) - : INHERITED (factory) {} + GrGLDistanceFieldTextureEffect(const GrBackendEffectFactory& factory, + const GrDrawEffect& drawEffect) + : INHERITED (factory) + , fTextureSize(SkSize::Make(-1.f,-1.f)) {} virtual void emitCode(GrGLFullShaderBuilder* builder, const GrDrawEffect& drawEffect, @@ -31,43 +34,77 @@ public: const TextureSamplerArray& samplers) SK_OVERRIDE { SkASSERT(1 == drawEffect.castEffect().numVertexAttribs()); - SkString fsCoordName; - const char* vsVaryingName; - const char* fsVaryingNamePtr; - builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsVaryingName, &fsVaryingNamePtr); - fsCoordName = fsVaryingNamePtr; + SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); - const char* attrName = + SkString fsCoordName; + const char* vsCoordName; + const char* fsCoordNamePtr; + builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr); + fsCoordName = fsCoordNamePtr; + + const char* attrName0 = builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0])->c_str(); - builder->vsCodeAppendf("\t%s = %s;\n", vsVaryingName, attrName); + builder->vsCodeAppendf("\t%s = %s;\n", vsCoordName, attrName0); + + const char* textureSizeUniName = NULL; + fTextureSizeUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec2f_GrSLType, "TextureSize", + &textureSizeUniName); builder->fsCodeAppend("\tvec4 texColor = "); builder->fsAppendTextureLookup(samplers[0], fsCoordName.c_str(), kVec2f_GrSLType); builder->fsCodeAppend(";\n"); - builder->fsCodeAppend("\tfloat distance = texColor.r;\n"); + builder->fsCodeAppend("\tfloat distance = " MULTIPLIER "*(texColor.r - " THRESHOLD ");\n"); + + // we adjust for the effect of the transformation on the distance by using + // the length of the gradient of the texture coordinates. We use st coordinates + // to ensure we're mapping 1:1 from texel space to pixel space. + builder->fsCodeAppendf("\tvec2 st = %s*%s;\n", fsCoordName.c_str(), textureSizeUniName); + builder->fsCodeAppend("\tvec2 Jdx = dFdx(st);\n"); + builder->fsCodeAppend("\tvec2 Jdy = dFdy(st);\n"); + builder->fsCodeAppend("\tvec2 st_grad = normalize(st);\n"); + builder->fsCodeAppend("\tvec2 grad = vec2(st_grad.x*Jdx.x + st_grad.y*Jdy.x,\n"); + builder->fsCodeAppend("\t st_grad.x*Jdx.y + st_grad.y*Jdy.y);\n"); + // this gives us a smooth step across approximately one fragment // (assuming a radius of the diagonal of the fragment, hence a factor of sqrt(2)/2) - builder->fsCodeAppend("\tfloat afwidth = 0.7071*length(vec2(dFdx(distance), dFdy(distance)));\n"); - builder->fsCodeAppend("\tfloat val = smoothstep("THRESHOLD"-afwidth, "THRESHOLD"+afwidth, distance);\n"); + builder->fsCodeAppend("\tfloat afwidth = 0.7071*length(grad);\n"); + builder->fsCodeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n"); builder->fsCodeAppendf("\t%s = %s;\n", outputColor, (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str()); } virtual void setData(const GrGLUniformManager& uman, - const GrDrawEffect& drawEffect) SK_OVERRIDE {} + const GrDrawEffect& drawEffect) SK_OVERRIDE { + SkASSERT(fTextureSizeUni.isValid()); + const GrDistanceFieldTextureEffect& distanceFieldEffect = + drawEffect.castEffect(); + if (distanceFieldEffect.getSize().width() != fTextureSize.width() || + distanceFieldEffect.getSize().height() != fTextureSize.height()) { + fTextureSize = distanceFieldEffect.getSize(); + uman.set2f(fTextureSizeUni, + distanceFieldEffect.getSize().width(), + distanceFieldEffect.getSize().height()); + } + } private: + GrGLUniformManager::UniformHandle fTextureSizeUni; + SkSize fTextureSize; + typedef GrGLVertexEffect INHERITED; }; /////////////////////////////////////////////////////////////////////////////// GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, - const GrTextureParams& params) - : fTextureAccess(texture, params) { + const GrTextureParams& params, + const SkISize& size) + : fTextureAccess(texture, params) + , fSize(SkSize::Make(SkIntToScalar(size.width()), SkIntToScalar(size.height()))) { this->addTextureAccess(&fTextureAccess); this->addVertexAttrib(kVec2f_GrSLType); } @@ -112,6 +149,7 @@ GrEffectRef* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, }; GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode); + SkISize size = SkISize::Make(1024, 2048); - return GrDistanceFieldTextureEffect::Create(textures[texIdx], params); + return GrDistanceFieldTextureEffect::Create(textures[texIdx], params, size); } diff --git a/gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.h b/gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.h old mode 100755 new mode 100644 index fc37ddb99a2f..1292c0322126 --- a/gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.h +++ b/gfx/skia/trunk/src/gpu/effects/GrDistanceFieldTextureEffect.h @@ -21,27 +21,30 @@ class GrGLDistanceFieldTextureEffect; */ class GrDistanceFieldTextureEffect : public GrVertexEffect { public: - static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& p) { - AutoEffectUnref effect(SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, p))); + static GrEffectRef* Create(GrTexture* tex, const GrTextureParams& p, const SkISize& s) { + AutoEffectUnref effect(SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, p, s))); return CreateEffectRef(effect); } virtual ~GrDistanceFieldTextureEffect() {} - static const char* Name() { return "Texture"; } + static const char* Name() { return "DistanceFieldTexture"; } virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; + const SkSize& getSize() const { return fSize; } typedef GrGLDistanceFieldTextureEffect GLEffect; virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; private: - GrDistanceFieldTextureEffect(GrTexture* texture, const GrTextureParams& params); + GrDistanceFieldTextureEffect(GrTexture* texture, const GrTextureParams& params, + const SkISize& textureSize); virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; GrTextureAccess fTextureAccess; + SkSize fSize; GR_DECLARE_EFFECT_TEST; diff --git a/gfx/skia/trunk/src/gpu/effects/GrRRectEffect.cpp b/gfx/skia/trunk/src/gpu/effects/GrRRectEffect.cpp new file mode 100644 index 000000000000..9d83785810fa --- /dev/null +++ b/gfx/skia/trunk/src/gpu/effects/GrRRectEffect.cpp @@ -0,0 +1,721 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrRRectEffect.h" + +#include "gl/GrGLEffect.h" +#include "gl/GrGLSL.h" +#include "GrTBackendEffectFactory.h" + +#include "SkRRect.h" + +class GLCircularRRectEffect; + +class CircularRRectEffect : public GrEffect { +public: + // This effect only supports circular corner rrects where the radius is >= kRadiusMin. + static const SkScalar kRadiusMin; + + enum CornerFlags { + kTopLeft_CornerFlag = (1 << SkRRect::kUpperLeft_Corner), + kTopRight_CornerFlag = (1 << SkRRect::kUpperRight_Corner), + kBottomRight_CornerFlag = (1 << SkRRect::kLowerRight_Corner), + kBottomLeft_CornerFlag = (1 << SkRRect::kLowerLeft_Corner), + + kLeft_CornerFlags = kTopLeft_CornerFlag | kBottomLeft_CornerFlag, + kTop_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag, + kRight_CornerFlags = kTopRight_CornerFlag | kBottomRight_CornerFlag, + kBottom_CornerFlags = kBottomLeft_CornerFlag | kBottomRight_CornerFlag, + + kAll_CornerFlags = kTopLeft_CornerFlag | kTopRight_CornerFlag | + kBottomLeft_CornerFlag | kBottomRight_CornerFlag, + + }; + + // The flags are used to indicate which corners are circluar (unflagged corners are assumed to + // be square). + static GrEffectRef* Create(GrEffectEdgeType, uint32_t circularCornerFlags, const SkRRect&); + + virtual ~CircularRRectEffect() {}; + static const char* Name() { return "CircularRRect"; } + + const SkRRect& getRRect() const { return fRRect; } + + uint32_t getCircularCornerFlags() const { return fCircularCornerFlags; } + + GrEffectEdgeType getEdgeType() const { return fEdgeType; } + + typedef GLCircularRRectEffect GLEffect; + + virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; + + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; + +private: + CircularRRectEffect(GrEffectEdgeType, uint32_t circularCornerFlags, const SkRRect&); + + virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; + + SkRRect fRRect; + GrEffectEdgeType fEdgeType; + uint32_t fCircularCornerFlags; + + GR_DECLARE_EFFECT_TEST; + + typedef GrEffect INHERITED; +}; + +const SkScalar CircularRRectEffect::kRadiusMin = 0.5f; + +GrEffectRef* CircularRRectEffect::Create(GrEffectEdgeType edgeType, + uint32_t circularCornerFlags, + const SkRRect& rrect) { + SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdgeType == edgeType); + return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircularRRectEffect, + (edgeType, circularCornerFlags, rrect)))); +} + +void CircularRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { + *validFlags = 0; +} + +const GrBackendEffectFactory& CircularRRectEffect::getFactory() const { + return GrTBackendEffectFactory::getInstance(); +} + +CircularRRectEffect::CircularRRectEffect(GrEffectEdgeType edgeType, uint32_t circularCornerFlags, + const SkRRect& rrect) + : fRRect(rrect) + , fEdgeType(edgeType) + , fCircularCornerFlags(circularCornerFlags) { + this->setWillReadFragmentPosition(); +} + +bool CircularRRectEffect::onIsEqual(const GrEffect& other) const { + const CircularRRectEffect& crre = CastEffect(other); + // The corner flags are derived from fRRect, so no need to check them. + return fEdgeType == crre.fEdgeType && fRRect == crre.fRRect; +} + +////////////////////////////////////////////////////////////////////////////// + +GR_DEFINE_EFFECT_TEST(CircularRRectEffect); + +GrEffectRef* CircularRRectEffect::TestCreate(SkRandom* random, + GrContext*, + const GrDrawTargetCaps& caps, + GrTexture*[]) { + SkScalar w = random->nextRangeScalar(20.f, 1000.f); + SkScalar h = random->nextRangeScalar(20.f, 1000.f); + SkScalar r = random->nextRangeF(kRadiusMin, 9.f); + SkRRect rrect; + rrect.setRectXY(SkRect::MakeWH(w, h), r, r); + GrEffectRef* effect; + do { + GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectEdgeTypeCnt); + effect = GrRRectEffect::Create(et, rrect); + } while (NULL == effect); + return effect; +} + +////////////////////////////////////////////////////////////////////////////// + +class GLCircularRRectEffect : public GrGLEffect { +public: + GLCircularRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); + + virtual void emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TransformedCoordsArray&, + const TextureSamplerArray&) SK_OVERRIDE; + + static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); + + virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; + +private: + GrGLUniformManager::UniformHandle fInnerRectUniform; + GrGLUniformManager::UniformHandle fRadiusPlusHalfUniform; + SkRRect fPrevRRect; + typedef GrGLEffect INHERITED; +}; + +GLCircularRRectEffect::GLCircularRRectEffect(const GrBackendEffectFactory& factory, + const GrDrawEffect& drawEffect) + : INHERITED (factory) { + fPrevRRect.setEmpty(); +} + +void GLCircularRRectEffect::emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TransformedCoordsArray&, + const TextureSamplerArray& samplers) { + const CircularRRectEffect& crre = drawEffect.castEffect(); + const char *rectName; + const char *radiusPlusHalfName; + // The inner rect is the rrect bounds inset by the radius. Its left, top, right, and bottom + // edges correspond to components x, y, z, and w, respectively. When a side of the rrect has + // only rectangular corners, that side's value corresponds to the rect edge's value outset by + // half a pixel. + fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec4f_GrSLType, + "innerRect", + &rectName); + fRadiusPlusHalfUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kFloat_GrSLType, + "radiusPlusHalf", + &radiusPlusHalfName); + const char* fragmentPos = builder->fragmentPosition(); + // At each quarter-circle corner we compute a vector that is the offset of the fragment position + // from the circle center. The vector is pinned in x and y to be in the quarter-plane relevant + // to that corner. This means that points near the interior near the rrect top edge will have + // a vector that points straight up for both the TL left and TR corners. Computing an + // alpha from this vector at either the TR or TL corner will give the correct result. Similarly, + // fragments near the other three edges will get the correct AA. Fragments in the interior of + // the rrect will have a (0,0) vector at all four corners. So long as the radius > 0.5 they will + // correctly produce an alpha value of 1 at all four corners. We take the min of all the alphas. + // The code below is a simplified version of the above that performs maxs on the vector + // components before computing distances and alpha values so that only one distance computation + // need be computed to determine the min alpha. + // + // For the cases where one half of the rrect is rectangular we drop one of the x or y + // computations, compute a separate rect edge alpha for the rect side, and mul the two computed + // alphas together. + switch (crre.getCircularCornerFlags()) { + case CircularRRectEffect::kAll_CornerFlags: + builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); + builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName); + builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n"); + builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + case CircularRRectEffect::kTopLeft_CornerFlag: + builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.xy, 0.0);\n", + rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n", + rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n", + rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + case CircularRRectEffect::kTopRight_CornerFlag: + builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.z, %s.y - %s.y), 0.0);\n", + fragmentPos, rectName, rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n", + fragmentPos, rectName); + builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n", + rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + case CircularRRectEffect::kBottomRight_CornerFlag: + builder->fsCodeAppendf("\t\tvec2 dxy = max(%s.xy - %s.zw, 0.0);\n", + fragmentPos, rectName); + builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n", + fragmentPos, rectName); + builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n", + fragmentPos, rectName); + builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + case CircularRRectEffect::kBottomLeft_CornerFlag: + builder->fsCodeAppendf("\t\tvec2 dxy = max(vec2(%s.x - %s.x, %s.y - %s.w), 0.0);\n", + rectName, fragmentPos, fragmentPos, rectName); + builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n", + rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n", + fragmentPos, rectName); + builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + case CircularRRectEffect::kLeft_CornerFlags: + builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat dy1 = %s.y - %s.w;\n", fragmentPos, rectName); + builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy0.x, max(dxy0.y, dy1)), 0.0);\n"); + builder->fsCodeAppendf("\t\tfloat rightAlpha = clamp(%s.z - %s.x, 0.0, 1.0);\n", + rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat alpha = rightAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + case CircularRRectEffect::kTop_CornerFlags: + builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat dx1 = %s.x - %s.z;\n", fragmentPos, rectName); + builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dxy0.x, dx1), dxy0.y), 0.0);\n"); + builder->fsCodeAppendf("\t\tfloat bottomAlpha = clamp(%s.w - %s.y, 0.0, 1.0);\n", + rectName, fragmentPos); + builder->fsCodeAppendf("\t\tfloat alpha = bottomAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + case CircularRRectEffect::kRight_CornerFlags: + builder->fsCodeAppendf("\t\tfloat dy0 = %s.y - %s.y;\n", rectName, fragmentPos); + builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName); + builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(dxy1.x, max(dy0, dxy1.y)), 0.0);\n"); + builder->fsCodeAppendf("\t\tfloat leftAlpha = clamp(%s.x - %s.x, 0.0, 1.0);\n", + fragmentPos, rectName); + builder->fsCodeAppendf("\t\tfloat alpha = leftAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + case CircularRRectEffect::kBottom_CornerFlags: + builder->fsCodeAppendf("\t\tfloat dx0 = %s.x - %s.x;\n", rectName, fragmentPos); + builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName); + builder->fsCodeAppend("\t\tvec2 dxy = max(vec2(max(dx0, dxy1.x), dxy1.y), 0.0);\n"); + builder->fsCodeAppendf("\t\tfloat topAlpha = clamp(%s.y - %s.y, 0.0, 1.0);\n", + fragmentPos, rectName); + builder->fsCodeAppendf("\t\tfloat alpha = topAlpha * clamp(%s - length(dxy), 0.0, 1.0);\n", + radiusPlusHalfName); + break; + } + + if (kInverseFillAA_GrEffectEdgeType == crre.getEdgeType()) { + builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n"); + } + + builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, + (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); +} + +GrGLEffect::EffectKey GLCircularRRectEffect::GenKey(const GrDrawEffect& drawEffect, + const GrGLCaps&) { + const CircularRRectEffect& crre = drawEffect.castEffect(); + GR_STATIC_ASSERT(kGrEffectEdgeTypeCnt <= 8); + return (crre.getCircularCornerFlags() << 3) | crre.getEdgeType(); +} + +void GLCircularRRectEffect::setData(const GrGLUniformManager& uman, + const GrDrawEffect& drawEffect) { + const CircularRRectEffect& crre = drawEffect.castEffect(); + const SkRRect& rrect = crre.getRRect(); + if (rrect != fPrevRRect) { + SkRect rect = rrect.getBounds(); + SkScalar radius = 0; + switch (crre.getCircularCornerFlags()) { + case CircularRRectEffect::kAll_CornerFlags: + SkASSERT(rrect.isSimpleCircular()); + radius = rrect.getSimpleRadii().fX; + SkASSERT(radius >= CircularRRectEffect::kRadiusMin); + rect.inset(radius, radius); + break; + case CircularRRectEffect::kTopLeft_CornerFlag: + radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; + rect.fLeft += radius; + rect.fTop += radius; + rect.fRight += 0.5f; + rect.fBottom += 0.5f; + break; + case CircularRRectEffect::kTopRight_CornerFlag: + radius = rrect.radii(SkRRect::kUpperRight_Corner).fX; + rect.fLeft -= 0.5f; + rect.fTop += radius; + rect.fRight -= radius; + rect.fBottom += 0.5f; + break; + case CircularRRectEffect::kBottomRight_CornerFlag: + radius = rrect.radii(SkRRect::kLowerRight_Corner).fX; + rect.fLeft -= 0.5f; + rect.fTop -= 0.5f; + rect.fRight -= radius; + rect.fBottom -= radius; + break; + case CircularRRectEffect::kBottomLeft_CornerFlag: + radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX; + rect.fLeft += radius; + rect.fTop -= 0.5f; + rect.fRight += 0.5f; + rect.fBottom -= radius; + break; + case CircularRRectEffect::kLeft_CornerFlags: + radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; + rect.fLeft += radius; + rect.fTop += radius; + rect.fRight += 0.5f; + rect.fBottom -= radius; + break; + case CircularRRectEffect::kTop_CornerFlags: + radius = rrect.radii(SkRRect::kUpperLeft_Corner).fX; + rect.fLeft += radius; + rect.fTop += radius; + rect.fRight -= radius; + rect.fBottom += 0.5f; + break; + case CircularRRectEffect::kRight_CornerFlags: + radius = rrect.radii(SkRRect::kUpperRight_Corner).fX; + rect.fLeft -= 0.5f; + rect.fTop += radius; + rect.fRight -= radius; + rect.fBottom -= radius; + break; + case CircularRRectEffect::kBottom_CornerFlags: + radius = rrect.radii(SkRRect::kLowerLeft_Corner).fX; + rect.fLeft += radius; + rect.fTop -= 0.5f; + rect.fRight -= radius; + rect.fBottom -= radius; + break; + default: + GrCrash("Should have been one of the above cases."); + } + uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); + uman.set1f(fRadiusPlusHalfUniform, radius + 0.5f); + fPrevRRect = rrect; + } +} + +////////////////////////////////////////////////////////////////////////////// + +class GLEllipticalRRectEffect; + +class EllipticalRRectEffect : public GrEffect { +public: + // This effect currently works for these two classifications of SkRRects + enum RRectType { + kSimple_RRectType, // SkRRect::kSimple_Type + kNinePatch_RRectType, // The two left x radii are the same, the two + // top y radii are the same, etc. + }; + + // This effect only supports rrects where the radii are >= kRadiusMin. + static const SkScalar kRadiusMin; + + static GrEffectRef* Create(GrEffectEdgeType, RRectType, const SkRRect&); + + virtual ~EllipticalRRectEffect() {}; + static const char* Name() { return "EllipticalRRect"; } + + const SkRRect& getRRect() const { return fRRect; } + + RRectType getRRectType() const { return fRRectType; } + + GrEffectEdgeType getEdgeType() const { return fEdgeType; } + + typedef GLEllipticalRRectEffect GLEffect; + + virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; + + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; + +private: + EllipticalRRectEffect(GrEffectEdgeType, RRectType, const SkRRect&); + + virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; + + SkRRect fRRect; + RRectType fRRectType; + GrEffectEdgeType fEdgeType; + + GR_DECLARE_EFFECT_TEST; + + typedef GrEffect INHERITED; +}; + +const SkScalar EllipticalRRectEffect::kRadiusMin = 0.5f; + +GrEffectRef* EllipticalRRectEffect::Create(GrEffectEdgeType edgeType, + RRectType rrType, + const SkRRect& rrect) { + SkASSERT(kFillAA_GrEffectEdgeType == edgeType || kInverseFillAA_GrEffectEdgeType == edgeType); + return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipticalRRectEffect, (edgeType, rrType, + rrect)))); +} + +void EllipticalRRectEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { + *validFlags = 0; +} + +const GrBackendEffectFactory& EllipticalRRectEffect::getFactory() const { + return GrTBackendEffectFactory::getInstance(); +} + +EllipticalRRectEffect::EllipticalRRectEffect(GrEffectEdgeType edgeType, RRectType rrType, + const SkRRect& rrect) + : fRRect(rrect) + , fRRectType(rrType) + , fEdgeType(edgeType){ + this->setWillReadFragmentPosition(); +} + +bool EllipticalRRectEffect::onIsEqual(const GrEffect& other) const { + const EllipticalRRectEffect& erre = CastEffect(other); + // No need to check fRRectType as it is derived from fRRect. + return fEdgeType == erre.fEdgeType && fRRect == erre.fRRect; +} + +////////////////////////////////////////////////////////////////////////////// + +GR_DEFINE_EFFECT_TEST(EllipticalRRectEffect); + +GrEffectRef* EllipticalRRectEffect::TestCreate(SkRandom* random, + GrContext*, + const GrDrawTargetCaps& caps, + GrTexture*[]) { + SkScalar w = random->nextRangeScalar(20.f, 1000.f); + SkScalar h = random->nextRangeScalar(20.f, 1000.f); + SkVector r[4]; + r[SkRRect::kUpperLeft_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); + // ensure at least one corner really is elliptical + do { + r[SkRRect::kUpperLeft_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); + } while (r[SkRRect::kUpperLeft_Corner].fY == r[SkRRect::kUpperLeft_Corner].fX); + + SkRRect rrect; + if (random->nextBool()) { + // half the time create a four-radii rrect. + r[SkRRect::kLowerRight_Corner].fX = random->nextRangeF(kRadiusMin, 9.f); + r[SkRRect::kLowerRight_Corner].fY = random->nextRangeF(kRadiusMin, 9.f); + + r[SkRRect::kUpperRight_Corner].fX = r[SkRRect::kLowerRight_Corner].fX; + r[SkRRect::kUpperRight_Corner].fY = r[SkRRect::kUpperLeft_Corner].fY; + + r[SkRRect::kLowerLeft_Corner].fX = r[SkRRect::kUpperLeft_Corner].fX; + r[SkRRect::kLowerLeft_Corner].fY = r[SkRRect::kLowerRight_Corner].fY; + + rrect.setRectRadii(SkRect::MakeWH(w, h), r); + } else { + rrect.setRectXY(SkRect::MakeWH(w, h), r[SkRRect::kUpperLeft_Corner].fX, + r[SkRRect::kUpperLeft_Corner].fY); + } + GrEffectRef* effect; + do { + GrEffectEdgeType et = (GrEffectEdgeType)random->nextULessThan(kGrEffectEdgeTypeCnt); + effect = GrRRectEffect::Create(et, rrect); + } while (NULL == effect); + return effect; +} + +////////////////////////////////////////////////////////////////////////////// + +class GLEllipticalRRectEffect : public GrGLEffect { +public: + GLEllipticalRRectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); + + virtual void emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TransformedCoordsArray&, + const TextureSamplerArray&) SK_OVERRIDE; + + static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); + + virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; + +private: + GrGLUniformManager::UniformHandle fInnerRectUniform; + GrGLUniformManager::UniformHandle fInvRadiiSqdUniform; + SkRRect fPrevRRect; + typedef GrGLEffect INHERITED; +}; + +GLEllipticalRRectEffect::GLEllipticalRRectEffect(const GrBackendEffectFactory& factory, + const GrDrawEffect& drawEffect) + : INHERITED (factory) { + fPrevRRect.setEmpty(); +} + +void GLEllipticalRRectEffect::emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TransformedCoordsArray&, + const TextureSamplerArray& samplers) { + const EllipticalRRectEffect& erre = drawEffect.castEffect(); + const char *rectName; + // The inner rect is the rrect bounds inset by the x/y radii + fInnerRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec4f_GrSLType, + "innerRect", + &rectName); + const char* fragmentPos = builder->fragmentPosition(); + // At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos + // to the ellipse center. The vector is pinned in x and y to be in the quarter-plane relevant + // to that corner. This means that points near the interior near the rrect top edge will have + // a vector that points straight up for both the TL left and TR corners. Computing an + // alpha from this vector at either the TR or TL corner will give the correct result. Similarly, + // fragments near the other three edges will get the correct AA. Fragments in the interior of + // the rrect will have a (0,0) vector at all four corners. So long as the radii > 0.5 they will + // correctly produce an alpha value of 1 at all four corners. We take the min of all the alphas. + // The code below is a simplified version of the above that performs maxs on the vector + // components before computing distances and alpha values so that only one distance computation + // need be computed to determine the min alpha. + builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos); + builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName); + switch (erre.getRRectType()) { + case EllipticalRRectEffect::kSimple_RRectType: { + const char *invRadiiXYSqdName; + fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec2f_GrSLType, + "invRadiiXY", + &invRadiiXYSqdName); + builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n"); + // Z is the x/y offsets divided by squared radii. + builder->fsCodeAppendf("\t\tvec2 Z = dxy * %s;\n", invRadiiXYSqdName); + break; + } + case EllipticalRRectEffect::kNinePatch_RRectType: { + const char *invRadiiLTRBSqdName; + fInvRadiiSqdUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, + kVec4f_GrSLType, + "invRadiiLTRB", + &invRadiiLTRBSqdName); + builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n"); + // Z is the x/y offsets divided by squared radii. We only care about the (at most) one + // corner where both the x and y offsets are positive, hence the maxes. (The inverse + // squared radii will always be positive.) + builder->fsCodeAppendf("\t\tvec2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);\n", + invRadiiLTRBSqdName, invRadiiLTRBSqdName); + break; + } + } + // implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1. + builder->fsCodeAppend("\t\tfloat implicit = dot(Z, dxy) - 1.0;\n"); + // grad_dot is the squared length of the gradient of the implicit. + builder->fsCodeAppendf("\t\tfloat grad_dot = 4.0 * dot(Z, Z);\n"); + builder->fsCodeAppend("\t\tgrad_dot = max(grad_dot, 1.0e-4);\n"); + builder->fsCodeAppendf("\t\tfloat approx_dist = implicit * inversesqrt(grad_dot);\n"); + + if (kFillAA_GrEffectEdgeType == erre.getEdgeType()) { + builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n"); + } else { + builder->fsCodeAppend("\t\tfloat alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n"); + } + + builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, + (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); +} + +GrGLEffect::EffectKey GLEllipticalRRectEffect::GenKey(const GrDrawEffect& drawEffect, + const GrGLCaps&) { + const EllipticalRRectEffect& erre = drawEffect.castEffect(); + GR_STATIC_ASSERT(kLast_GrEffectEdgeType < (1 << 3)); + return erre.getRRectType() | erre.getEdgeType() << 3; +} + +void GLEllipticalRRectEffect::setData(const GrGLUniformManager& uman, + const GrDrawEffect& drawEffect) { + const EllipticalRRectEffect& erre = drawEffect.castEffect(); + const SkRRect& rrect = erre.getRRect(); + if (rrect != fPrevRRect) { + SkRect rect = rrect.getBounds(); + const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); + SkASSERT(r0.fX >= EllipticalRRectEffect::kRadiusMin); + SkASSERT(r0.fY >= EllipticalRRectEffect::kRadiusMin); + switch (erre.getRRectType()) { + case EllipticalRRectEffect::kSimple_RRectType: + rect.inset(r0.fX, r0.fY); + uman.set2f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), + 1.f / (r0.fY * r0.fY)); + break; + case EllipticalRRectEffect::kNinePatch_RRectType: { + const SkVector& r1 = rrect.radii(SkRRect::kLowerRight_Corner); + SkASSERT(r1.fX >= EllipticalRRectEffect::kRadiusMin); + SkASSERT(r1.fY >= EllipticalRRectEffect::kRadiusMin); + rect.fLeft += r0.fX; + rect.fTop += r0.fY; + rect.fRight -= r1.fX; + rect.fBottom -= r1.fY; + uman.set4f(fInvRadiiSqdUniform, 1.f / (r0.fX * r0.fX), + 1.f / (r0.fY * r0.fY), + 1.f / (r1.fX * r1.fX), + 1.f / (r1.fY * r1.fY)); + break; + } + } + uman.set4f(fInnerRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); + fPrevRRect = rrect; + } +} + +////////////////////////////////////////////////////////////////////////////// + +GrEffectRef* GrRRectEffect::Create(GrEffectEdgeType edgeType, const SkRRect& rrect) { + if (kFillAA_GrEffectEdgeType != edgeType && kInverseFillAA_GrEffectEdgeType != edgeType) { + return NULL; + } + uint32_t cornerFlags; + if (rrect.isSimple()) { + if (rrect.getSimpleRadii().fX == rrect.getSimpleRadii().fY) { + if (rrect.getSimpleRadii().fX < CircularRRectEffect::kRadiusMin) { + return NULL; + } + cornerFlags = CircularRRectEffect::kAll_CornerFlags; + } else { + if (rrect.getSimpleRadii().fX < EllipticalRRectEffect::kRadiusMin || + rrect.getSimpleRadii().fY < EllipticalRRectEffect::kRadiusMin) { + return NULL; + } + return EllipticalRRectEffect::Create(edgeType, + EllipticalRRectEffect::kSimple_RRectType, rrect); + } + } else if (rrect.isComplex()) { + // Check for the "tab" cases - two adjacent circular corners and two square corners. + SkScalar radius = 0; + cornerFlags = 0; + for (int c = 0; c < 4; ++c) { + const SkVector& r = rrect.radii((SkRRect::Corner)c); + SkASSERT((0 == r.fX) == (0 == r.fY)); + if (0 == r.fX) { + continue; + } + if (r.fX != r.fY) { + cornerFlags = ~0U; + break; + } + if (!cornerFlags) { + radius = r.fX; + if (radius < CircularRRectEffect::kRadiusMin) { + cornerFlags = ~0U; + break; + } + cornerFlags = 1 << c; + } else { + if (r.fX != radius) { + cornerFlags = ~0U; + break; + } + cornerFlags |= 1 << c; + } + } + + switch (cornerFlags) { + case CircularRRectEffect::kTopLeft_CornerFlag: + case CircularRRectEffect::kTopRight_CornerFlag: + case CircularRRectEffect::kBottomRight_CornerFlag: + case CircularRRectEffect::kBottomLeft_CornerFlag: + case CircularRRectEffect::kLeft_CornerFlags: + case CircularRRectEffect::kTop_CornerFlags: + case CircularRRectEffect::kRight_CornerFlags: + case CircularRRectEffect::kBottom_CornerFlags: + case CircularRRectEffect::kAll_CornerFlags: + break; + default: + if (rrect.isNinePatch()) { + const SkVector& r0 = rrect.radii(SkRRect::kUpperLeft_Corner); + const SkVector& r1 = rrect.radii(SkRRect::kLowerRight_Corner); + if (r0.fX >= EllipticalRRectEffect::kRadiusMin && + r0.fY >= EllipticalRRectEffect::kRadiusMin && + r1.fX >= EllipticalRRectEffect::kRadiusMin && + r1.fY >= EllipticalRRectEffect::kRadiusMin) { + return EllipticalRRectEffect::Create(edgeType, + EllipticalRRectEffect::kNinePatch_RRectType, + rrect); + } + } + return NULL; + } + } else { + return NULL; + } + return CircularRRectEffect::Create(edgeType, cornerFlags, rrect); +} diff --git a/gfx/skia/trunk/src/gpu/effects/GrRRectEffect.h b/gfx/skia/trunk/src/gpu/effects/GrRRectEffect.h new file mode 100644 index 000000000000..45ac5f43cfbd --- /dev/null +++ b/gfx/skia/trunk/src/gpu/effects/GrRRectEffect.h @@ -0,0 +1,25 @@ +/* + * 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 GrRRectEffect_DEFINED +#define GrRRectEffect_DEFINED + +#include "GrTypes.h" +#include "GrTypesPriv.h" + +class GrEffectRef; +class SkRRect; + +namespace GrRRectEffect { + /** + * Creates an effect that performs anti-aliased clipping against a SkRRect. It doesn't support + * all varieties of SkRRect so the caller must check for a NULL return. + */ + GrEffectRef* Create(GrEffectEdgeType, const SkRRect&); +}; + +#endif diff --git a/gfx/skia/trunk/src/gpu/effects/GrTextureDomainEffect.cpp b/gfx/skia/trunk/src/gpu/effects/GrTextureDomainEffect.cpp deleted file mode 100644 index 699aa729fd9f..000000000000 --- a/gfx/skia/trunk/src/gpu/effects/GrTextureDomainEffect.cpp +++ /dev/null @@ -1,221 +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. - */ - -#include "GrTextureDomainEffect.h" -#include "GrSimpleTextureEffect.h" -#include "GrTBackendEffectFactory.h" -#include "gl/GrGLEffect.h" -#include "SkFloatingPoint.h" - -class GrGLTextureDomainEffect : public GrGLEffect { -public: - GrGLTextureDomainEffect(const GrBackendEffectFactory&, const GrDrawEffect&); - - virtual void emitCode(GrGLShaderBuilder*, - const GrDrawEffect&, - EffectKey, - const char* outputColor, - const char* inputColor, - const TransformedCoordsArray&, - const TextureSamplerArray&) SK_OVERRIDE; - - virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; - - static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); - -private: - GrGLUniformManager::UniformHandle fNameUni; - GrGLfloat fPrevDomain[4]; - - typedef GrGLEffect INHERITED; -}; - -GrGLTextureDomainEffect::GrGLTextureDomainEffect(const GrBackendEffectFactory& factory, - const GrDrawEffect&) - : INHERITED(factory) { - fPrevDomain[0] = SK_FloatNaN; -} - -void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder, - const GrDrawEffect& drawEffect, - EffectKey key, - const char* outputColor, - const char* inputColor, - const TransformedCoordsArray& coords, - const TextureSamplerArray& samplers) { - const GrTextureDomainEffect& texDom = drawEffect.castEffect(); - - SkString coords2D = builder->ensureFSCoords2D(coords, 0); - const char* domain; - fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, - kVec4f_GrSLType, "TexDom", &domain); - if (GrTextureDomainEffect::kClamp_WrapMode == texDom.wrapMode()) { - - builder->fsCodeAppendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n", - coords2D.c_str(), domain, domain); - - builder->fsCodeAppendf("\t%s = ", outputColor); - builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], "clampCoord"); - builder->fsCodeAppend(";\n"); - } else { - SkASSERT(GrTextureDomainEffect::kDecal_WrapMode == texDom.wrapMode()); - - if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) { - // On the NexusS and GalaxyNexus, the other path (with the 'any' - // call) causes the compilation error "Calls to any function that - // may require a gradient calculation inside a conditional block - // may return undefined results". This appears to be an issue with - // the 'any' call since even the simple "result=black; if (any()) - // result=white;" code fails to compile. - builder->fsCodeAppend("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n"); - builder->fsCodeAppend("\tvec4 inside = "); - builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], coords2D.c_str()); - builder->fsCodeAppend(";\n"); - - builder->fsCodeAppendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n", - coords2D.c_str(), domain, domain, domain); - builder->fsCodeAppendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n", - coords2D.c_str(), domain, domain, domain); - builder->fsCodeAppend("\tfloat blend = step(1.0, max(x, y));\n"); - builder->fsCodeAppendf("\t%s = mix(inside, outside, blend);\n", outputColor); - } else { - builder->fsCodeAppend("\tbvec4 outside;\n"); - builder->fsCodeAppendf("\toutside.xy = lessThan(%s, %s.xy);\n", coords2D.c_str(), domain); - builder->fsCodeAppendf("\toutside.zw = greaterThan(%s, %s.zw);\n", coords2D.c_str(), domain); - builder->fsCodeAppendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outputColor); - builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], coords2D.c_str()); - builder->fsCodeAppend(";\n"); - } - } -} - -void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, - const GrDrawEffect& drawEffect) { - const GrTextureDomainEffect& texDom = drawEffect.castEffect(); - const SkRect& domain = texDom.domain(); - - float values[4] = { - SkScalarToFloat(domain.left()), - SkScalarToFloat(domain.top()), - SkScalarToFloat(domain.right()), - SkScalarToFloat(domain.bottom()) - }; - // vertical flip if necessary - if (kBottomLeft_GrSurfaceOrigin == texDom.texture(0)->origin()) { - values[1] = 1.0f - values[1]; - values[3] = 1.0f - values[3]; - // The top and bottom were just flipped, so correct the ordering - // of elements so that values = (l, t, r, b). - SkTSwap(values[1], values[3]); - } - if (0 != memcmp(values, fPrevDomain, 4 * sizeof(GrGLfloat))) { - uman.set4fv(fNameUni, 1, values); - memcpy(fPrevDomain, values, 4 * sizeof(GrGLfloat)); - } -} - -GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrDrawEffect& drawEffect, - const GrGLCaps&) { - return drawEffect.castEffect().wrapMode(); -} - - -/////////////////////////////////////////////////////////////////////////////// - -GrEffectRef* GrTextureDomainEffect::Create(GrTexture* texture, - const SkMatrix& matrix, - const SkRect& domain, - WrapMode wrapMode, - GrTextureParams::FilterMode filterMode, - GrCoordSet coordSet) { - static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; - if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) { - return GrSimpleTextureEffect::Create(texture, matrix, filterMode); - } else { - SkRect clippedDomain; - // We don't currently handle domains that are empty or don't intersect the texture. - // It is OK if the domain rect is a line or point, but it should not be inverted. We do not - // handle rects that do not intersect the [0..1]x[0..1] rect. - SkASSERT(domain.fLeft <= domain.fRight); - SkASSERT(domain.fTop <= domain.fBottom); - clippedDomain.fLeft = SkMaxScalar(domain.fLeft, kFullRect.fLeft); - clippedDomain.fRight = SkMinScalar(domain.fRight, kFullRect.fRight); - clippedDomain.fTop = SkMaxScalar(domain.fTop, kFullRect.fTop); - clippedDomain.fBottom = SkMinScalar(domain.fBottom, kFullRect.fBottom); - SkASSERT(clippedDomain.fLeft <= clippedDomain.fRight); - SkASSERT(clippedDomain.fTop <= clippedDomain.fBottom); - - AutoEffectUnref effect(SkNEW_ARGS(GrTextureDomainEffect, (texture, - matrix, - clippedDomain, - wrapMode, - filterMode, - coordSet))); - return CreateEffectRef(effect); - - } -} - -GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, - const SkMatrix& matrix, - const SkRect& domain, - WrapMode wrapMode, - GrTextureParams::FilterMode filterMode, - GrCoordSet coordSet) - : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) - , fWrapMode(wrapMode) - , fTextureDomain(domain) { -} - -GrTextureDomainEffect::~GrTextureDomainEffect() { - -} - -const GrBackendEffectFactory& GrTextureDomainEffect::getFactory() const { - return GrTBackendEffectFactory::getInstance(); -} - -bool GrTextureDomainEffect::onIsEqual(const GrEffect& sBase) const { - const GrTextureDomainEffect& s = CastEffect(sBase); - return this->hasSameTextureParamsMatrixAndSourceCoords(s) && - this->fTextureDomain == s.fTextureDomain; -} - -void GrTextureDomainEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - if (kDecal_WrapMode == fWrapMode) { - *validFlags = 0; - } else { - this->updateConstantColorComponentsForModulation(color, validFlags); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -GR_DEFINE_EFFECT_TEST(GrTextureDomainEffect); - -GrEffectRef* GrTextureDomainEffect::TestCreate(SkRandom* random, - GrContext*, - const GrDrawTargetCaps&, - GrTexture* textures[]) { - int texIdx = random->nextBool() ? GrEffectUnitTest::kSkiaPMTextureIdx : - GrEffectUnitTest::kAlphaTextureIdx; - SkRect domain; - domain.fLeft = random->nextUScalar1(); - domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1); - domain.fTop = random->nextUScalar1(); - domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1); - WrapMode wrapMode = random->nextBool() ? kClamp_WrapMode : kDecal_WrapMode; - const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random); - bool bilerp = random->nextBool(); - GrCoordSet coords = random->nextBool() ? kLocal_GrCoordSet : kPosition_GrCoordSet; - return GrTextureDomainEffect::Create(textures[texIdx], - matrix, - domain, - wrapMode, - bilerp ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode, - coords); -} diff --git a/gfx/skia/trunk/src/gpu/effects/GrTextureDomainEffect.h b/gfx/skia/trunk/src/gpu/effects/GrTextureDomainEffect.h deleted file mode 100644 index 46ee2a650668..000000000000 --- a/gfx/skia/trunk/src/gpu/effects/GrTextureDomainEffect.h +++ /dev/null @@ -1,89 +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 GrTextureDomainEffect_DEFINED -#define GrTextureDomainEffect_DEFINED - -#include "GrSingleTextureEffect.h" - -class GrGLTextureDomainEffect; -struct SkRect; - -/** - * Limits a texture's lookup coordinates to a domain. Samples outside the domain are either clamped - * the edge of the domain or result in a vec4 of zeros. The domain is clipped to normalized texture - * coords ([0,1]x[0,1] square). Bilinear filtering can cause texels outside the domain to affect the - * read value unless the caller considers this when calculating the domain. TODO: This should be a - * helper that can assist an effect rather than effect unto itself. - */ -class GrTextureDomainEffect : public GrSingleTextureEffect { - -public: - /** - * If SkShader::kDecal_TileMode sticks then this enum could be replaced by SkShader::TileMode. - * We could also consider replacing/augmenting Decal mode with Border mode where the color - * outside of the domain is user-specifiable. Decal mode currently has a hard (non-lerped) - * transition between the border and the interior. - */ - enum WrapMode { - kClamp_WrapMode, - kDecal_WrapMode, - }; - - static GrEffectRef* Create(GrTexture*, - const SkMatrix&, - const SkRect& domain, - WrapMode, - GrTextureParams::FilterMode filterMode, - GrCoordSet = kLocal_GrCoordSet); - - virtual ~GrTextureDomainEffect(); - - static const char* Name() { return "TextureDomain"; } - - typedef GrGLTextureDomainEffect GLEffect; - - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - - const SkRect& domain() const { return fTextureDomain; } - WrapMode wrapMode() const { return fWrapMode; } - - /* Computes a domain that bounds all the texels in texelRect. Note that with bilerp enabled - texels neighboring the domain may be read. */ - static const SkRect MakeTexelDomain(const GrTexture* texture, const SkIRect& texelRect) { - SkScalar wInv = SK_Scalar1 / texture->width(); - SkScalar hInv = SK_Scalar1 / texture->height(); - SkRect result = { - texelRect.fLeft * wInv, - texelRect.fTop * hInv, - texelRect.fRight * wInv, - texelRect.fBottom * hInv - }; - return result; - } - -protected: - WrapMode fWrapMode; - SkRect fTextureDomain; - -private: - GrTextureDomainEffect(GrTexture*, - const SkMatrix&, - const SkRect& domain, - WrapMode, - GrTextureParams::FilterMode filterMode, - GrCoordSet); - - virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; - - GR_DECLARE_EFFECT_TEST; - - typedef GrSingleTextureEffect INHERITED; -}; - -#endif diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLCaps.cpp b/gfx/skia/trunk/src/gpu/gl/GrGLCaps.cpp index bdb19e2e3a52..a60230a2fe91 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLCaps.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGLCaps.cpp @@ -312,6 +312,8 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering"); SkASSERT(!fPathRenderingSupport || fFixedFunctionSupport); + fGpuTracingSupport = ctxInfo.hasExtension("GL_EXT_debug_marker"); + fDstReadInShaderSupport = kNone_FBFetchType != fFBFetchType; // Disable scratch texture reuse on Mali and Adreno devices diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLCreateNullInterface.cpp b/gfx/skia/trunk/src/gpu/gl/GrGLCreateNullInterface.cpp index 105fb0b60447..391aea27f466 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLCreateNullInterface.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGLCreateNullInterface.cpp @@ -100,7 +100,6 @@ GrGLvoid GR_GL_FUNCTION_TYPE nullGLBeginQuery(GrGLenum target, GrGLuint id) {} GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindAttribLocation(GrGLuint program, GrGLuint index, const char* name) {} GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindTexture(GrGLenum target, GrGLuint texture) {} GrGLvoid GR_GL_FUNCTION_TYPE nullGLBindVertexArray(GrGLuint id) {} -GrGLvoid GR_GL_FUNCTION_TYPE nullGLClientActiveTexture(GrGLenum) {} GrGLvoid GR_GL_FUNCTION_TYPE nullGLGenBuffers(GrGLsizei n, GrGLuint* ids) { @@ -260,150 +259,144 @@ GrGLvoid GR_GL_FUNCTION_TYPE nullGLGetBufferParameteriv(GrGLenum target, GrGLenu } // end anonymous namespace const GrGLInterface* GrGLCreateNullInterface() { - // The gl functions are not context-specific so we create one global - // interface - static SkAutoTUnref glInterface; - if (!glInterface.get()) { - GrGLInterface* interface = SkNEW(GrGLInterface); - glInterface.reset(interface); + GrGLInterface* interface = SkNEW(GrGLInterface); - interface->fStandard = kGL_GrGLStandard; + interface->fStandard = kGL_GrGLStandard; - GrGLInterface::Functions* functions = &interface->fFunctions; - functions->fActiveTexture = nullGLActiveTexture; - functions->fAttachShader = nullGLAttachShader; - functions->fBeginQuery = nullGLBeginQuery; - functions->fBindAttribLocation = nullGLBindAttribLocation; - functions->fBindBuffer = nullGLBindBuffer; - functions->fBindFragDataLocation = noOpGLBindFragDataLocation; - functions->fBindTexture = nullGLBindTexture; - functions->fBindVertexArray = nullGLBindVertexArray; - functions->fBlendColor = noOpGLBlendColor; - functions->fBlendFunc = noOpGLBlendFunc; - functions->fBufferData = nullGLBufferData; - functions->fBufferSubData = noOpGLBufferSubData; - functions->fClear = noOpGLClear; - functions->fClearColor = noOpGLClearColor; - functions->fClearStencil = noOpGLClearStencil; - functions->fClientActiveTexture = nullGLClientActiveTexture; - functions->fColorMask = noOpGLColorMask; - functions->fCompileShader = noOpGLCompileShader; - functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; - functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; - functions->fCreateProgram = nullGLCreateProgram; - functions->fCreateShader = nullGLCreateShader; - functions->fCullFace = noOpGLCullFace; - functions->fDeleteBuffers = nullGLDeleteBuffers; - functions->fDeleteProgram = nullGLDelete; - functions->fDeleteQueries = noOpGLDeleteIds; - functions->fDeleteShader = nullGLDelete; - functions->fDeleteTextures = noOpGLDeleteIds; - functions->fDeleteVertexArrays = noOpGLDeleteIds; - functions->fDepthMask = noOpGLDepthMask; - functions->fDisable = noOpGLDisable; - functions->fDisableClientState = noOpGLDisableClientState; - functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; - functions->fDrawArrays = noOpGLDrawArrays; - functions->fDrawBuffer = noOpGLDrawBuffer; - functions->fDrawBuffers = noOpGLDrawBuffers; - functions->fDrawElements = noOpGLDrawElements; - functions->fEnable = noOpGLEnable; - functions->fEnableClientState = noOpGLEnableClientState; - functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; - functions->fEndQuery = noOpGLEndQuery; - functions->fFinish = noOpGLFinish; - functions->fFlush = noOpGLFlush; - functions->fFrontFace = noOpGLFrontFace; - functions->fGenBuffers = nullGLGenBuffers; - functions->fGenerateMipmap = nullGLGenerateMipmap; - functions->fGenQueries = noOpGLGenIds; - functions->fGenTextures = noOpGLGenIds; - functions->fGenVertexArrays = noOpGLGenIds; - functions->fGetBufferParameteriv = nullGLGetBufferParameteriv; - functions->fGetError = noOpGLGetError; - functions->fGetIntegerv = noOpGLGetIntegerv; - functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; - functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; - functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; - functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; - functions->fGetQueryiv = noOpGLGetQueryiv; - functions->fGetProgramInfoLog = noOpGLGetInfoLog; - functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; - functions->fGetShaderInfoLog = noOpGLGetInfoLog; - functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; - functions->fGetString = noOpGLGetString; - functions->fGetStringi = noOpGLGetStringi; - functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; - functions->fGetUniformLocation = noOpGLGetUniformLocation; - functions->fLoadIdentity = noOpGLLoadIdentity; - functions->fLoadMatrixf = noOpGLLoadMatrixf; - functions->fLineWidth = noOpGLLineWidth; - functions->fLinkProgram = noOpGLLinkProgram; - functions->fMatrixMode = noOpGLMatrixMode; - functions->fPixelStorei = nullGLPixelStorei; - functions->fQueryCounter = noOpGLQueryCounter; - functions->fReadBuffer = noOpGLReadBuffer; - functions->fReadPixels = nullGLReadPixels; - functions->fScissor = noOpGLScissor; - functions->fShaderSource = noOpGLShaderSource; - functions->fStencilFunc = noOpGLStencilFunc; - functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; - functions->fStencilMask = noOpGLStencilMask; - functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; - functions->fStencilOp = noOpGLStencilOp; - functions->fStencilOpSeparate = noOpGLStencilOpSeparate; - functions->fTexGenf = noOpGLTexGenf; - functions->fTexGenfv = noOpGLTexGenfv; - functions->fTexGeni = noOpGLTexGeni; - functions->fTexImage2D = noOpGLTexImage2D; - functions->fTexParameteri = noOpGLTexParameteri; - functions->fTexParameteriv = noOpGLTexParameteriv; - functions->fTexSubImage2D = noOpGLTexSubImage2D; - functions->fTexStorage2D = noOpGLTexStorage2D; - functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; - functions->fUniform1f = noOpGLUniform1f; - functions->fUniform1i = noOpGLUniform1i; - functions->fUniform1fv = noOpGLUniform1fv; - functions->fUniform1iv = noOpGLUniform1iv; - functions->fUniform2f = noOpGLUniform2f; - functions->fUniform2i = noOpGLUniform2i; - functions->fUniform2fv = noOpGLUniform2fv; - functions->fUniform2iv = noOpGLUniform2iv; - functions->fUniform3f = noOpGLUniform3f; - functions->fUniform3i = noOpGLUniform3i; - functions->fUniform3fv = noOpGLUniform3fv; - functions->fUniform3iv = noOpGLUniform3iv; - functions->fUniform4f = noOpGLUniform4f; - functions->fUniform4i = noOpGLUniform4i; - functions->fUniform4fv = noOpGLUniform4fv; - functions->fUniform4iv = noOpGLUniform4iv; - functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; - functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; - functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; - functions->fUseProgram = nullGLUseProgram; - functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; - functions->fVertexAttribPointer = noOpGLVertexAttribPointer; - functions->fVertexPointer = noOpGLVertexPointer; - functions->fViewport = nullGLViewport; - functions->fBindFramebuffer = nullGLBindFramebuffer; - functions->fBindRenderbuffer = nullGLBindRenderbuffer; - functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; - functions->fDeleteFramebuffers = nullGLDeleteFramebuffers; - functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers; - functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer; - functions->fFramebufferTexture2D = nullGLFramebufferTexture2D; - functions->fGenFramebuffers = noOpGLGenIds; - functions->fGenRenderbuffers = noOpGLGenIds; - functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttachmentParameteriv; - functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; - functions->fRenderbufferStorage = noOpGLRenderbufferStorage; - functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultisample; - functions->fBlitFramebuffer = noOpGLBlitFramebuffer; - functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuffer; - functions->fMapBuffer = nullGLMapBuffer; - functions->fUnmapBuffer = nullGLUnmapBuffer; - functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; - } - glInterface.get()->ref(); - return glInterface.get(); + GrGLInterface::Functions* functions = &interface->fFunctions; + functions->fActiveTexture = nullGLActiveTexture; + functions->fAttachShader = nullGLAttachShader; + functions->fBeginQuery = nullGLBeginQuery; + functions->fBindAttribLocation = nullGLBindAttribLocation; + functions->fBindBuffer = nullGLBindBuffer; + functions->fBindFragDataLocation = noOpGLBindFragDataLocation; + functions->fBindTexture = nullGLBindTexture; + functions->fBindVertexArray = nullGLBindVertexArray; + functions->fBlendColor = noOpGLBlendColor; + functions->fBlendFunc = noOpGLBlendFunc; + functions->fBufferData = nullGLBufferData; + functions->fBufferSubData = noOpGLBufferSubData; + functions->fClear = noOpGLClear; + functions->fClearColor = noOpGLClearColor; + functions->fClearStencil = noOpGLClearStencil; + functions->fColorMask = noOpGLColorMask; + functions->fCompileShader = noOpGLCompileShader; + functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; + functions->fCopyTexSubImage2D = noOpGLCopyTexSubImage2D; + functions->fCreateProgram = nullGLCreateProgram; + functions->fCreateShader = nullGLCreateShader; + functions->fCullFace = noOpGLCullFace; + functions->fDeleteBuffers = nullGLDeleteBuffers; + functions->fDeleteProgram = nullGLDelete; + functions->fDeleteQueries = noOpGLDeleteIds; + functions->fDeleteShader = nullGLDelete; + functions->fDeleteTextures = noOpGLDeleteIds; + functions->fDeleteVertexArrays = noOpGLDeleteIds; + functions->fDepthMask = noOpGLDepthMask; + functions->fDisable = noOpGLDisable; + functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; + functions->fDrawArrays = noOpGLDrawArrays; + functions->fDrawBuffer = noOpGLDrawBuffer; + functions->fDrawBuffers = noOpGLDrawBuffers; + functions->fDrawElements = noOpGLDrawElements; + functions->fEnable = noOpGLEnable; + functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; + functions->fEndQuery = noOpGLEndQuery; + functions->fFinish = noOpGLFinish; + functions->fFlush = noOpGLFlush; + functions->fFrontFace = noOpGLFrontFace; + functions->fGenBuffers = nullGLGenBuffers; + functions->fGenerateMipmap = nullGLGenerateMipmap; + functions->fGenQueries = noOpGLGenIds; + functions->fGenTextures = noOpGLGenIds; + functions->fGenVertexArrays = noOpGLGenIds; + functions->fGetBufferParameteriv = nullGLGetBufferParameteriv; + functions->fGetError = noOpGLGetError; + functions->fGetIntegerv = noOpGLGetIntegerv; + functions->fGetQueryObjecti64v = noOpGLGetQueryObjecti64v; + functions->fGetQueryObjectiv = noOpGLGetQueryObjectiv; + functions->fGetQueryObjectui64v = noOpGLGetQueryObjectui64v; + functions->fGetQueryObjectuiv = noOpGLGetQueryObjectuiv; + functions->fGetQueryiv = noOpGLGetQueryiv; + functions->fGetProgramInfoLog = noOpGLGetInfoLog; + functions->fGetProgramiv = noOpGLGetShaderOrProgramiv; + functions->fGetShaderInfoLog = noOpGLGetInfoLog; + functions->fGetShaderiv = noOpGLGetShaderOrProgramiv; + functions->fGetString = noOpGLGetString; + functions->fGetStringi = noOpGLGetStringi; + functions->fGetTexLevelParameteriv = noOpGLGetTexLevelParameteriv; + functions->fGetUniformLocation = noOpGLGetUniformLocation; + functions->fInsertEventMarker = noOpGLInsertEventMarker; + functions->fLoadIdentity = noOpGLLoadIdentity; + functions->fLoadMatrixf = noOpGLLoadMatrixf; + functions->fLineWidth = noOpGLLineWidth; + functions->fLinkProgram = noOpGLLinkProgram; + functions->fMatrixMode = noOpGLMatrixMode; + functions->fPixelStorei = nullGLPixelStorei; + functions->fPopGroupMarker = noOpGLPopGroupMarker; + functions->fPushGroupMarker = noOpGLPushGroupMarker; + functions->fQueryCounter = noOpGLQueryCounter; + functions->fReadBuffer = noOpGLReadBuffer; + functions->fReadPixels = nullGLReadPixels; + functions->fScissor = noOpGLScissor; + functions->fShaderSource = noOpGLShaderSource; + functions->fStencilFunc = noOpGLStencilFunc; + functions->fStencilFuncSeparate = noOpGLStencilFuncSeparate; + functions->fStencilMask = noOpGLStencilMask; + functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; + functions->fStencilOp = noOpGLStencilOp; + functions->fStencilOpSeparate = noOpGLStencilOpSeparate; + functions->fTexGenfv = noOpGLTexGenfv; + functions->fTexGeni = noOpGLTexGeni; + functions->fTexImage2D = noOpGLTexImage2D; + functions->fTexParameteri = noOpGLTexParameteri; + functions->fTexParameteriv = noOpGLTexParameteriv; + functions->fTexSubImage2D = noOpGLTexSubImage2D; + functions->fTexStorage2D = noOpGLTexStorage2D; + functions->fDiscardFramebuffer = noOpGLDiscardFramebuffer; + functions->fUniform1f = noOpGLUniform1f; + functions->fUniform1i = noOpGLUniform1i; + functions->fUniform1fv = noOpGLUniform1fv; + functions->fUniform1iv = noOpGLUniform1iv; + functions->fUniform2f = noOpGLUniform2f; + functions->fUniform2i = noOpGLUniform2i; + functions->fUniform2fv = noOpGLUniform2fv; + functions->fUniform2iv = noOpGLUniform2iv; + functions->fUniform3f = noOpGLUniform3f; + functions->fUniform3i = noOpGLUniform3i; + functions->fUniform3fv = noOpGLUniform3fv; + functions->fUniform3iv = noOpGLUniform3iv; + functions->fUniform4f = noOpGLUniform4f; + functions->fUniform4i = noOpGLUniform4i; + functions->fUniform4fv = noOpGLUniform4fv; + functions->fUniform4iv = noOpGLUniform4iv; + functions->fUniformMatrix2fv = noOpGLUniformMatrix2fv; + functions->fUniformMatrix3fv = noOpGLUniformMatrix3fv; + functions->fUniformMatrix4fv = noOpGLUniformMatrix4fv; + functions->fUseProgram = nullGLUseProgram; + functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; + functions->fVertexAttribPointer = noOpGLVertexAttribPointer; + functions->fViewport = nullGLViewport; + functions->fBindFramebuffer = nullGLBindFramebuffer; + functions->fBindRenderbuffer = nullGLBindRenderbuffer; + functions->fCheckFramebufferStatus = noOpGLCheckFramebufferStatus; + functions->fDeleteFramebuffers = nullGLDeleteFramebuffers; + functions->fDeleteRenderbuffers = nullGLDeleteRenderbuffers; + functions->fFramebufferRenderbuffer = nullGLFramebufferRenderbuffer; + functions->fFramebufferTexture2D = nullGLFramebufferTexture2D; + functions->fGenFramebuffers = noOpGLGenIds; + functions->fGenRenderbuffers = noOpGLGenIds; + functions->fGetFramebufferAttachmentParameteriv = noOpGLGetFramebufferAttachmentParameteriv; + functions->fGetRenderbufferParameteriv = noOpGLGetRenderbufferParameteriv; + functions->fRenderbufferStorage = noOpGLRenderbufferStorage; + functions->fRenderbufferStorageMultisample = noOpGLRenderbufferStorageMultisample; + functions->fBlitFramebuffer = noOpGLBlitFramebuffer; + functions->fResolveMultisampleFramebuffer = noOpGLResolveMultisampleFramebuffer; + functions->fMapBuffer = nullGLMapBuffer; + functions->fUnmapBuffer = nullGLUnmapBuffer; + functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; + + interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi, + functions->fGetIntegerv); + return interface; } diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLExtensions.cpp b/gfx/skia/trunk/src/gpu/gl/GrGLExtensions.cpp index 33273e5f6511..6d1b04d2cc6c 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLExtensions.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGLExtensions.cpp @@ -120,6 +120,17 @@ bool GrGLExtensions::remove(const char ext[]) { } } +void GrGLExtensions::add(const char ext[]) { + int idx = find_string(*fStrings, ext); + if (idx < 0) { + // This is not the most effecient approach since we end up doing a full sort of the + // extensions after the add + fStrings->push_back().set(ext); + SkTLessFunctionToFunctorAdaptor cmp; + SkTQSort(&fStrings->front(), &fStrings->back(), cmp); + } +} + void GrGLExtensions::print(const char* sep) const { if (NULL == sep) { sep = " "; diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLInterface.cpp b/gfx/skia/trunk/src/gpu/gl/GrGLInterface.cpp index f7b0a53c20d5..7cb6239a8554 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLInterface.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGLInterface.cpp @@ -18,252 +18,82 @@ void GrGLDefaultInterfaceCallback(const GrGLInterface*) {} } #endif +const GrGLInterface* GrGLInterfaceAddTestDebugMarker(const GrGLInterface* interface, + GrGLInsertEventMarkerProc insertEventMarkerFn, + GrGLPushGroupMarkerProc pushGroupMarkerFn, + GrGLPopGroupMarkerProc popGroupMarkerFn) { + GrGLInterface* newInterface = GrGLInterface::NewClone(interface); + + if (!newInterface->fExtensions.has("GL_EXT_debug_marker")) { + newInterface->fExtensions.add("GL_EXT_debug_marker"); + } + + newInterface->fFunctions.fInsertEventMarker = insertEventMarkerFn; + newInterface->fFunctions.fPushGroupMarker = pushGroupMarkerFn; + newInterface->fFunctions.fPopGroupMarker = popGroupMarkerFn; + + return newInterface; +} + const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface) { GrGLInterface* newInterface = GrGLInterface::NewClone(interface); newInterface->fExtensions.remove("GL_NV_path_rendering"); - newInterface->fPathCommands = NULL; - newInterface->fPathCoords = NULL; - newInterface->fPathSubCommands = NULL; - newInterface->fPathSubCoords = NULL; - newInterface->fPathString = NULL; - newInterface->fPathGlyphs = NULL; - newInterface->fPathGlyphRange = NULL; - newInterface->fWeightPaths = NULL; - newInterface->fCopyPath = NULL; - newInterface->fInterpolatePaths = NULL; - newInterface->fTransformPath = NULL; - newInterface->fPathParameteriv = NULL; - newInterface->fPathParameteri = NULL; - newInterface->fPathParameterfv = NULL; - newInterface->fPathParameterf = NULL; - newInterface->fPathDashArray = NULL; - newInterface->fGenPaths = NULL; - newInterface->fDeletePaths = NULL; - newInterface->fIsPath = NULL; - newInterface->fPathStencilFunc = NULL; - newInterface->fPathStencilDepthOffset = NULL; - newInterface->fStencilFillPath = NULL; - newInterface->fStencilStrokePath = NULL; - newInterface->fStencilFillPathInstanced = NULL; - newInterface->fStencilStrokePathInstanced = NULL; - newInterface->fPathCoverDepthFunc = NULL; - newInterface->fPathColorGen = NULL; - newInterface->fPathTexGen = NULL; - newInterface->fPathFogGen = NULL; - newInterface->fCoverFillPath = NULL; - newInterface->fCoverStrokePath = NULL; - newInterface->fCoverFillPathInstanced = NULL; - newInterface->fCoverStrokePathInstanced = NULL; - newInterface->fGetPathParameteriv = NULL; - newInterface->fGetPathParameterfv = NULL; - newInterface->fGetPathCommands = NULL; - newInterface->fGetPathCoords = NULL; - newInterface->fGetPathDashArray = NULL; - newInterface->fGetPathMetrics = NULL; - newInterface->fGetPathMetricRange = NULL; - newInterface->fGetPathSpacing = NULL; - newInterface->fGetPathColorGeniv = NULL; - newInterface->fGetPathColorGenfv = NULL; - newInterface->fGetPathTexGeniv = NULL; - newInterface->fGetPathTexGenfv = NULL; - newInterface->fIsPointInFillPath = NULL; - newInterface->fIsPointInStrokePath = NULL; - newInterface->fGetPathLength = NULL; - newInterface->fPointAlongPath = NULL; + newInterface->fFunctions.fPathCommands = NULL; + newInterface->fFunctions.fPathCoords = NULL; + newInterface->fFunctions.fPathSubCommands = NULL; + newInterface->fFunctions.fPathSubCoords = NULL; + newInterface->fFunctions.fPathString = NULL; + newInterface->fFunctions.fPathGlyphs = NULL; + newInterface->fFunctions.fPathGlyphRange = NULL; + newInterface->fFunctions.fWeightPaths = NULL; + newInterface->fFunctions.fCopyPath = NULL; + newInterface->fFunctions.fInterpolatePaths = NULL; + newInterface->fFunctions.fTransformPath = NULL; + newInterface->fFunctions.fPathParameteriv = NULL; + newInterface->fFunctions.fPathParameteri = NULL; + newInterface->fFunctions.fPathParameterfv = NULL; + newInterface->fFunctions.fPathParameterf = NULL; + newInterface->fFunctions.fPathDashArray = NULL; + newInterface->fFunctions.fGenPaths = NULL; + newInterface->fFunctions.fDeletePaths = NULL; + newInterface->fFunctions.fIsPath = NULL; + newInterface->fFunctions.fPathStencilFunc = NULL; + newInterface->fFunctions.fPathStencilDepthOffset = NULL; + newInterface->fFunctions.fStencilFillPath = NULL; + newInterface->fFunctions.fStencilStrokePath = NULL; + newInterface->fFunctions.fStencilFillPathInstanced = NULL; + newInterface->fFunctions.fStencilStrokePathInstanced = NULL; + newInterface->fFunctions.fPathCoverDepthFunc = NULL; + newInterface->fFunctions.fPathColorGen = NULL; + newInterface->fFunctions.fPathTexGen = NULL; + newInterface->fFunctions.fPathFogGen = NULL; + newInterface->fFunctions.fCoverFillPath = NULL; + newInterface->fFunctions.fCoverStrokePath = NULL; + newInterface->fFunctions.fCoverFillPathInstanced = NULL; + newInterface->fFunctions.fCoverStrokePathInstanced = NULL; + newInterface->fFunctions.fGetPathParameteriv = NULL; + newInterface->fFunctions.fGetPathParameterfv = NULL; + newInterface->fFunctions.fGetPathCommands = NULL; + newInterface->fFunctions.fGetPathCoords = NULL; + newInterface->fFunctions.fGetPathDashArray = NULL; + newInterface->fFunctions.fGetPathMetrics = NULL; + newInterface->fFunctions.fGetPathMetricRange = NULL; + newInterface->fFunctions.fGetPathSpacing = NULL; + newInterface->fFunctions.fGetPathColorGeniv = NULL; + newInterface->fFunctions.fGetPathColorGenfv = NULL; + newInterface->fFunctions.fGetPathTexGeniv = NULL; + newInterface->fFunctions.fGetPathTexGenfv = NULL; + newInterface->fFunctions.fIsPointInFillPath = NULL; + newInterface->fFunctions.fIsPointInStrokePath = NULL; + newInterface->fFunctions.fGetPathLength = NULL; + newInterface->fFunctions.fPointAlongPath = NULL; return newInterface; } -GrGLInterface::GrGLInterface() - // TODO: Remove this madness ASAP. - : fActiveTexture(&fFunctions.fActiveTexture) - , fAttachShader(&fFunctions.fAttachShader) - , fBeginQuery(&fFunctions.fBeginQuery) - , fBindAttribLocation(&fFunctions.fBindAttribLocation) - , fBindBuffer(&fFunctions.fBindBuffer) - , fBindFragDataLocation(&fFunctions.fBindFragDataLocation) - , fBindFragDataLocationIndexed(&fFunctions.fBindFragDataLocationIndexed) - , fBindFramebuffer(&fFunctions.fBindFramebuffer) - , fBindRenderbuffer(&fFunctions.fBindRenderbuffer) - , fBindTexture(&fFunctions.fBindTexture) - , fBindVertexArray(&fFunctions.fBindVertexArray) - , fBlendColor(&fFunctions.fBlendColor) - , fBlendFunc(&fFunctions.fBlendFunc) - , fBlitFramebuffer(&fFunctions.fBlitFramebuffer) - , fBufferData(&fFunctions.fBufferData) - , fBufferSubData(&fFunctions.fBufferSubData) - , fCheckFramebufferStatus(&fFunctions.fCheckFramebufferStatus) - , fClear(&fFunctions.fClear) - , fClearColor(&fFunctions.fClearColor) - , fClearStencil(&fFunctions.fClearStencil) - , fClientActiveTexture(&fFunctions.fClientActiveTexture) - , fColorMask(&fFunctions.fColorMask) - , fCompileShader(&fFunctions.fCompileShader) - , fCompressedTexImage2D(&fFunctions.fCompressedTexImage2D) - , fCopyTexSubImage2D(&fFunctions.fCopyTexSubImage2D) - , fCreateProgram(&fFunctions.fCreateProgram) - , fCreateShader(&fFunctions.fCreateShader) - , fCullFace(&fFunctions.fCullFace) - , fDeleteBuffers(&fFunctions.fDeleteBuffers) - , fDeleteFramebuffers(&fFunctions.fDeleteFramebuffers) - , fDeleteProgram(&fFunctions.fDeleteProgram) - , fDeleteQueries(&fFunctions.fDeleteQueries) - , fDeleteRenderbuffers(&fFunctions.fDeleteRenderbuffers) - , fDeleteShader(&fFunctions.fDeleteShader) - , fDeleteTextures(&fFunctions.fDeleteTextures) - , fDeleteVertexArrays(&fFunctions.fDeleteVertexArrays) - , fDepthMask(&fFunctions.fDepthMask) - , fDisable(&fFunctions.fDisable) - , fDisableClientState(&fFunctions.fDisableClientState) - , fDisableVertexAttribArray(&fFunctions.fDisableVertexAttribArray) - , fDrawArrays(&fFunctions.fDrawArrays) - , fDrawBuffer(&fFunctions.fDrawBuffer) - , fDrawBuffers(&fFunctions.fDrawBuffers) - , fDrawElements(&fFunctions.fDrawElements) - , fEnable(&fFunctions.fEnable) - , fEnableClientState(&fFunctions.fEnableClientState) - , fEnableVertexAttribArray(&fFunctions.fEnableVertexAttribArray) - , fEndQuery(&fFunctions.fEndQuery) - , fFinish(&fFunctions.fFinish) - , fFlush(&fFunctions.fFlush) - , fFramebufferRenderbuffer(&fFunctions.fFramebufferRenderbuffer) - , fFramebufferTexture2D(&fFunctions.fFramebufferTexture2D) - , fFramebufferTexture2DMultisample(&fFunctions.fFramebufferTexture2DMultisample) - , fFrontFace(&fFunctions.fFrontFace) - , fGenBuffers(&fFunctions.fGenBuffers) - , fGenFramebuffers(&fFunctions.fGenFramebuffers) - , fGenerateMipmap(&fFunctions.fGenerateMipmap) - , fGenQueries(&fFunctions.fGenQueries) - , fGenRenderbuffers(&fFunctions.fGenRenderbuffers) - , fGenTextures(&fFunctions.fGenTextures) - , fGenVertexArrays(&fFunctions.fGenVertexArrays) - , fGetBufferParameteriv(&fFunctions.fGetBufferParameteriv) - , fGetError(&fFunctions.fGetError) - , fGetFramebufferAttachmentParameteriv(&fFunctions.fGetFramebufferAttachmentParameteriv) - , fGetIntegerv(&fFunctions.fGetIntegerv) - , fGetQueryObjecti64v(&fFunctions.fGetQueryObjecti64v) - , fGetQueryObjectiv(&fFunctions.fGetQueryObjectiv) - , fGetQueryObjectui64v(&fFunctions.fGetQueryObjectui64v) - , fGetQueryObjectuiv(&fFunctions.fGetQueryObjectuiv) - , fGetQueryiv(&fFunctions.fGetQueryiv) - , fGetProgramInfoLog(&fFunctions.fGetProgramInfoLog) - , fGetProgramiv(&fFunctions.fGetProgramiv) - , fGetRenderbufferParameteriv(&fFunctions.fGetRenderbufferParameteriv) - , fGetShaderInfoLog(&fFunctions.fGetShaderInfoLog) - , fGetShaderiv(&fFunctions.fGetShaderiv) - , fGetString(&fFunctions.fGetString) - , fGetStringi(&fFunctions.fGetStringi) - , fGetTexLevelParameteriv(&fFunctions.fGetTexLevelParameteriv) - , fGetUniformLocation(&fFunctions.fGetUniformLocation) - , fLineWidth(&fFunctions.fLineWidth) - , fLinkProgram(&fFunctions.fLinkProgram) - , fLoadIdentity(&fFunctions.fLoadIdentity) - , fLoadMatrixf(&fFunctions.fLoadMatrixf) - , fMapBuffer(&fFunctions.fMapBuffer) - , fMatrixMode(&fFunctions.fMatrixMode) - , fPixelStorei(&fFunctions.fPixelStorei) - , fQueryCounter(&fFunctions.fQueryCounter) - , fReadBuffer(&fFunctions.fReadBuffer) - , fReadPixels(&fFunctions.fReadPixels) - , fRenderbufferStorage(&fFunctions.fRenderbufferStorage) - , fRenderbufferStorageMultisampleES2EXT(&fFunctions.fRenderbufferStorageMultisampleES2EXT) - , fRenderbufferStorageMultisampleES2APPLE(&fFunctions.fRenderbufferStorageMultisampleES2APPLE) - , fRenderbufferStorageMultisample(&fFunctions.fRenderbufferStorageMultisample) - , fBindUniformLocation(&fFunctions.fBindUniformLocation) - , fResolveMultisampleFramebuffer(&fFunctions.fResolveMultisampleFramebuffer) - , fScissor(&fFunctions.fScissor) - , fShaderSource(&fFunctions.fShaderSource) - , fStencilFunc(&fFunctions.fStencilFunc) - , fStencilFuncSeparate(&fFunctions.fStencilFuncSeparate) - , fStencilMask(&fFunctions.fStencilMask) - , fStencilMaskSeparate(&fFunctions.fStencilMaskSeparate) - , fStencilOp(&fFunctions.fStencilOp) - , fStencilOpSeparate(&fFunctions.fStencilOpSeparate) - , fTexGenf(&fFunctions.fTexGenf) - , fTexGenfv(&fFunctions.fTexGenfv) - , fTexGeni(&fFunctions.fTexGeni) - , fTexImage2D(&fFunctions.fTexImage2D) - , fTexParameteri(&fFunctions.fTexParameteri) - , fTexParameteriv(&fFunctions.fTexParameteriv) - , fTexSubImage2D(&fFunctions.fTexSubImage2D) - , fTexStorage2D(&fFunctions.fTexStorage2D) - , fDiscardFramebuffer(&fFunctions.fDiscardFramebuffer) - , fUniform1f(&fFunctions.fUniform1f) - , fUniform1i(&fFunctions.fUniform1i) - , fUniform1fv(&fFunctions.fUniform1fv) - , fUniform1iv(&fFunctions.fUniform1iv) - , fUniform2f(&fFunctions.fUniform2f) - , fUniform2i(&fFunctions.fUniform2i) - , fUniform2fv(&fFunctions.fUniform2fv) - , fUniform2iv(&fFunctions.fUniform2iv) - , fUniform3f(&fFunctions.fUniform3f) - , fUniform3i(&fFunctions.fUniform3i) - , fUniform3fv(&fFunctions.fUniform3fv) - , fUniform3iv(&fFunctions.fUniform3iv) - , fUniform4f(&fFunctions.fUniform4f) - , fUniform4i(&fFunctions.fUniform4i) - , fUniform4fv(&fFunctions.fUniform4fv) - , fUniform4iv(&fFunctions.fUniform4iv) - , fUniformMatrix2fv(&fFunctions.fUniformMatrix2fv) - , fUniformMatrix3fv(&fFunctions.fUniformMatrix3fv) - , fUniformMatrix4fv(&fFunctions.fUniformMatrix4fv) - , fUnmapBuffer(&fFunctions.fUnmapBuffer) - , fUseProgram(&fFunctions.fUseProgram) - , fVertexAttrib4fv(&fFunctions.fVertexAttrib4fv) - , fVertexAttribPointer(&fFunctions.fVertexAttribPointer) - , fVertexPointer(&fFunctions.fVertexPointer) - , fViewport(&fFunctions.fViewport) - , fPathCommands(&fFunctions.fPathCommands) - , fPathCoords(&fFunctions.fPathCoords) - , fPathSubCommands(&fFunctions.fPathSubCommands) - , fPathSubCoords(&fFunctions.fPathSubCoords) - , fPathString(&fFunctions.fPathString) - , fPathGlyphs(&fFunctions.fPathGlyphs) - , fPathGlyphRange(&fFunctions.fPathGlyphRange) - , fWeightPaths(&fFunctions.fWeightPaths) - , fCopyPath(&fFunctions.fCopyPath) - , fInterpolatePaths(&fFunctions.fInterpolatePaths) - , fTransformPath(&fFunctions.fTransformPath) - , fPathParameteriv(&fFunctions.fPathParameteriv) - , fPathParameteri(&fFunctions.fPathParameteri) - , fPathParameterfv(&fFunctions.fPathParameterfv) - , fPathParameterf(&fFunctions.fPathParameterf) - , fPathDashArray(&fFunctions.fPathDashArray) - , fGenPaths(&fFunctions.fGenPaths) - , fDeletePaths(&fFunctions.fDeletePaths) - , fIsPath(&fFunctions.fIsPath) - , fPathStencilFunc(&fFunctions.fPathStencilFunc) - , fPathStencilDepthOffset(&fFunctions.fPathStencilDepthOffset) - , fStencilFillPath(&fFunctions.fStencilFillPath) - , fStencilStrokePath(&fFunctions.fStencilStrokePath) - , fStencilFillPathInstanced(&fFunctions.fStencilFillPathInstanced) - , fStencilStrokePathInstanced(&fFunctions.fStencilStrokePathInstanced) - , fPathCoverDepthFunc(&fFunctions.fPathCoverDepthFunc) - , fPathColorGen(&fFunctions.fPathColorGen) - , fPathTexGen(&fFunctions.fPathTexGen) - , fPathFogGen(&fFunctions.fPathFogGen) - , fCoverFillPath(&fFunctions.fCoverFillPath) - , fCoverStrokePath(&fFunctions.fCoverStrokePath) - , fCoverFillPathInstanced(&fFunctions.fCoverFillPathInstanced) - , fCoverStrokePathInstanced(&fFunctions.fCoverStrokePathInstanced) - , fGetPathParameteriv(&fFunctions.fGetPathParameteriv) - , fGetPathParameterfv(&fFunctions.fGetPathParameterfv) - , fGetPathCommands(&fFunctions.fGetPathCommands) - , fGetPathCoords(&fFunctions.fGetPathCoords) - , fGetPathDashArray(&fFunctions.fGetPathDashArray) - , fGetPathMetrics(&fFunctions.fGetPathMetrics) - , fGetPathMetricRange(&fFunctions.fGetPathMetricRange) - , fGetPathSpacing(&fFunctions.fGetPathSpacing) - , fGetPathColorGeniv(&fFunctions.fGetPathColorGeniv) - , fGetPathColorGenfv(&fFunctions.fGetPathColorGenfv) - , fGetPathTexGeniv(&fFunctions.fGetPathTexGeniv) - , fGetPathTexGenfv(&fFunctions.fGetPathTexGenfv) - , fIsPointInFillPath(&fFunctions.fIsPointInFillPath) - , fIsPointInStrokePath(&fFunctions.fIsPointInStrokePath) - , fGetPathLength(&fFunctions.fGetPathLength) - , fPointAlongPath(&fFunctions.fPointAlongPath) { +GrGLInterface::GrGLInterface() { fStandard = kNone_GrGLStandard; #if GR_GL_PER_GL_FUNC_CALLBACK @@ -292,14 +122,8 @@ bool GrGLInterface::validate() const { return false; } - // This const hackery is necessary because the factories in Chromium do not yet initialize - // fExtensions. if (!fExtensions.isInitialized()) { - GrGLExtensions* extensions = const_cast(&fExtensions); - if (!extensions->init(fStandard, fFunctions.fGetString, fFunctions.fGetStringi, - fFunctions.fGetIntegerv)) { - return false; - } + return false; } // functions that are always required @@ -463,16 +287,11 @@ bool GrGLInterface::validate() const { } } if (!isCoreProfile) { - if (NULL == fFunctions.fClientActiveTexture || - NULL == fFunctions.fDisableClientState || - NULL == fFunctions.fEnableClientState || - NULL == fFunctions.fLoadIdentity || + if (NULL == fFunctions.fLoadIdentity || NULL == fFunctions.fLoadMatrixf || NULL == fFunctions.fMatrixMode || - NULL == fFunctions.fTexGenf || NULL == fFunctions.fTexGenfv || - NULL == fFunctions.fTexGeni || - NULL == fFunctions.fVertexPointer) { + NULL == fFunctions.fTexGeni) { return false; } } @@ -655,5 +474,15 @@ bool GrGLInterface::validate() const { } } } + +#if 0 + if (fExtensions.has("GL_EXT_debug_marker")) { + if (NULL == fFunctions.fInsertEventMarker || + NULL == fFunctions.fPushGroupMarker || + NULL == fFunctions.fPopGroupMarker) { + return false; + } + } +#endif return true; } diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.cpp b/gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.cpp index 0641af85d736..65729c962db8 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.cpp @@ -119,9 +119,6 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDepthMask(GrGLboolean flag) { GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDisable(GrGLenum cap) { } -GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDisableClientState(GrGLenum) { -} - GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDisableVertexAttribArray(GrGLuint index) { } @@ -146,9 +143,6 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDrawElements(GrGLenum mode, GrGLvoid GR_GL_FUNCTION_TYPE noOpGLEnable(GrGLenum cap) { } -GrGLvoid GR_GL_FUNCTION_TYPE noOpGLEnableClientState(GrGLenum cap) { -} - GrGLvoid GR_GL_FUNCTION_TYPE noOpGLEnableVertexAttribArray(GrGLuint index) { } @@ -385,9 +379,6 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttribPointer(GrGLuint indx, const GrGLvoid* ptr) { } -GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexPointer(GrGLint, GrGLenum, GrGLsizei, const GrGLvoid*) { -} - GrGLvoid GR_GL_FUNCTION_TYPE noOpGLViewport(GrGLint x, GrGLint y, GrGLsizei width, @@ -656,3 +647,10 @@ GrGLint GR_GL_FUNCTION_TYPE noOpGLGetUniformLocation(GrGLuint program, const cha static int gUniLocation = 0; return ++gUniLocation; } + +GrGLvoid GR_GL_FUNCTION_TYPE noOpGLInsertEventMarker(GrGLsizei length, const char* marker) { +} +GrGLvoid GR_GL_FUNCTION_TYPE noOpGLPushGroupMarker(GrGLsizei length , const char* marker) { +} +GrGLvoid GR_GL_FUNCTION_TYPE noOpGLPopGroupMarker() { +} diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.h b/gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.h index 8fe9b44ea2ef..b5b681fec3d6 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.h +++ b/gfx/skia/trunk/src/gpu/gl/GrGLNoOpInterface.h @@ -70,8 +70,6 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDepthMask(GrGLboolean flag); GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDisable(GrGLenum cap); -GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDisableClientState(GrGLenum); - GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDisableVertexAttribArray(GrGLuint index); GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDrawArrays(GrGLenum mode, GrGLint first, GrGLsizei count); @@ -88,8 +86,6 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLDrawElements(GrGLenum mode, GrGLvoid GR_GL_FUNCTION_TYPE noOpGLEnable(GrGLenum cap); -GrGLvoid GR_GL_FUNCTION_TYPE noOpGLEnableClientState(GrGLenum cap); - GrGLvoid GR_GL_FUNCTION_TYPE noOpGLEnableVertexAttribArray(GrGLuint index); GrGLvoid GR_GL_FUNCTION_TYPE noOpGLEndQuery(GrGLenum target); @@ -277,8 +273,6 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexAttribPointer(GrGLuint indx, GrGLsizei stride, const GrGLvoid* ptr); -GrGLvoid GR_GL_FUNCTION_TYPE noOpGLVertexPointer(GrGLint, GrGLenum, GrGLsizei, const GrGLvoid*); - GrGLvoid GR_GL_FUNCTION_TYPE noOpGLViewport(GrGLint x, GrGLint y, GrGLsizei width, @@ -375,4 +369,8 @@ GrGLvoid GR_GL_FUNCTION_TYPE noOpGLGetTexLevelParameteriv(GrGLenum target, GrGLint GR_GL_FUNCTION_TYPE noOpGLGetUniformLocation(GrGLuint program, const char* name); +GrGLvoid GR_GL_FUNCTION_TYPE noOpGLInsertEventMarker(GrGLsizei length, const char* marker); +GrGLvoid GR_GL_FUNCTION_TYPE noOpGLPushGroupMarker(GrGLsizei length , const char* marker); +GrGLvoid GR_GL_FUNCTION_TYPE noOpGLPopGroupMarker(); + #endif diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLShaderBuilder.cpp b/gfx/skia/trunk/src/gpu/gl/GrGLShaderBuilder.cpp index 264bc3b0050e..94568e034ad3 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGLShaderBuilder.cpp @@ -404,14 +404,11 @@ const char* GrGLShaderBuilder::fragmentPosition() { return ""; } } + // We only declare "gl_FragCoord" when we're in the case where we want to use layout qualifiers + // to reverse y. Otherwise it isn't necessary and whether the "in" qualifier appears in the + // declaration varies in earlier GLSL specs. So it is simpler to omit it. if (fTopLeftFragPosRead) { - if (!fSetupFragPosition) { - fFSInputs.push_back().set(kVec4f_GrSLType, - GrGLShaderVar::kIn_TypeModifier, - "gl_FragCoord", - GrGLShaderVar::kDefault_Precision); - fSetupFragPosition = true; - } + fSetupFragPosition = true; return "gl_FragCoord"; } else if (fGpu->glCaps().fragCoordConventionsSupport()) { if (!fSetupFragPosition) { diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLUtil.cpp b/gfx/skia/trunk/src/gpu/gl/GrGLUtil.cpp index 87e2f83a289c..a479523b65b8 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLUtil.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGLUtil.cpp @@ -213,7 +213,7 @@ GrGLVendor GrGLGetVendorFromString(const char* vendorString) { if (0 == strcmp(vendorString, "Imagination Technologies")) { return kImagination_GrGLVendor; } - if (0 == strcmp(vendorString, "Intel")) { + if (0 == strncmp(vendorString, "Intel ", 6) || 0 == strcmp(vendorString, "Intel")) { return kIntel_GrGLVendor; } if (0 == strcmp(vendorString, "Qualcomm")) { diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.cpp b/gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.cpp index 605ec3327b3a..abd337a8060b 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.cpp @@ -49,39 +49,7 @@ void GrGLAttribArrayState::set(const GrGpuGL* gpu, } } -void GrGLAttribArrayState::setFixedFunctionVertexArray(const GrGpuGL* gpu, - GrGLVertexBuffer* buffer, - GrGLint size, - GrGLenum type, - GrGLsizei stride, - GrGLvoid* offset) { - SkASSERT(gpu->glCaps().fixedFunctionSupport()); - AttribArrayState* array = &fFixedFunctionVertexArray; - if (!array->fEnableIsValid || !array->fEnabled) { - GR_GL_CALL(gpu->glInterface(), EnableClientState(GR_GL_VERTEX_ARRAY)); - array->fEnableIsValid = true; - array->fEnabled = true; - } - if (!array->fAttribPointerIsValid || - array->fVertexBufferID != buffer->bufferID() || - array->fSize != size || - array->fStride != stride || - array->fOffset != offset) { - - buffer->bind(); - GR_GL_CALL(gpu->glInterface(), VertexPointer(size, - type, - stride, - offset)); - array->fAttribPointerIsValid = true; - array->fVertexBufferID = buffer->bufferID(); - array->fSize = size; - array->fStride = stride; - array->fOffset = offset; - } -} - -void GrGLAttribArrayState::disableUnusedArrays(const GrGpuGL* gpu, uint64_t usedMask, bool usingFFVertexArray) { +void GrGLAttribArrayState::disableUnusedArrays(const GrGpuGL* gpu, uint64_t usedMask) { int count = fAttribArrayStates.count(); for (int i = 0; i < count; ++i) { if (!(usedMask & 0x1)) { @@ -96,35 +64,6 @@ void GrGLAttribArrayState::disableUnusedArrays(const GrGpuGL* gpu, uint64_t used // if the count is greater than 64 then this will become 0 and we will disable arrays 64+. usedMask >>= 1; } - - // Deal with fixed-function vertex arrays. - if (gpu->glCaps().fixedFunctionSupport()) { - if (!usingFFVertexArray) { - if (!fFixedFunctionVertexArray.fEnableIsValid || fFixedFunctionVertexArray.fEnabled) { - GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_VERTEX_ARRAY)); - fFixedFunctionVertexArray.fEnableIsValid = true; - fFixedFunctionVertexArray.fEnabled = false; - } - } else { - SkASSERT(fFixedFunctionVertexArray.fEnableIsValid && fFixedFunctionVertexArray.fEnabled); - } - // When we use fixed function vertex processing we always use the vertex array and none of - // the other arrays. - if (!fUnusedFixedFunctionArraysDisabled) { - GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_NORMAL_ARRAY)); - GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_COLOR_ARRAY)); - GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_SECONDARY_COLOR_ARRAY)); - GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_INDEX_ARRAY)); - GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_EDGE_FLAG_ARRAY)); - for (int i = 0; i < gpu->glCaps().maxFixedFunctionTextureCoords(); ++i) { - GR_GL_CALL(gpu->glInterface(), ClientActiveTexture(GR_GL_TEXTURE0 + i)); - GR_GL_CALL(gpu->glInterface(), DisableClientState(GR_GL_TEXTURE_COORD_ARRAY)); - } - fUnusedFixedFunctionArraysDisabled = true; - } - } else { - SkASSERT(!usingFFVertexArray); - } } /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.h b/gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.h index 5cc7b5fd5bec..8a61f1a2c605 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.h +++ b/gfx/skia/trunk/src/gpu/gl/GrGLVertexArray.h @@ -51,9 +51,6 @@ class GrGLAttribArrayState { public: explicit GrGLAttribArrayState(int arrayCount = 0) { this->resize(arrayCount); - // glVertexPointer doesn't have a normalization param. - fFixedFunctionVertexArray.fNormalized = false; - fUnusedFixedFunctionArraysDisabled = false; } void resize(int newCount) { @@ -77,26 +74,17 @@ public: GrGLsizei stride, GrGLvoid* offset); - void setFixedFunctionVertexArray(const GrGpuGL*, - GrGLVertexBuffer*, - GrGLint size, - GrGLenum type, - GrGLsizei stride, - GrGLvoid* offset); - /** * This function disables vertex attribs not present in the mask. It is assumed that the * GrGLAttribArrayState is tracking the state of the currently bound vertex array object. */ - void disableUnusedArrays(const GrGpuGL*, uint64_t usedAttribArrayMask, bool usingFFVertexArray); + void disableUnusedArrays(const GrGpuGL*, uint64_t usedAttribArrayMask); void invalidate() { int count = fAttribArrayStates.count(); for (int i = 0; i < count; ++i) { fAttribArrayStates[i].invalidate(); } - fFixedFunctionVertexArray.invalidate(); - fUnusedFixedFunctionArraysDisabled = false; } void notifyVertexBufferDelete(GrGLuint id) { @@ -107,10 +95,6 @@ public: fAttribArrayStates[i].invalidate(); } } - if (fFixedFunctionVertexArray.fAttribPointerIsValid && - id == fFixedFunctionVertexArray.fVertexBufferID) { - fFixedFunctionVertexArray.invalidate(); - } } /** @@ -140,13 +124,6 @@ private: }; SkSTArray<16, AttribArrayState, true> fAttribArrayStates; - - // Tracks the array specified by glVertexPointer. - AttribArrayState fFixedFunctionVertexArray; - - // Tracks whether we've disabled the other fixed function arrays that we don't - // use (e.g. glNormalPointer). - bool fUnusedFixedFunctionArraysDisabled; }; /** diff --git a/gfx/skia/trunk/src/gpu/gl/GrGpuGL.cpp b/gfx/skia/trunk/src/gpu/gl/GrGpuGL.cpp index ec9c8d6fab7e..5fb268863b25 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGpuGL.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGpuGL.cpp @@ -117,14 +117,12 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) , fGLContext(ctx) { SkASSERT(ctx.isInitialized()); - fCaps.reset(SkRef(ctx.caps())); fHWBoundTextures.reset(this->glCaps().maxFragmentTextureUnits()); fHWTexGenSettings.reset(this->glCaps().maxFixedFunctionTextureCoords()); GrGLClearErr(fGLContext.interface()); - if (gPrintStartupSpew) { const GrGLubyte* vendor; const GrGLubyte* renderer; @@ -2663,6 +2661,23 @@ bool GrGpuGL::onCanCopySurface(GrSurface* dst, return INHERITED::onCanCopySurface(dst, src, srcRect, dstPoint); } +void GrGpuGL::onInstantGpuTraceEvent(const char* marker) { + if (this->caps()->gpuTracingSupport()) { + // GL_CALL(InsertEventMarker(0, marker)); + } +} + +void GrGpuGL::onPushGpuTraceEvent(const char* marker) { + if (this->caps()->gpuTracingSupport()) { + // GL_CALL(PushGroupMarker(0, marker)); + } +} + +void GrGpuGL::onPopGpuTraceEvent() { + if (this->caps()->gpuTracingSupport()) { + // GL_CALL(PopGroupMarker()); + } +} /////////////////////////////////////////////////////////////////////////////// diff --git a/gfx/skia/trunk/src/gpu/gl/GrGpuGL.h b/gfx/skia/trunk/src/gpu/gl/GrGpuGL.h index edd58c44bc86..05802550af85 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGpuGL.h +++ b/gfx/skia/trunk/src/gpu/gl/GrGpuGL.h @@ -162,6 +162,12 @@ private: bool insideClip) SK_OVERRIDE; virtual bool flushGraphicsState(DrawType, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; + // GrDrawTarget ovverides + virtual void onInstantGpuTraceEvent(const char* marker) SK_OVERRIDE; + virtual void onPushGpuTraceEvent(const char* marker) SK_OVERRIDE; + virtual void onPopGpuTraceEvent() SK_OVERRIDE; + + // binds texture unit in GL void setTextureUnit(int unitIdx); diff --git a/gfx/skia/trunk/src/gpu/gl/GrGpuGL_program.cpp b/gfx/skia/trunk/src/gpu/gl/GrGpuGL_program.cpp index a3beab1a5999..50ecf0b3322d 100644 --- a/gfx/skia/trunk/src/gpu/gl/GrGpuGL_program.cpp +++ b/gfx/skia/trunk/src/gpu/gl/GrGpuGL_program.cpp @@ -344,22 +344,29 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) { if (!fCurrentProgram->hasVertexShader()) { int posIdx = this->getDrawState().positionAttributeIndex(); - const GrVertexAttrib* vertexArray = this->getDrawState().getVertexAttribs() + posIdx; - GrVertexAttribType vertexArrayType = vertexArray->fType; - SkASSERT(!GrGLAttribTypeToLayout(vertexArrayType).fNormalized); - SkASSERT(GrGLAttribTypeToLayout(vertexArrayType).fCount == 2); - attribState->setFixedFunctionVertexArray(this, - vbuf, - 2, - GrGLAttribTypeToLayout(vertexArrayType).fType, - stride, - reinterpret_cast( - vertexOffsetInBytes + vertexArray->fOffset)); - attribState->disableUnusedArrays(this, 0, true); + const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs() + posIdx; + GrVertexAttribType attribType = vertexAttrib->fType; + SkASSERT(!GrGLAttribTypeToLayout(attribType).fNormalized); + SkASSERT(GrGLAttribTypeToLayout(attribType).fCount == 2); + + // Attrib at location 0 is defined to be bound to vertex in fixed-function pipe. Asserts + // above should make sure position attribute goes to location 0 when below code is executed. + + attribState->set(this, + 0, + vbuf, + GrGLAttribTypeToLayout(attribType).fCount, + GrGLAttribTypeToLayout(attribType).fType, + GrGLAttribTypeToLayout(attribType).fNormalized, + stride, + reinterpret_cast( + vertexOffsetInBytes + vertexAttrib->fOffset)); + attribState->disableUnusedArrays(this, 1); } else { + int vertexAttribCount = this->getDrawState().getVertexAttribCount(); uint32_t usedAttribArraysMask = 0; const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs(); - int vertexAttribCount = this->getDrawState().getVertexAttribCount(); + for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount; ++vertexAttribIndex, ++vertexAttrib) { @@ -373,9 +380,8 @@ void GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) { GrGLAttribTypeToLayout(attribType).fNormalized, stride, reinterpret_cast( - vertexOffsetInBytes + vertexAttrib->fOffset)); + vertexOffsetInBytes + vertexAttrib->fOffset)); } - - attribState->disableUnusedArrays(this, usedAttribArraysMask, false); + attribState->disableUnusedArrays(this, usedAttribArraysMask); } } diff --git a/gfx/skia/trunk/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp b/gfx/skia/trunk/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp index 1f911653043a..eacd2a3647b9 100644 --- a/gfx/skia/trunk/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp +++ b/gfx/skia/trunk/src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp @@ -190,6 +190,12 @@ static GrGLInterface* create_es_interface(GrGLVersion version, functions->fUnmapBuffer = (GrGLUnmapBufferProc) eglGetProcAddress("glUnmapBufferOES"); #endif + if (extensions.has("GL_EXT_debug_marker")) { + functions->fInsertEventMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glInsertEventMarkerEXT"); + functions->fPushGroupMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glPushGroupMarkerEXT"); + functions->fPopGroupMarker = (GrGLPopGroupMarkerProc) eglGetProcAddress("glPopGropuMarkerEXT"); + } + return interface; } @@ -225,7 +231,6 @@ static GrGLInterface* create_desktop_interface(GrGLVersion version, functions->fClear = (GrGLClearProc) eglGetProcAddress("glClear"); functions->fClearColor = (GrGLClearColorProc) eglGetProcAddress("glClearColor"); functions->fClearStencil = (GrGLClearStencilProc) eglGetProcAddress("glClearStencil"); - functions->fClientActiveTexture = (GrGLClientActiveTextureProc) eglGetProcAddress("glClientActiveTexture"); functions->fColorMask = (GrGLColorMaskProc) eglGetProcAddress("glColorMask"); functions->fCompileShader = (GrGLCompileShaderProc) eglGetProcAddress("glCompileShader"); functions->fCompressedTexImage2D = (GrGLCompressedTexImage2DProc) eglGetProcAddress("glCompressedTexImage2D"); @@ -243,14 +248,12 @@ static GrGLInterface* create_desktop_interface(GrGLVersion version, functions->fDeleteVertexArrays = (GrGLDeleteVertexArraysProc) eglGetProcAddress("glDeleteVertexArrays"); functions->fDepthMask = (GrGLDepthMaskProc) eglGetProcAddress("glDepthMask"); functions->fDisable = (GrGLDisableProc) eglGetProcAddress("glDisable"); - functions->fDisableClientState = (GrGLDisableClientStateProc) eglGetProcAddress("glDisableClientState"); functions->fDisableVertexAttribArray = (GrGLDisableVertexAttribArrayProc) eglGetProcAddress("glDisableVertexAttribArray"); functions->fDrawArrays = (GrGLDrawArraysProc) eglGetProcAddress("glDrawArrays"); functions->fDrawBuffer = (GrGLDrawBufferProc) eglGetProcAddress("glDrawBuffer"); functions->fDrawBuffers = (GrGLDrawBuffersProc) eglGetProcAddress("glDrawBuffers"); functions->fDrawElements = (GrGLDrawElementsProc) eglGetProcAddress("glDrawElements"); functions->fEnable = (GrGLEnableProc) eglGetProcAddress("glEnable"); - functions->fEnableClientState = (GrGLEnableClientStateProc) eglGetProcAddress("glEnableClientState"); functions->fEnableVertexAttribArray = (GrGLEnableVertexAttribArrayProc) eglGetProcAddress("glEnableVertexAttribArray"); functions->fEndQuery = (GrGLEndQueryProc) eglGetProcAddress("glEndQuery"); functions->fFinish = (GrGLFinishProc) eglGetProcAddress("glFinish"); @@ -303,7 +306,6 @@ static GrGLInterface* create_desktop_interface(GrGLVersion version, functions->fStencilMaskSeparate = (GrGLStencilMaskSeparateProc) eglGetProcAddress("glStencilMaskSeparate"); functions->fStencilOp = (GrGLStencilOpProc) eglGetProcAddress("glStencilOp"); functions->fStencilOpSeparate = (GrGLStencilOpSeparateProc) eglGetProcAddress("glStencilOpSeparate"); - functions->fTexGenf = (GrGLTexGenfProc) eglGetProcAddress("glTexGenf"); functions->fTexGenfv = (GrGLTexGenfvProc) eglGetProcAddress("glTexGenfv"); functions->fTexGeni = (GrGLTexGeniProc) eglGetProcAddress("glTexGeni"); functions->fTexImage2D = (GrGLTexImage2DProc) eglGetProcAddress("glTexImage2D"); @@ -334,7 +336,6 @@ static GrGLInterface* create_desktop_interface(GrGLVersion version, functions->fUseProgram = (GrGLUseProgramProc) eglGetProcAddress("glUseProgram"); functions->fVertexAttrib4fv = (GrGLVertexAttrib4fvProc) eglGetProcAddress("glVertexAttrib4fv"); functions->fVertexAttribPointer = (GrGLVertexAttribPointerProc) eglGetProcAddress("glVertexAttribPointer"); - functions->fVertexPointer = (GrGLVertexPointerProc) eglGetProcAddress("glVertexPointer"); functions->fViewport = (GrGLViewportProc) eglGetProcAddress("glViewport"); if (extensions.has("GL_NV_path_rendering")) { @@ -389,6 +390,12 @@ static GrGLInterface* create_desktop_interface(GrGLVersion version, functions->fPointAlongPath = (GrGLPointAlongPathProc) eglGetProcAddress("glPointAlongPathNV"); } + if (extensions.has("GL_EXT_debug_marker")) { + functions->fInsertEventMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glInsertEventMarkerEXT"); + functions->fPushGroupMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glPushGroupMarkerEXT"); + functions->fPopGroupMarker = (GrGLPopGroupMarkerProc) eglGetProcAddress("glPopGropuMarkerEXT"); + } + return interface; } diff --git a/gfx/skia/trunk/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp b/gfx/skia/trunk/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp index 1695c3c36f5d..2d91404538e7 100644 --- a/gfx/skia/trunk/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp +++ b/gfx/skia/trunk/src/gpu/gl/angle/GrGLCreateANGLEInterface.cpp @@ -153,6 +153,12 @@ const GrGLInterface* GrGLCreateANGLEInterface() { functions->fMapBuffer = (GrGLMapBufferProc) eglGetProcAddress("glMapBufferOES"); functions->fUnmapBuffer = (GrGLUnmapBufferProc) eglGetProcAddress("glUnmapBufferOES"); +#if GL_EXT_debug_marker + functions->fInsertEventMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glInsertEventMarkerEXT"); + functions->fPushGroupMarker = (GrGLInsertEventMarkerProc) eglGetProcAddress("glPushGroupMarkerEXT"); + functions->fPopGroupMarker = (GrGLPopGroupMarkerProc) eglGetProcAddress("glPopGropuMarkerEXT"); +#endif + interface->fExtensions.init(kGLES_GrGLStandard, interface->fFunctions.fGetString, interface->fFunctions.fGetStringi, diff --git a/gfx/skia/trunk/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp b/gfx/skia/trunk/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp index 97ab9c235848..2751e02c189d 100644 --- a/gfx/skia/trunk/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp +++ b/gfx/skia/trunk/src/gpu/gl/debug/GrGLCreateDebugInterface.cpp @@ -32,13 +32,6 @@ GrGLvoid GR_GL_FUNCTION_TYPE debugGLActiveTexture(GrGLenum texture) { GrDebugGL::getInstance()->setCurTextureUnit(texture); } -GrGLvoid GR_GL_FUNCTION_TYPE debugGLClientActiveTexture(GrGLenum texture) { - - // Ganesh offsets the texture unit indices - texture -= GR_GL_TEXTURE0; - GrAlwaysAssert(texture < GrDebugGL::getInstance()->getMaxTextureUnits()); -} - //////////////////////////////////////////////////////////////////////////////// GrGLvoid GR_GL_FUNCTION_TYPE debugGLAttachShader(GrGLuint programID, GrGLuint shaderID) { @@ -808,7 +801,6 @@ const GrGLInterface* GrGLCreateDebugInterface() { functions->fClear = noOpGLClear; functions->fClearColor = noOpGLClearColor; functions->fClearStencil = noOpGLClearStencil; - functions->fClientActiveTexture = debugGLClientActiveTexture; functions->fColorMask = noOpGLColorMask; functions->fCompileShader = noOpGLCompileShader; functions->fCompressedTexImage2D = noOpGLCompressedTexImage2D; @@ -824,14 +816,12 @@ const GrGLInterface* GrGLCreateDebugInterface() { functions->fDeleteVertexArrays = debugGLDeleteVertexArrays; functions->fDepthMask = noOpGLDepthMask; functions->fDisable = noOpGLDisable; - functions->fDisableClientState = noOpGLDisableClientState; functions->fDisableVertexAttribArray = noOpGLDisableVertexAttribArray; functions->fDrawArrays = noOpGLDrawArrays; functions->fDrawBuffer = noOpGLDrawBuffer; functions->fDrawBuffers = noOpGLDrawBuffers; functions->fDrawElements = noOpGLDrawElements; functions->fEnable = noOpGLEnable; - functions->fEnableClientState = noOpGLEnableClientState; functions->fEnableVertexAttribArray = noOpGLEnableVertexAttribArray; functions->fEndQuery = noOpGLEndQuery; functions->fFinish = noOpGLFinish; @@ -875,7 +865,6 @@ const GrGLInterface* GrGLCreateDebugInterface() { functions->fStencilMaskSeparate = noOpGLStencilMaskSeparate; functions->fStencilOp = noOpGLStencilOp; functions->fStencilOpSeparate = noOpGLStencilOpSeparate; - functions->fTexGenf = noOpGLTexGenf; functions->fTexGenfv = noOpGLTexGenfv; functions->fTexGeni = noOpGLTexGeni; functions->fTexImage2D = noOpGLTexImage2D; @@ -906,7 +895,6 @@ const GrGLInterface* GrGLCreateDebugInterface() { functions->fUseProgram = debugGLUseProgram; functions->fVertexAttrib4fv = noOpGLVertexAttrib4fv; functions->fVertexAttribPointer = noOpGLVertexAttribPointer; - functions->fVertexPointer = noOpGLVertexPointer; functions->fViewport = noOpGLViewport; functions->fBindFramebuffer = debugGLBindFramebuffer; functions->fBindRenderbuffer = debugGLBindRenderbuffer; @@ -931,5 +919,8 @@ const GrGLInterface* GrGLCreateDebugInterface() { functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed; + interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi, + functions->fGetIntegerv); + return interface; } diff --git a/gfx/skia/trunk/src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp b/gfx/skia/trunk/src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp index d8b4e1f8ccf7..decc23498c1d 100644 --- a/gfx/skia/trunk/src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp +++ b/gfx/skia/trunk/src/gpu/gl/iOS/GrGLCreateNativeInterface_iOS.cpp @@ -144,6 +144,12 @@ const GrGLInterface* GrGLCreateNativeInterface() { functions->fGenVertexArrays = glGenVertexArraysOES; #endif +#if GL_EXT_debug_marker + functions->fInsertEventMarker = glInsertEventMarkerEXT; + functions->fPushGroupMarker = glPushGroupMarkerEXT; + functions->fPopGroupMarker = glPopGroupMarkerEXT; +#endif + interface->fStandard = kGLES_GrGLStandard; interface->fExtensions.init(kGLES_GrGLStandard, glGetString, NULL, glGetIntegerv); diff --git a/gfx/skia/trunk/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp b/gfx/skia/trunk/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp index f57b80ebc7de..3a6e07a64b76 100644 --- a/gfx/skia/trunk/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp +++ b/gfx/skia/trunk/src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp @@ -79,7 +79,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { GET_PROC(Clear); GET_PROC(ClearColor); GET_PROC(ClearStencil); - GET_PROC(ClientActiveTexture); GET_PROC(ColorMask); GET_PROC(CompileShader); GET_PROC(CompressedTexImage2D); @@ -94,14 +93,12 @@ const GrGLInterface* GrGLCreateNativeInterface() { GET_PROC(DeleteTextures); GET_PROC(DepthMask); GET_PROC(Disable); - GET_PROC(DisableClientState); GET_PROC(DisableVertexAttribArray); GET_PROC(DrawArrays); GET_PROC(DrawBuffer); GET_PROC(DrawBuffers); GET_PROC(DrawElements); GET_PROC(Enable); - GET_PROC(EnableClientState); GET_PROC(EnableVertexAttribArray); GET_PROC(EndQuery); GET_PROC(Finish); @@ -142,7 +139,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { GET_PROC(StencilMaskSeparate); GET_PROC(StencilOp); GET_PROC(StencilOpSeparate); - GET_PROC(TexGenf); GET_PROC(TexGenfv); GET_PROC(TexGeni); GET_PROC(TexImage2D); @@ -178,7 +174,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { GET_PROC(UseProgram); GET_PROC(VertexAttrib4fv); GET_PROC(VertexAttribPointer); - GET_PROC(VertexPointer); GET_PROC(Viewport); if (ver >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) { @@ -241,6 +236,12 @@ const GrGLInterface* GrGLCreateNativeInterface() { GET_PROC(BindFragDataLocationIndexed); } + if (extensions.has("GL_EXT_debug_marker")) { + GET_PROC_SUFFIX(InsertEventMarker, EXT); + GET_PROC_SUFFIX(PushGroupMarker, EXT); + GET_PROC_SUFFIX(PopGroupMarker, EXT); + } + interface->fExtensions.swap(&extensions); return interface; } diff --git a/gfx/skia/trunk/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp b/gfx/skia/trunk/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp index 59314445b348..7736d954eeb6 100644 --- a/gfx/skia/trunk/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp +++ b/gfx/skia/trunk/src/gpu/gl/mesa/GrGLCreateMesaInterface.cpp @@ -63,7 +63,6 @@ const GrGLInterface* GrGLCreateMesaInterface() { GR_GL_GET_PROC(Clear); GR_GL_GET_PROC(ClearColor); GR_GL_GET_PROC(ClearStencil); - GR_GL_GET_PROC(ClientActiveTexture); GR_GL_GET_PROC(ColorMask); GR_GL_GET_PROC(CompileShader); GR_GL_GET_PROC(CompressedTexImage2D); @@ -78,14 +77,12 @@ const GrGLInterface* GrGLCreateMesaInterface() { GR_GL_GET_PROC(DeleteTextures); GR_GL_GET_PROC(DepthMask); GR_GL_GET_PROC(Disable); - GR_GL_GET_PROC(DisableClientState); GR_GL_GET_PROC(DisableVertexAttribArray); GR_GL_GET_PROC(DrawArrays); GR_GL_GET_PROC(DrawBuffer); GR_GL_GET_PROC(DrawBuffers); GR_GL_GET_PROC(DrawElements); GR_GL_GET_PROC(Enable); - GR_GL_GET_PROC(EnableClientState); GR_GL_GET_PROC(EnableVertexAttribArray); GR_GL_GET_PROC(EndQuery); GR_GL_GET_PROC(Finish); @@ -134,7 +131,6 @@ const GrGLInterface* GrGLCreateMesaInterface() { GR_GL_GET_PROC(StencilMaskSeparate); GR_GL_GET_PROC(StencilOp); GR_GL_GET_PROC(StencilOpSeparate); - GR_GL_GET_PROC(TexGenf); GR_GL_GET_PROC(TexGenfv); GR_GL_GET_PROC(TexGeni); GR_GL_GET_PROC(TexImage2D) @@ -168,7 +164,6 @@ const GrGLInterface* GrGLCreateMesaInterface() { GR_GL_GET_PROC(UseProgram); GR_GL_GET_PROC(VertexAttrib4fv); GR_GL_GET_PROC(VertexAttribPointer); - GR_GL_GET_PROC(VertexPointer); GR_GL_GET_PROC(Viewport); if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) { @@ -221,6 +216,12 @@ const GrGLInterface* GrGLCreateMesaInterface() { } GR_GL_GET_PROC(BindFragDataLocationIndexed); + if (extensions.has("GL_EXT_debug_marker")) { + GR_GL_GET_PROC_SUFFIX(InsertEventMarker, EXT); + GR_GL_GET_PROC_SUFFIX(PopGroupMarker, EXT); + GR_GL_GET_PROC_SUFFIX(PushGroupMarker, EXT); + } + interface->fStandard = kGL_GrGLStandard; interface->fExtensions.swap(&extensions); diff --git a/gfx/skia/trunk/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp b/gfx/skia/trunk/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp index 67d7ef5a5f16..c3951777e0f9 100644 --- a/gfx/skia/trunk/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp +++ b/gfx/skia/trunk/src/gpu/gl/unix/GrGLCreateNativeInterface_unix.cpp @@ -63,7 +63,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { functions->fClear = glClear; functions->fClearColor = glClearColor; functions->fClearStencil = glClearStencil; - functions->fClientActiveTexture = glClientActiveTexture; functions->fColorMask = glColorMask; GR_GL_GET_PROC(CompileShader); functions->fCompressedTexImage2D = glCompressedTexImage2D; @@ -78,14 +77,12 @@ const GrGLInterface* GrGLCreateNativeInterface() { functions->fDeleteTextures = glDeleteTextures; functions->fDepthMask = glDepthMask; functions->fDisable = glDisable; - functions->fDisableClientState = glDisableClientState; GR_GL_GET_PROC(DisableVertexAttribArray); functions->fDrawArrays = glDrawArrays; functions->fDrawBuffer = glDrawBuffer; GR_GL_GET_PROC(DrawBuffers); functions->fDrawElements = glDrawElements; functions->fEnable = glEnable; - functions->fEnableClientState = glEnableClientState; GR_GL_GET_PROC(EnableVertexAttribArray); GR_GL_GET_PROC(EndQuery); functions->fFinish = glFinish; @@ -132,7 +129,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { functions->fStencilOp = glStencilOp; GR_GL_GET_PROC(StencilOpSeparate); functions->fTexImage2D = glTexImage2D; - functions->fTexGenf = glTexGenf; functions->fTexGenfv = glTexGenfv; functions->fTexGeni = glTexGeni; functions->fTexParameteri = glTexParameteri; @@ -166,7 +162,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { GR_GL_GET_PROC(UseProgram); GR_GL_GET_PROC(VertexAttrib4fv); GR_GL_GET_PROC(VertexAttribPointer); - GR_GL_GET_PROC(VertexPointer); functions->fViewport = glViewport; GR_GL_GET_PROC(BindFragDataLocationIndexed); @@ -275,6 +270,12 @@ const GrGLInterface* GrGLCreateNativeInterface() { GR_GL_GET_PROC_SUFFIX(PointAlongPath, NV); } + if (extensions.has("GL_EXT_debug_marker")) { + GR_GL_GET_PROC_SUFFIX(InsertEventMarker, EXT); + GR_GL_GET_PROC_SUFFIX(PushGroupMarker, EXT); + GR_GL_GET_PROC_SUFFIX(PopGroupMarker, EXT); + } + interface->fStandard = kGL_GrGLStandard; interface->fExtensions.swap(&extensions); diff --git a/gfx/skia/trunk/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp b/gfx/skia/trunk/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp index e901b3602c0d..adc90a4bed55 100644 --- a/gfx/skia/trunk/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp +++ b/gfx/skia/trunk/src/gpu/gl/win/GrGLCreateNativeInterface_win.cpp @@ -90,12 +90,10 @@ const GrGLInterface* GrGLCreateNativeInterface() { SET_PROC(DeleteTextures) SET_PROC(DepthMask) SET_PROC(Disable) - SET_PROC(DisableClientState) SET_PROC(DrawArrays) SET_PROC(DrawElements) SET_PROC(DrawBuffer) SET_PROC(Enable) - SET_PROC(EnableClientState) SET_PROC(FrontFace) SET_PROC(Finish) SET_PROC(Flush) @@ -115,7 +113,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { SET_PROC(StencilFunc) SET_PROC(StencilMask) SET_PROC(StencilOp) - SET_PROC(TexGenf) SET_PROC(TexGenfv) SET_PROC(TexGeni) SET_PROC(TexImage2D) @@ -128,7 +125,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { } SET_PROC(TexSubImage2D) SET_PROC(Viewport) - SET_PROC(VertexPointer) WGL_SET_PROC(ActiveTexture); WGL_SET_PROC(AttachShader); @@ -138,7 +134,6 @@ const GrGLInterface* GrGLCreateNativeInterface() { WGL_SET_PROC(BindFragDataLocation); WGL_SET_PROC(BufferData); WGL_SET_PROC(BufferSubData); - WGL_SET_PROC(ClientActiveTexture); WGL_SET_PROC(CompileShader); WGL_SET_PROC(CompressedTexImage2D); WGL_SET_PROC(CreateProgram); @@ -304,6 +299,12 @@ const GrGLInterface* GrGLCreateNativeInterface() { WGL_SET_PROC_SUFFIX(PointAlongPath, NV); } + if (extensions.has("GL_EXT_debug_marker")) { + WGL_SET_PROC_SUFFIX(InsertEventMarker, EXT); + WGL_SET_PROC_SUFFIX(PushGroupMarker, EXT); + WGL_SET_PROC_SUFFIX(PopGroupMarker, EXT); + } + interface->fStandard = kGL_GrGLStandard; interface->fExtensions.swap(&extensions); diff --git a/gfx/skia/trunk/src/image/SkDataPixelRef.cpp b/gfx/skia/trunk/src/image/SkDataPixelRef.cpp deleted file mode 100644 index 7897bf931584..000000000000 --- a/gfx/skia/trunk/src/image/SkDataPixelRef.cpp +++ /dev/null @@ -1,43 +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. - */ - -#include "SkDataPixelRef.h" -#include "SkData.h" -#include "SkFlattenableBuffers.h" - -SkDataPixelRef::SkDataPixelRef(SkData* data) : fData(data) { - fData->ref(); - this->setPreLocked(const_cast(fData->data()), NULL); -} - -SkDataPixelRef::~SkDataPixelRef() { - fData->unref(); -} - -void* SkDataPixelRef::onLockPixels(SkColorTable** ct) { - *ct = NULL; - return const_cast(fData->data()); -} - -void SkDataPixelRef::onUnlockPixels() { - // nothing to do -} - -size_t SkDataPixelRef::getAllocatedSizeInBytes() const { - return fData ? fData->size() : 0; -} - -void SkDataPixelRef::flatten(SkFlattenableWriteBuffer& buffer) const { - this->INHERITED::flatten(buffer); - buffer.writeDataAsByteArray(fData); -} - -SkDataPixelRef::SkDataPixelRef(SkFlattenableReadBuffer& buffer) - : INHERITED(buffer, NULL) { - fData = buffer.readByteArrayAsData(); - this->setPreLocked(const_cast(fData->data()), NULL); -} diff --git a/gfx/skia/trunk/src/image/SkDataPixelRef.h b/gfx/skia/trunk/src/image/SkDataPixelRef.h deleted file mode 100644 index 50c885714b91..000000000000 --- a/gfx/skia/trunk/src/image/SkDataPixelRef.h +++ /dev/null @@ -1,36 +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 SkDataPixelRef_DEFINED -#define SkDataPixelRef_DEFINED - -#include "SkPixelRef.h" - -class SkData; - -class SkDataPixelRef : public SkPixelRef { -public: - SkDataPixelRef(SkData* data); - virtual ~SkDataPixelRef(); - - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDataPixelRef) - -protected: - virtual void* onLockPixels(SkColorTable**) SK_OVERRIDE; - virtual void onUnlockPixels() SK_OVERRIDE; - virtual size_t getAllocatedSizeInBytes() const SK_OVERRIDE; - - SkDataPixelRef(SkFlattenableReadBuffer& buffer); - virtual void flatten(SkFlattenableWriteBuffer&) const SK_OVERRIDE; - -private: - SkData* fData; - - typedef SkPixelRef INHERITED; -}; - -#endif diff --git a/gfx/skia/trunk/src/image/SkImagePriv.h b/gfx/skia/trunk/src/image/SkImagePriv.h index 8883e2c0707d..bf28f598c50f 100644 --- a/gfx/skia/trunk/src/image/SkImagePriv.h +++ b/gfx/skia/trunk/src/image/SkImagePriv.h @@ -14,8 +14,6 @@ class SkPicture; extern SkBitmap::Config SkImageInfoToBitmapConfig(const SkImageInfo&); -extern SkBitmap::Config SkColorTypeToBitmapConfig(SkColorType); -extern SkColorType SkBitmapConfigToColorType(SkBitmap::Config); // Call this if you explicitly want to use/share this pixelRef in the image extern SkImage* SkNewImageFromPixelRef(const SkImageInfo&, SkPixelRef*, diff --git a/gfx/skia/trunk/src/image/SkImage_Gpu.cpp b/gfx/skia/trunk/src/image/SkImage_Gpu.cpp index 0d8ddaa60188..475f50ed8ab8 100644 --- a/gfx/skia/trunk/src/image/SkImage_Gpu.cpp +++ b/gfx/skia/trunk/src/image/SkImage_Gpu.cpp @@ -59,7 +59,7 @@ GrTexture* SkImage_Gpu::onGetTexture() { } bool SkImage_Gpu::getROPixels(SkBitmap* dst) const { - return fBitmap.copyTo(dst, SkBitmap::kARGB_8888_Config); + return fBitmap.copyTo(dst, kPMColor_SkColorType); } /////////////////////////////////////////////////////////////////////////////// diff --git a/gfx/skia/trunk/src/image/SkImage_Raster.cpp b/gfx/skia/trunk/src/image/SkImage_Raster.cpp index 504943e8943b..abf6dc8af08a 100644 --- a/gfx/skia/trunk/src/image/SkImage_Raster.cpp +++ b/gfx/skia/trunk/src/image/SkImage_Raster.cpp @@ -127,7 +127,7 @@ bool SkImage_Raster::onReadPixels(SkBitmap* dst, const SkIRect& subset) const { if (!fBitmap.extractSubset(&src, subset)) { return false; } - return src.copyTo(dst, src.config()); + return src.copyTo(dst, src.colorType()); } } diff --git a/gfx/skia/trunk/src/image/SkSurface.cpp b/gfx/skia/trunk/src/image/SkSurface.cpp index cb029c8aea3b..ecb80427576d 100644 --- a/gfx/skia/trunk/src/image/SkSurface.cpp +++ b/gfx/skia/trunk/src/image/SkSurface.cpp @@ -121,3 +121,7 @@ void SkSurface::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) { return asSB(this)->onDraw(canvas, x, y, paint); } + +const void* SkSurface::peekPixels(SkImageInfo* info, size_t* rowBytes) { + return this->getCanvas()->peekPixels(info, rowBytes); +} diff --git a/gfx/skia/trunk/src/image/SkSurface_Gpu.cpp b/gfx/skia/trunk/src/image/SkSurface_Gpu.cpp index 58f9ef34375d..ae05ea8c0460 100644 --- a/gfx/skia/trunk/src/image/SkSurface_Gpu.cpp +++ b/gfx/skia/trunk/src/image/SkSurface_Gpu.cpp @@ -14,7 +14,6 @@ class SkSurface_Gpu : public SkSurface_Base { public: SK_DECLARE_INST_COUNT(SkSurface_Gpu) - SkSurface_Gpu(GrContext*, const SkImageInfo&, int sampleCount); SkSurface_Gpu(GrRenderTarget*); virtual ~SkSurface_Gpu(); @@ -33,18 +32,6 @@ private: /////////////////////////////////////////////////////////////////////////////// -SkSurface_Gpu::SkSurface_Gpu(GrContext* ctx, const SkImageInfo& info, - int sampleCount) - : INHERITED(info.fWidth, info.fHeight) { - SkBitmap::Config config = SkImageInfoToBitmapConfig(info); - - fDevice = SkNEW_ARGS(SkGpuDevice, (ctx, config, info.fWidth, info.fHeight, sampleCount)); - - if (!SkAlphaTypeIsOpaque(info.fAlphaType)) { - fDevice->clear(0x0); - } -} - SkSurface_Gpu::SkSurface_Gpu(GrRenderTarget* renderTarget) : INHERITED(renderTarget->width(), renderTarget->height()) { fDevice = SkNEW_ARGS(SkGpuDevice, (renderTarget->getContext(), renderTarget)); @@ -85,18 +72,20 @@ void SkSurface_Gpu::onCopyOnWrite(ContentChangeMode mode) { // are we sharing our render target with the image? SkASSERT(NULL != this->getCachedImage()); if (rt->asTexture() == SkTextureImageGetTexture(this->getCachedImage())) { - SkAutoTUnref newDevice(SkNEW_ARGS(SkGpuDevice, - (fDevice->context(), fDevice->config(), fDevice->width(), - fDevice->height(), rt->numSamples()))); - + // We call createCompatibleDevice because it uses the texture cache. This isn't + // necessarily correct (http://skbug.com/2252), but never using the cache causes + // a Chromium regression. (http://crbug.com/344020) + SkGpuDevice* newDevice = static_cast( + fDevice->createCompatibleDevice(fDevice->imageInfo())); + SkAutoTUnref aurd(newDevice); if (kRetain_ContentChangeMode == mode) { - fDevice->context()->copyTexture(rt->asTexture(), - reinterpret_cast(newDevice->accessRenderTarget())); + fDevice->context()->copyTexture(rt->asTexture(), newDevice->accessRenderTarget()); } SkASSERT(NULL != this->getCachedCanvas()); SkASSERT(this->getCachedCanvas()->getDevice() == fDevice); - this->getCachedCanvas()->setDevice(newDevice); - SkRefCnt_SafeAssign(fDevice, newDevice.get()); + + this->getCachedCanvas()->setRootDevice(newDevice); + SkRefCnt_SafeAssign(fDevice, newDevice); } } diff --git a/gfx/skia/trunk/src/image/SkSurface_Raster.cpp b/gfx/skia/trunk/src/image/SkSurface_Raster.cpp index 1b218eb44622..e24c0e869950 100644 --- a/gfx/skia/trunk/src/image/SkSurface_Raster.cpp +++ b/gfx/skia/trunk/src/image/SkSurface_Raster.cpp @@ -125,7 +125,7 @@ void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { fBitmap.allocPixels(); } else { SkBitmap prev(fBitmap); - prev.deepCopyTo(&fBitmap, prev.config()); + prev.deepCopyTo(&fBitmap); } // Now fBitmap is a deep copy of itself (and therefore different from // what is being used by the image. Next we update the canvas to use diff --git a/gfx/skia/trunk/src/images/SkDecodingImageGenerator.cpp b/gfx/skia/trunk/src/images/SkDecodingImageGenerator.cpp index 1e2813660329..2d93eb542e28 100644 --- a/gfx/skia/trunk/src/images/SkDecodingImageGenerator.cpp +++ b/gfx/skia/trunk/src/images/SkDecodingImageGenerator.cpp @@ -14,60 +14,50 @@ #include "SkStream.h" #include "SkUtils.h" +static bool equal_modulo_alpha(const SkImageInfo& a, const SkImageInfo& b) { + return a.width() == b.width() && a.height() == b.height() && + a.colorType() == b.colorType(); +} + namespace { /** * Special allocator used by getPixels(). Uses preallocated memory - * provided. + * provided if possible, else fall-back on the default allocator */ class TargetAllocator : public SkBitmap::Allocator { public: - TargetAllocator(void* target, - size_t rowBytes, - int width, - int height, - SkBitmap::Config config) - : fTarget(target) + TargetAllocator(const SkImageInfo& info, + void* target, + size_t rowBytes) + : fInfo(info) + , fTarget(target) , fRowBytes(rowBytes) - , fWidth(width) - , fHeight(height) - , fConfig(config) { } + {} bool isReady() { return (fTarget != NULL); } virtual bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) { - if ((NULL == fTarget) - || (fConfig != bm->config()) - || (fWidth != bm->width()) - || (fHeight != bm->height()) - || (ct != NULL)) { + if (NULL == fTarget || !equal_modulo_alpha(fInfo, bm->info())) { // Call default allocator. return bm->allocPixels(NULL, ct); } - // make sure fRowBytes is correct. - bm->setConfig(fConfig, fWidth, fHeight, fRowBytes, bm->alphaType()); + // TODO(halcanary): verify that all callers of this function // will respect new RowBytes. Will be moot once rowbytes belongs // to PixelRef. - bm->setPixels(fTarget, NULL); + bm->installPixels(fInfo, fTarget, fRowBytes, NULL, NULL); + fTarget = NULL; // never alloc same pixels twice! return true; } private: + const SkImageInfo fInfo; void* fTarget; // Block of memory to be supplied as pixel memory // in allocPixelRef. Must be large enough to hold - // a bitmap described by fWidth, fHeight, and - // fRowBytes. - size_t fRowBytes; // rowbytes for the destination bitmap - int fWidth; // Along with fHeight and fConfig, the information - int fHeight; // about the bitmap whose pixels this allocator is - // expected to allocate. If they do not match the - // bitmap passed to allocPixelRef, it is assumed - // that the bitmap will be copied to a bitmap with - // the correct info using this allocator, so the - // default allocator will be used instead of - // fTarget. - SkBitmap::Config fConfig; + // a bitmap described by fInfo and fRowBytes + const size_t fRowBytes; // rowbytes for the destination bitmap + typedef SkBitmap::Allocator INHERITED; }; @@ -94,14 +84,13 @@ SkDecodingImageGenerator::SkDecodingImageGenerator( SkStreamRewindable* stream, const SkImageInfo& info, int sampleSize, - bool ditherImage, - SkBitmap::Config requestedConfig) + bool ditherImage) : fData(data) , fStream(stream) , fInfo(info) , fSampleSize(sampleSize) , fDitherImage(ditherImage) - , fRequestedConfig(requestedConfig) { +{ SkASSERT(stream != NULL); SkSafeRef(fData); // may be NULL. } @@ -151,8 +140,7 @@ bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info, // to change the settings. return false; } - int bpp = SkBitmap::ComputeBytesPerPixel(fRequestedConfig); - if (static_cast(bpp * info.fWidth) > rowBytes) { + if (info.minRowBytes() > rowBytes) { // The caller has specified a bad rowBytes. return false; } @@ -166,10 +154,11 @@ bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info, decoder->setSampleSize(fSampleSize); SkBitmap bitmap; - TargetAllocator allocator(pixels, rowBytes, info.fWidth, - info.fHeight, fRequestedConfig); + TargetAllocator allocator(fInfo, pixels, rowBytes); decoder->setAllocator(&allocator); - bool success = decoder->decode(fStream, &bitmap, fRequestedConfig, + // TODO: need to be able to pass colortype directly to decoder + SkBitmap::Config legacyConfig = SkColorTypeToBitmapConfig(info.colorType()); + bool success = decoder->decode(fStream, &bitmap, legacyConfig, SkImageDecoder::kDecodePixels_Mode); decoder->setAllocator(NULL); if (!success) { @@ -177,16 +166,16 @@ bool SkDecodingImageGenerator::getPixels(const SkImageInfo& info, } if (allocator.isReady()) { // Did not use pixels! SkBitmap bm; - SkASSERT(bitmap.canCopyTo(fRequestedConfig)); - if (!bitmap.copyTo(&bm, fRequestedConfig, &allocator) - || allocator.isReady()) { + SkASSERT(bitmap.canCopyTo(info.colorType())); + bool copySuccess = bitmap.copyTo(&bm, info.colorType(), &allocator); + if (!copySuccess || allocator.isReady()) { SkDEBUGFAIL("bitmap.copyTo(requestedConfig) failed."); // Earlier we checked canCopyto(); we expect consistency. return false; } - SkASSERT(check_alpha(fInfo.fAlphaType, bm.alphaType())); + SkASSERT(check_alpha(info.alphaType(), bm.alphaType())); } else { - SkASSERT(check_alpha(fInfo.fAlphaType, bitmap.alphaType())); + SkASSERT(check_alpha(info.alphaType(), bitmap.alphaType())); } return true; } @@ -245,38 +234,23 @@ SkImageGenerator* SkDecodingImageGenerator::Create( return NULL; } - SkImageInfo info; - SkBitmap::Config config; + SkImageInfo info = bitmap.info(); if (!opts.fUseRequestedColorType) { - // Use default config. - if (SkBitmap::kIndex8_Config == bitmap.config()) { + // Use default + if (kIndex_8_SkColorType == bitmap.colorType()) { // We don't support kIndex8 because we don't support // colortables in this workflow. - config = SkBitmap::kARGB_8888_Config; - info.fWidth = bitmap.width(); - info.fHeight = bitmap.height(); info.fColorType = kPMColor_SkColorType; - info.fAlphaType = bitmap.alphaType(); - } else { - config = bitmap.config(); // Save for later! - if (!bitmap.asImageInfo(&info)) { - SkDEBUGFAIL("Getting SkImageInfo from bitmap failed."); - return NULL; - } } } else { - config = SkColorTypeToBitmapConfig(opts.fRequestedColorType); - if (!bitmap.canCopyTo(config)) { - SkASSERT(bitmap.config() != config); + if (!bitmap.canCopyTo(opts.fRequestedColorType)) { + SkASSERT(bitmap.colorType() != opts.fRequestedColorType); return NULL; // Can not translate to needed config. } - info.fWidth = bitmap.width(); - info.fHeight = bitmap.height(); info.fColorType = opts.fRequestedColorType; - info.fAlphaType = bitmap.alphaType(); } return SkNEW_ARGS(SkDecodingImageGenerator, (data, autoStream.detach(), info, - opts.fSampleSize, opts.fDitherImage, config)); + opts.fSampleSize, opts.fDitherImage)); } diff --git a/gfx/skia/trunk/src/images/SkDecodingImageGenerator.h b/gfx/skia/trunk/src/images/SkDecodingImageGenerator.h index 12a49d59c47e..fef7c6c7c789 100644 --- a/gfx/skia/trunk/src/images/SkDecodingImageGenerator.h +++ b/gfx/skia/trunk/src/images/SkDecodingImageGenerator.h @@ -113,13 +113,12 @@ private: const SkImageInfo fInfo; const int fSampleSize; const bool fDitherImage; - const SkBitmap::Config fRequestedConfig; + SkDecodingImageGenerator(SkData* data, SkStreamRewindable* stream, const SkImageInfo& info, int sampleSize, - bool ditherImage, - SkBitmap::Config requestedConfig); + bool ditherImage); static SkImageGenerator* Create(SkData*, SkStreamRewindable*, const Options&); typedef SkImageGenerator INHERITED; diff --git a/gfx/skia/trunk/src/images/SkImageDecoder_libpng.cpp b/gfx/skia/trunk/src/images/SkImageDecoder_libpng.cpp index 3cc41e3f5983..cd09f5f980d4 100644 --- a/gfx/skia/trunk/src/images/SkImageDecoder_libpng.cpp +++ b/gfx/skia/trunk/src/images/SkImageDecoder_libpng.cpp @@ -333,6 +333,11 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); decodedBitmap->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight()); + // we should communicate alphaType, even if we early-return in bounds-only-mode. + if (this->getRequireUnpremultipliedColors()) { + decodedBitmap->setAlphaType(kUnpremul_SkAlphaType); + } + if (SkImageDecoder::kDecodeBounds_Mode == mode) { return true; } @@ -478,15 +483,9 @@ bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, } } - SkAlphaType alphaType = kOpaque_SkAlphaType; - if (reallyHasAlpha) { - if (this->getRequireUnpremultipliedColors()) { - alphaType = kUnpremul_SkAlphaType; - } else { - alphaType = kPremul_SkAlphaType; - } + if (!reallyHasAlpha) { + decodedBitmap->setAlphaType(kOpaque_SkAlphaType); } - decodedBitmap->setAlphaType(alphaType); return true; } diff --git a/gfx/skia/trunk/src/images/SkImageDecoder_libwebp.cpp b/gfx/skia/trunk/src/images/SkImageDecoder_libwebp.cpp index 05925d03a266..49d5bd1cca07 100644 --- a/gfx/skia/trunk/src/images/SkImageDecoder_libwebp.cpp +++ b/gfx/skia/trunk/src/images/SkImageDecoder_libwebp.cpp @@ -444,6 +444,8 @@ bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, /////////////////////////////////////////////////////////////////////////////// +#include "SkUnPreMultiply.h" + typedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width, const SkPMColor* SK_RESTRICT ctable); @@ -459,6 +461,31 @@ static void ARGB_8888_To_RGB(const uint8_t* in, uint8_t* rgb, int width, } } +static void ARGB_8888_To_RGBA(const uint8_t* in, uint8_t* rgb, int width, + const SkPMColor*) { + const uint32_t* SK_RESTRICT src = (const uint32_t*)in; + const SkUnPreMultiply::Scale* SK_RESTRICT table = + SkUnPreMultiply::GetScaleTable(); + for (int i = 0; i < width; ++i) { + const uint32_t c = *src++; + uint8_t a = SkGetPackedA32(c); + uint8_t r = SkGetPackedR32(c); + uint8_t g = SkGetPackedG32(c); + uint8_t b = SkGetPackedB32(c); + if (0 != a && 255 != a) { + SkUnPreMultiply::Scale scale = table[a]; + r = SkUnPreMultiply::ApplyScale(scale, r); + g = SkUnPreMultiply::ApplyScale(scale, g); + b = SkUnPreMultiply::ApplyScale(scale, b); + } + rgb[0] = r; + rgb[1] = g; + rgb[2] = b; + rgb[3] = a; + rgb += 4; + } +} + static void RGB_565_To_RGB(const uint8_t* in, uint8_t* rgb, int width, const SkPMColor*) { const uint16_t* SK_RESTRICT src = (const uint16_t*)in; @@ -483,6 +510,31 @@ static void ARGB_4444_To_RGB(const uint8_t* in, uint8_t* rgb, int width, } } +static void ARGB_4444_To_RGBA(const uint8_t* in, uint8_t* rgb, int width, + const SkPMColor*) { + const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in; + const SkUnPreMultiply::Scale* SK_RESTRICT table = + SkUnPreMultiply::GetScaleTable(); + for (int i = 0; i < width; ++i) { + const SkPMColor16 c = *src++; + uint8_t a = SkPacked4444ToA32(c); + uint8_t r = SkPacked4444ToR32(c); + uint8_t g = SkPacked4444ToG32(c); + uint8_t b = SkPacked4444ToB32(c); + if (0 != a && 255 != a) { + SkUnPreMultiply::Scale scale = table[a]; + r = SkUnPreMultiply::ApplyScale(scale, r); + g = SkUnPreMultiply::ApplyScale(scale, g); + b = SkUnPreMultiply::ApplyScale(scale, b); + } + rgb[0] = r; + rgb[1] = g; + rgb[2] = b; + rgb[3] = a; + rgb += 4; + } +} + static void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width, const SkPMColor* SK_RESTRICT ctable) { const uint8_t* SK_RESTRICT src = (const uint8_t*)in; @@ -495,15 +547,31 @@ static void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width, } } -static ScanlineImporter ChooseImporter(const SkBitmap::Config& config) { +static ScanlineImporter ChooseImporter(const SkBitmap::Config& config, + bool hasAlpha, + int* bpp) { switch (config) { case SkBitmap::kARGB_8888_Config: - return ARGB_8888_To_RGB; - case SkBitmap::kRGB_565_Config: - return RGB_565_To_RGB; + if (hasAlpha) { + *bpp = 4; + return ARGB_8888_To_RGBA; + } else { + *bpp = 3; + return ARGB_8888_To_RGB; + } case SkBitmap::kARGB_4444_Config: - return ARGB_4444_To_RGB; + if (hasAlpha) { + *bpp = 4; + return ARGB_4444_To_RGBA; + } else { + *bpp = 3; + return ARGB_4444_To_RGB; + } + case SkBitmap::kRGB_565_Config: + *bpp = 3; + return RGB_565_To_RGB; case SkBitmap::kIndex8_Config: + *bpp = 3; return Index8_To_RGB; default: return NULL; @@ -527,10 +595,16 @@ private: bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, int quality) { const SkBitmap::Config config = bm.config(); - const ScanlineImporter scanline_import = ChooseImporter(config); + const bool hasAlpha = !bm.isOpaque(); + int bpp = -1; + const ScanlineImporter scanline_import = ChooseImporter(config, hasAlpha, + &bpp); if (NULL == scanline_import) { return false; } + if (-1 == bpp) { + return false; + } SkAutoLockPixels alp(bm); SkAutoLockColors ctLocker; @@ -552,7 +626,7 @@ bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, const SkPMColor* colors = ctLocker.lockColors(bm); const uint8_t* src = (uint8_t*)bm.getPixels(); - const int rgbStride = pic.width * 3; + const int rgbStride = pic.width * bpp; // Import (for each scanline) the bit-map image (in appropriate color-space) // to RGB color space. @@ -562,7 +636,12 @@ bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, pic.width, colors); } - bool ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride)); + bool ok; + if (bpp == 3) { + ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride)); + } else { + ok = SkToBool(WebPPictureImportRGBA(&pic, rgb, rgbStride)); + } delete[] rgb; ok = ok && WebPEncode(&webp_config, &pic); diff --git a/gfx/skia/trunk/src/images/SkImageRef.cpp b/gfx/skia/trunk/src/images/SkImageRef.cpp index ea129642db15..458aa2aa5abe 100644 --- a/gfx/skia/trunk/src/images/SkImageRef.cpp +++ b/gfx/skia/trunk/src/images/SkImageRef.cpp @@ -30,6 +30,10 @@ SkImageRef::SkImageRef(const SkImageInfo& info, SkStreamRewindable* stream, fPrev = fNext = NULL; fFactory = NULL; + // This sets the colortype/alphatype to exactly match our info, so that this + // can get communicated down to the codec. + fBitmap.setConfig(info); + #ifdef DUMP_IMAGEREF_LIFECYCLE SkDebugf("add ImageRef %p [%d] data=%d\n", this, this->info().fColorType, (int)stream->getLength()); @@ -117,7 +121,12 @@ bool SkImageRef::prepareBitmap(SkImageDecoder::Mode mode) { codec->setSampleSize(fSampleSize); codec->setDitherImage(fDoDither); + codec->setRequireUnpremultipliedColors(this->info().fAlphaType == kUnpremul_SkAlphaType); if (this->onDecode(codec, fStream, &fBitmap, fBitmap.config(), mode)) { + if (kOpaque_SkAlphaType == fBitmap.alphaType()) { + this->changeAlphaType(kOpaque_SkAlphaType); + } + SkASSERT(this->info() == fBitmap.info()); return true; } } @@ -178,6 +187,10 @@ SkImageRef::SkImageRef(SkReadBuffer& buffer, SkBaseMutex* mutex) fPrev = fNext = NULL; fFactory = NULL; + + // This sets the colortype/alphatype to exactly match our info, so that this + // can get communicated down to the codec. + fBitmap.setConfig(this->info()); } void SkImageRef::flatten(SkWriteBuffer& buffer) const { diff --git a/gfx/skia/trunk/src/lazy/SkDiscardablePixelRef.cpp b/gfx/skia/trunk/src/lazy/SkDiscardablePixelRef.cpp index 0878d00335d0..56b94b734e31 100644 --- a/gfx/skia/trunk/src/lazy/SkDiscardablePixelRef.cpp +++ b/gfx/skia/trunk/src/lazy/SkDiscardablePixelRef.cpp @@ -87,7 +87,7 @@ bool SkInstallDiscardablePixelRef(SkImageGenerator* generator, || (!dst->setConfig(info, 0))) { return false; } - SkASSERT(dst->config() != SkBitmap::kNo_Config); + SkASSERT(dst->colorType() != kUnknown_SkColorType); if (dst->empty()) { // Use a normal pixelref. return dst->allocPixels(); } diff --git a/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_clamp_neon.h b/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_clamp_neon.h deleted file mode 100644 index a615e26b2401..000000000000 --- a/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_clamp_neon.h +++ /dev/null @@ -1,911 +0,0 @@ -/* NEON optimized code (C) COPYRIGHT 2009 Motorola - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* - * Modifications done in-house at Motorola - * - * this is a clone of SkBitmapProcState_matrix.h - * and has been tuned to work with the NEON unit. - * - * Still going back and forth between whether this approach - * (clone the entire SkBitmapProcState_matrix.h file or - * if I should put just the modified routines in here and - * then use a construct like #define DONT_DO_THIS_FUNCTION or - * something like that... - * - * This is for the ClampX_ClampY instance - * - */ - - -#include - -/* - * This has been modified on the knowledge that (at the time) - * we had the following macro definitions in the parent file - * - * #define MAKENAME(suffix) ClampX_ClampY ## suffix - * #define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max) - * #define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max) - * #define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF) - * #define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF) - * #define CHECK_FOR_DECAL - */ - -/* SkClampMax(val,max) -- bound to 0..max */ - -#define SCALE_NOFILTER_NAME MAKENAME(_nofilter_scale) -#define SCALE_FILTER_NAME MAKENAME(_filter_scale) -#define AFFINE_NOFILTER_NAME MAKENAME(_nofilter_affine) -#define AFFINE_FILTER_NAME MAKENAME(_filter_affine) -#define PERSP_NOFILTER_NAME MAKENAME(_nofilter_persp) -#define PERSP_FILTER_NAME MAKENAME(_filter_persp) - -#define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x) -#define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y) - -#ifndef PREAMBLE - #define PREAMBLE(state) - #define PREAMBLE_PARAM_X - #define PREAMBLE_PARAM_Y - #define PREAMBLE_ARG_X - #define PREAMBLE_ARG_Y -#endif - -static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask)) == 0); - - PREAMBLE(s); - // we store y, x, x, x, x, x - - const unsigned maxX = s.fBitmap->width() - 1; - SkFixed fx; - { - SkPoint pt; - s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &pt); - fx = SkScalarToFixed(pt.fY); - const unsigned maxY = s.fBitmap->height() - 1; - *xy++ = TILEY_PROCF(fx, maxY); - fx = SkScalarToFixed(pt.fX); - } - - if (0 == maxX) { - // all of the following X values must be 0 - memset(xy, 0, count * sizeof(uint16_t)); - return; - } - - const SkFixed dx = s.fInvSx; - -#ifdef CHECK_FOR_DECAL - // test if we don't need to apply the tile proc - if ((unsigned)(fx >> 16) <= maxX && - (unsigned)((fx + dx * (count - 1)) >> 16) <= maxX) { - decal_nofilter_scale_neon(xy, fx, dx, count); - return; - } -#endif - - int i; - - /* very much like done in decal_nofilter, but with - * an extra clamping function applied. - * TILEX_PROCF(fx,max) SkClampMax((fx)>>16, max) - */ - if (count >= 8) { - /* SkFixed is 16.16 fixed point */ - SkFixed dx2 = dx+dx; - SkFixed dx4 = dx2+dx2; - SkFixed dx8 = dx4+dx4; - - /* now build fx/fx+dx/fx+2dx/fx+3dx */ - SkFixed fx1, fx2, fx3; - int32x4_t lbase, hbase; - int16_t *dst16 = (int16_t *)xy; - - fx1 = fx+dx; - fx2 = fx1+dx; - fx3 = fx2+dx; - - /* build my template(s) */ - /* avoid the 'lbase unitialized' warning */ - lbase = vdupq_n_s32(fx); - lbase = vsetq_lane_s32(fx1, lbase, 1); - lbase = vsetq_lane_s32(fx2, lbase, 2); - lbase = vsetq_lane_s32(fx3, lbase, 3); - - hbase = vaddq_s32(lbase, vdupq_n_s32(dx4)); - - /* store & bump */ - do { - int32x4_t lout; - int32x4_t hout; - int16x8_t hi16; - - /* get the hi 16s of all those 32s */ - lout = lbase; - hout = hbase; - /* this sets up all lout's then all hout's in hout */ - asm ("vuzpq.16 %q0, %q1" : "+w" (lout), "+w" (hout)); - hi16 = vreinterpretq_s16_s32(hout); - - /* clamp & output */ - hi16 = vmaxq_s16(hi16, vdupq_n_s16(0)); - hi16 = vminq_s16(hi16, vdupq_n_s16(maxX)); - vst1q_s16(dst16, hi16); - - /* but preserving base & on to the next */ - lbase = vaddq_s32 (lbase, vdupq_n_s32(dx8)); - hbase = vaddq_s32 (hbase, vdupq_n_s32(dx8)); - dst16 += 8; - count -= 8; - fx += dx8; - } while (count >= 8); - xy = (uint32_t *) dst16; - } - - uint16_t* xx = (uint16_t*)xy; - for (i = count; i > 0; --i) { - *xx++ = TILEX_PROCF(fx, maxX); fx += dx; - } -} - -// note: we could special-case on a matrix which is skewed in X but not Y. -// this would require a more general setup thatn SCALE does, but could use -// SCALE's inner loop that only looks at dx - -static void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask | - SkMatrix::kAffine_Mask)) == 0); - - PREAMBLE(s); - SkPoint srcPt; - s.fInvProc(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - - SkFixed fx = SkScalarToFixed(srcPt.fX); - SkFixed fy = SkScalarToFixed(srcPt.fY); - SkFixed dx = s.fInvSx; - SkFixed dy = s.fInvKy; - int maxX = s.fBitmap->width() - 1; - int maxY = s.fBitmap->height() - 1; - - /* NEON lets us do an 8x unrolling */ - if (count >= 8) { - /* SkFixed is 16.16 fixed point */ - SkFixed dx4 = dx * 4; - SkFixed dy4 = dy * 4; - SkFixed dx8 = dx * 8; - SkFixed dy8 = dy * 8; - - int32x4_t xbase, ybase; - int32x4_t x2base, y2base; - int16_t *dst16 = (int16_t *) xy; - - /* my sets of maxx/maxy for clamping */ - int32_t maxpair = (maxX&0xffff) | ((maxY&0xffff)<<16); - int16x8_t maxXY = vreinterpretq_s16_s32(vdupq_n_s32(maxpair)); - - /* now build fx/fx+dx/fx+2dx/fx+3dx */ - /* avoid the 'xbase unitialized' warning...*/ - xbase = vdupq_n_s32(fx); - xbase = vsetq_lane_s32(fx+dx, xbase, 1); - xbase = vsetq_lane_s32(fx+dx+dx, xbase, 2); - xbase = vsetq_lane_s32(fx+dx+dx+dx, xbase, 3); - - /* same for fy */ - /* avoid the 'ybase unitialized' warning...*/ - ybase = vdupq_n_s32(fy); - ybase = vsetq_lane_s32(fy+dy, ybase, 1); - ybase = vsetq_lane_s32(fy+dy+dy, ybase, 2); - ybase = vsetq_lane_s32(fy+dy+dy+dy, ybase, 3); - - x2base = vaddq_s32(xbase, vdupq_n_s32(dx4)); - y2base = vaddq_s32(ybase, vdupq_n_s32(dy4)); - - /* store & bump */ - do { - int32x4_t xout, yout; - int32x4_t x2out, y2out; - int16x8_t hi16, hi16_2; - - xout = xbase; - yout = ybase; - - /* overlay y's low16 with hi16 from x */ - /* so we properly shifted xyxyxyxy */ - yout = vsriq_n_s32(yout, xout, 16); - hi16 = vreinterpretq_s16_s32 (yout); - - /* do the clamping; both guys get 0's */ - hi16 = vmaxq_s16 (hi16, vdupq_n_s16(0)); - hi16 = vminq_s16 (hi16, maxXY); - - vst1q_s16 (dst16, hi16); - - /* and for the other 4 pieces of this iteration */ - x2out = x2base; - y2out = y2base; - - /* overlay y's low16 with hi16 from x */ - /* so we properly shifted xyxyxyxy */ - y2out = vsriq_n_s32(y2out, x2out, 16); - hi16_2 = vreinterpretq_s16_s32 (y2out); - - /* do the clamping; both guys get 0's */ - hi16_2 = vmaxq_s16 (hi16_2, vdupq_n_s16(0)); - hi16_2 = vminq_s16 (hi16_2, maxXY); - - /* RBE: gcc regenerates dst16+8 all the time instead - * of folding it into an addressing mode. *sigh* */ - vst1q_s16 (dst16+8, hi16_2); - - /* moving base and on to the next */ - xbase = vaddq_s32 (xbase, vdupq_n_s32 (dx8)); - ybase = vaddq_s32 (ybase, vdupq_n_s32 (dy8)); - x2base = vaddq_s32 (x2base, vdupq_n_s32 (dx8)); - y2base = vaddq_s32 (y2base, vdupq_n_s32 (dy8)); - - dst16 += 16; /* 8x32 aka 16x16 */ - count -= 8; - fx += dx8; - fy += dy8; - } while (count >= 8); - xy = (uint32_t *) dst16; - } - - for (int i = count; i > 0; --i) { - *xy++ = (TILEY_PROCF(fy, maxY) << 16) | TILEX_PROCF(fx, maxX); - fx += dx; fy += dy; - } -} - -#undef DEBUG_PERSP_NOFILTER - -static void PERSP_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t* SK_RESTRICT xy, - int count, int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); - - PREAMBLE(s); - /* max{X,Y} are int here, but later shown/assumed to fit in 16 bits */ - int maxX = s.fBitmap->width() - 1; - int maxY = s.fBitmap->height() - 1; - - SkPerspIter iter(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, count); - - while ((count = iter.next()) != 0) { - const SkFixed* SK_RESTRICT srcXY = iter.getXY(); - -#if defined(DEBUG_PERSP_NOFILTER) - /* debugging stuff */ - const SkFixed *end_srcXY = srcXY + (count*2); - uint32_t *end_xy = xy + (count); - const SkFixed *base_srcXY = srcXY; - uint32_t *base_xy = xy; - int base_count = count; -#endif - -#if 1 - // 2009/9/30: crashes in ApiDemos - Views - Animation - 3D Transition - // 2009/10/9: reworked to avoid illegal (but allowed by gas) insn - - /* srcXY is a batch of 32 bit numbers X0,Y0,X1,Y1... - * but we immediately discard the low 16 bits... - * so what we're going to do is vld4, which will give us - * xlo,xhi,ylo,yhi distribution and we can ignore the 'lo' - * parts.... - */ - if (count >= 8) { - int16_t *mysrc = (int16_t *) srcXY; - int16_t *mydst = (int16_t *) xy; - int16x4_t maxX4 = vdup_n_s16((int16_t)maxX); - int16x4_t maxY4 = vdup_n_s16((int16_t)maxY); - int16x4_t zero4 = vdup_n_s16(0); - - /* The constructs with local blocks for register assignments - * and asm() instructions is to make keep any hard register - * assignments to as small a scope as possible. and to avoid - * burning call-preserved hard registers on the vld/vst - * instructions. - */ - - do { - int16x4_t xhi, yhi; - int16x4_t x2hi, y2hi; - - /* vld4 does the de-interleaving for us */ - { - register int16x4_t t_xlo asm("d0"); - register int16x4_t t_xhi asm("d1"); - register int16x4_t t_ylo asm("d2"); - register int16x4_t t_yhi asm("d3"); - - asm ("vld4.16 {d0-d3},[%4] /* xlo=%P0 xhi=%P1 ylo=%P2 yhi=%P3 */" - : "=w" (t_xlo), "=w" (t_xhi), "=w" (t_ylo), "=w" (t_yhi) - : "r" (mysrc) - ); - xhi = t_xhi; - yhi = t_yhi; - } - - /* clamp X>>16 (aka xhi) to 0..maxX */ - xhi = vmax_s16(xhi, zero4); /* now 0.. */ - xhi = vmin_s16(xhi, maxX4); /* now 0..maxX */ - - /* clamp Y>>16 (aka yhi) to 0..maxY */ - yhi = vmax_s16(yhi, zero4); /* now 0.. */ - yhi = vmin_s16(yhi, maxY4); /* now 0..maxY */ - - /* deal with the second set of numbers */ - { - register int16x4_t t_xlo asm("d4"); - register int16x4_t t_xhi asm("d5"); - register int16x4_t t_ylo asm("d6"); - register int16x4_t t_yhi asm("d7"); - - /* offset == 256 bits == 32 bytes == 8 longs == 16 shorts */ - asm ("vld4.16 {d4-d7},[%4] /* xlo=%P0 xhi=%P1 ylo=%P2 yhi=%P3 */" - : "=w" (t_xlo), "=w" (t_xhi), "=w" (t_ylo), "=w" (t_yhi) - : "r" (mysrc+16) - ); - x2hi = t_xhi; - y2hi = t_yhi; - } - - /* clamp the second 4 here */ - - if (0) { extern void rbe(void); rbe(); } - - /* clamp X>>16 (aka xhi) to 0..maxX */ - x2hi = vmax_s16(x2hi, zero4); /* now 0.. */ - x2hi = vmin_s16(x2hi, maxX4); /* now 0..maxX */ - - /* clamp Y>>16 (aka yhi) to 0..maxY */ - y2hi = vmax_s16(y2hi, zero4); /* now 0.. */ - y2hi = vmin_s16(y2hi, maxY4); /* now 0..maxY */ - - /* we're storing as {x,y}s: x is [0], y is [1] */ - /* we'll use vst2 to make this happen */ - - { - register int16x4_t out_x asm("d16") = xhi; - register int16x4_t out_y asm("d17") = yhi; - - asm ("vst2.16 {d16-d17},[%2] /* xlo=%P0 xhi=%P1 */" - : - : "w" (out_x), "w" (out_y), "r" (mydst) - ); - } - { - register int16x4_t out_x asm("d18") = x2hi; - register int16x4_t out_y asm("d19") = y2hi; - - asm ("vst2.16 {d18-d19},[%2] /* xlo=%P0 xhi=%P1 */" - : - : "w" (out_x), "w" (out_y), "r" (mydst+8) - ); - } - - /* XXX: gcc isn't interleaving these with the NEON ops - * but i think that all the scoreboarding works out */ - count -= 8; /* 8 iterations */ - mysrc += 32; /* 16 longs, aka 32 shorts */ - mydst += 16; /* 16 shorts, aka 8 longs */ - } while (count >= 8); - /* get xy and srcXY fixed up */ - srcXY = (const SkFixed *) mysrc; - xy = (uint32_t *) mydst; - } -#endif - - while (--count >= 0) { - *xy++ = (TILEY_PROCF(srcXY[1], maxY) << 16) | - TILEX_PROCF(srcXY[0], maxX); - srcXY += 2; - } - -#if defined(DEBUG_PERSP_NOFILTER) - /* for checking our NEON-produced results against vanilla code */ - { - int bad = (-1); - for (int i = 0; i < base_count; i++) { - uint32_t val; - val = (TILEY_PROCF (base_srcXY[i * 2 + 1], maxY) << 16) | - TILEX_PROCF (base_srcXY[i * 2 + 0], maxX); - - if (val != base_xy[i]) { - bad = i; - break; - } - } - if (bad >= 0) { - SkDebugf("clamp-nofilter-persp failed piece %d\n", bad); - SkDebugf(" maxX %08x maxY %08x\n", maxX, maxY); - bad -= (bad & 0x7); /* align */ - for (int i = bad; i < bad + 8; i++) { - uint32_t val; - val = (TILEY_PROCF (base_srcXY[i * 2 + 1], maxY) << 16) | - TILEX_PROCF (base_srcXY[i * 2 + 0], maxX); - - SkDebugf("%d: got %08x want %08x srcXY[0] %08x srcXY[1] %08x\n", - i, base_xy[i], val, base_srcXY[i * 2 + 0], - base_srcXY[i * 2 + 1]); - } - SkDebugf ("---\n"); - } - - if (end_xy != xy) { - SkDebugf("xy ended at %08x, should be %08x\n", xy, end_xy); - } - if (end_srcXY != srcXY) { - SkDebugf("srcXY ended at %08x, should be %08x\n", srcXY, - end_srcXY); - } - } -#endif - } -} - -#undef DEBUG_PERSP_NOFILTER - -////////////////////////////////////////////////////////////////////////////// - -static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max, - SkFixed one PREAMBLE_PARAM_Y) { - unsigned i = TILEY_PROCF(f, max); - i = (i << 4) | TILEY_LOW_BITS(f, max); - return (i << 14) | (TILEY_PROCF((f + one), max)); -} - -static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max, - SkFixed one PREAMBLE_PARAM_X) { - unsigned i = TILEX_PROCF(f, max); - i = (i << 4) | TILEX_LOW_BITS(f, max); - return (i << 14) | (TILEX_PROCF((f + one), max)); -} - -static void SCALE_FILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask)) == 0); - SkASSERT(s.fInvKy == 0); - - PREAMBLE(s); - - const unsigned maxX = s.fBitmap->width() - 1; - const SkFixed one = s.fFilterOneX; - const SkFixed dx = s.fInvSx; - SkFixed fx; - - { - SkPoint pt; - s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &pt); - const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1); - const unsigned maxY = s.fBitmap->height() - 1; - // compute our two Y values up front - *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y); - // now initialize fx - fx = SkScalarToFixed(pt.fX) - (one >> 1); - } - -#ifdef CHECK_FOR_DECAL - // test if we don't need to apply the tile proc - if (dx > 0 && - (unsigned)(fx >> 16) <= maxX && - (unsigned)((fx + dx * (count - 1)) >> 16) < maxX) { - decal_filter_scale_neon(xy, fx, dx, count); - } else -#endif - - if (count >= 4) { - int32x4_t wide_one, wide_fx, wide_fx1, wide_i, wide_lo; - #if 0 - /* verification hooks -- see below */ - SkFixed debug_fx = fx; - int count_done = 0; - #endif - - wide_fx = vdupq_n_s32(fx); - wide_fx = vsetq_lane_s32(fx+dx, wide_fx, 1); - wide_fx = vsetq_lane_s32(fx+dx+dx, wide_fx, 2); - wide_fx = vsetq_lane_s32(fx+dx+dx+dx, wide_fx, 3); - - wide_one = vdupq_n_s32(one); - - while (count >= 4) { - /* original expands to: - * unsigned i = SkClampMax((f) >> 16, max); - * i = (i << 4) | (((f) >> 12) & 0xF); - * return (i << 14) | (SkClampMax(((f + one)) >> 16, max)); - */ - - /* i = SkClampMax(f>>16, maxX) */ - wide_i = vmaxq_s32(vshrq_n_s32(wide_fx,16), vdupq_n_s32(0)); - wide_i = vminq_s32(wide_i, vdupq_n_s32(maxX)); - - /* i<<4 | TILEX_LOW_BITS(fx) */ - wide_lo = vshrq_n_s32(wide_fx, 12); - wide_i = vsliq_n_s32(wide_lo, wide_i, 4); - - /* i<<14 */ - wide_i = vshlq_n_s32(wide_i, 14); - - /* SkClampMax(((f + one)) >> 16, max) */ - wide_fx1 = vaddq_s32(wide_fx, wide_one); - wide_fx1 = vmaxq_s32(vshrq_n_s32(wide_fx1,16), vdupq_n_s32(0)); - wide_fx1 = vminq_s32(wide_fx1, vdupq_n_s32(maxX)); - - /* final combination */ - wide_i = vorrq_s32(wide_i, wide_fx1); - - vst1q_u32(xy, vreinterpretq_u32_s32(wide_i)); - - #if 0 - /* having a verification hook is a good idea */ - /* use debug_fx, debug_fx+dx, etc. */ - - for (int i=0;i<4;i++) { - uint32_t want = PACK_FILTER_X_NAME(debug_fx, maxX, one PREAMBLE_ARG_X); - if (xy[i] != want) - { - /* print a nastygram */ - SkDebugf("clamp-filter-scale fails\n"); - SkDebugf("got %08x want %08x\n", xy[i], want); - SkDebugf("fx %08x debug_fx %08x dx %08x done %d\n", - fx, debug_fx, dx, count_done); - SkDebugf(" maxX %08x one %08x\n", maxX, one); - - } - debug_fx += dx; - count_done++; - } - #endif - wide_fx += vdupq_n_s32(dx+dx+dx+dx); - fx += dx+dx+dx+dx; - xy += 4; - count -= 4; - } - } - - while (--count >= 0) { - *xy++ = PACK_FILTER_X_NAME(fx, maxX, one PREAMBLE_ARG_X); - fx += dx; - } -} - -static void AFFINE_FILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask | - SkMatrix::kAffine_Mask)) == 0); - - PREAMBLE(s); - SkPoint srcPt; - s.fInvProc(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - - SkFixed oneX = s.fFilterOneX; - SkFixed oneY = s.fFilterOneY; - SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1); - SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1); - SkFixed dx = s.fInvSx; - SkFixed dy = s.fInvKy; - unsigned maxX = s.fBitmap->width() - 1; - unsigned maxY = s.fBitmap->height() - 1; - - if (count >= 4) { - int32x4_t wide_i, wide_lo; - int32x4_t wide_fx, wide_onex, wide_fx1; - int32x4_t wide_fy, wide_oney, wide_fy1; - - #undef AFFINE_DEBUG - #if defined(AFFINE_DEBUG) - SkFixed fyp = fy; - SkFixed fxp = fx; - uint32_t *xyp = xy; - int count_done = 0; - #endif - - wide_fx = vdupq_n_s32(fx); - wide_fx = vsetq_lane_s32(fx+dx, wide_fx, 1); - wide_fx = vsetq_lane_s32(fx+dx+dx, wide_fx, 2); - wide_fx = vsetq_lane_s32(fx+dx+dx+dx, wide_fx, 3); - - wide_fy = vdupq_n_s32(fy); - wide_fy = vsetq_lane_s32(fy+dy, wide_fy, 1); - wide_fy = vsetq_lane_s32(fy+dy+dy, wide_fy, 2); - wide_fy = vsetq_lane_s32(fy+dy+dy+dy, wide_fy, 3); - - wide_onex = vdupq_n_s32(oneX); - wide_oney = vdupq_n_s32(oneY); - - while (count >= 4) { - int32x4_t wide_x; - int32x4_t wide_y; - - /* do the X side, then the Y side, then interleave them */ - - /* original expands to: - * unsigned i = SkClampMax((f) >> 16, max); - * i = (i << 4) | (((f) >> 12) & 0xF); - * return (i << 14) | (SkClampMax(((f + one)) >> 16, max)); - */ - - /* i = SkClampMax(f>>16, maxX) */ - wide_i = vmaxq_s32(vshrq_n_s32(wide_fx,16), vdupq_n_s32(0)); - wide_i = vminq_s32(wide_i, vdupq_n_s32(maxX)); - - /* i<<4 | TILEX_LOW_BITS(fx) */ - wide_lo = vshrq_n_s32(wide_fx, 12); - wide_i = vsliq_n_s32(wide_lo, wide_i, 4); - - /* i<<14 */ - wide_i = vshlq_n_s32(wide_i, 14); - - /* SkClampMax(((f + one)) >> 16, max) */ - wide_fx1 = vaddq_s32(wide_fx, wide_onex); - wide_fx1 = vmaxq_s32(vshrq_n_s32(wide_fx1,16), vdupq_n_s32(0)); - wide_fx1 = vminq_s32(wide_fx1, vdupq_n_s32(maxX)); - - /* final combination */ - wide_x = vorrq_s32(wide_i, wide_fx1); - - /* And now the Y side */ - - /* i = SkClampMax(f>>16, maxX) */ - wide_i = vmaxq_s32(vshrq_n_s32(wide_fy,16), vdupq_n_s32(0)); - wide_i = vminq_s32(wide_i, vdupq_n_s32(maxY)); - - /* i<<4 | TILEX_LOW_BITS(fx) */ - wide_lo = vshrq_n_s32(wide_fy, 12); - wide_i = vsliq_n_s32(wide_lo, wide_i, 4); - - /* i<<14 */ - wide_i = vshlq_n_s32(wide_i, 14); - - /* SkClampMax(((f + one)) >> 16, max) */ - wide_fy1 = vaddq_s32(wide_fy, wide_oney); - wide_fy1 = vmaxq_s32(vshrq_n_s32(wide_fy1,16), vdupq_n_s32(0)); - wide_fy1 = vminq_s32(wide_fy1, vdupq_n_s32(maxY)); - - /* final combination */ - wide_y = vorrq_s32(wide_i, wide_fy1); - - /* interleave as YXYXYXYX as part of the storing */ - { - /* vst2.32 needs side-by-side registers */ - register int32x4_t t_x asm("q1"); - register int32x4_t t_y asm("q0"); - - t_x = wide_x; t_y = wide_y; - asm ("vst2.32 {q0-q1},[%2] /* y=%q0 x=%q1 */" - : - : "w" (t_y), "w" (t_x), "r" (xy) - ); - } - - #if defined(AFFINE_DEBUG) - /* make sure we're good here -- check the 4 we just output */ - for (int i = 0; i<4;i++) { - uint32_t val; - val = PACK_FILTER_Y_NAME(fyp, maxY, oneY PREAMBLE_ARG_Y); - if (val != xy[i*2+0]) { - /* print a nastygram */ - SkDebugf("clamp-filter-affine fails\n"); - SkDebugf("[bad-y] got %08x want %08x\n", xy[i*2+0], val); - SkDebugf("fy %08x fxp %08x fyp %08x dx %08x dy %08x done %d\n", - fy, fxp, fyp, dx, dy, count_done); - SkDebugf(" maxY %08x oneY %08x\n", maxY, oneY); - } - val = PACK_FILTER_X_NAME(fxp, maxX, oneX PREAMBLE_ARG_X); - if (val != xy[i*2+1]) { - /* print a nastygram */ - SkDebugf("clamp-filter-affine fails\n"); - SkDebugf("[bad-x] got %08x want %08x\n", xy[i*2+1], val); - SkDebugf("fx %08x fxp %08x fyp %08x dx %08x dy %08x done %d\n", - fx, fxp, fyp, dx, dy, count_done); - SkDebugf(" maxX %08x one %08x\n", maxX, oneX); - } - fyp += dy; - fxp += dx; - count_done++; - } - #endif - - wide_fx += vdupq_n_s32(dx+dx+dx+dx); - fx += dx+dx+dx+dx; - wide_fy += vdupq_n_s32(dy+dy+dy+dy); - fy += dy+dy+dy+dy; - xy += 8; /* 4 x's, 4 y's */ - count -= 4; - } - } - - while (--count >= 0) { - /* NB: writing Y/X */ - *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y); - fy += dy; - *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X); - fx += dx; - } -} - -static void PERSP_FILTER_NAME(const SkBitmapProcState& s, - uint32_t* SK_RESTRICT xy, int count, - int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); - - PREAMBLE(s); - unsigned maxX = s.fBitmap->width() - 1; - unsigned maxY = s.fBitmap->height() - 1; - SkFixed oneX = s.fFilterOneX; - SkFixed oneY = s.fFilterOneY; - - SkPerspIter iter(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, count); - - while ((count = iter.next()) != 0) { - const SkFixed* SK_RESTRICT srcXY = iter.getXY(); - - if (count >= 4) { - int32x4_t wide_i, wide_lo; - int32x4_t wide_fx1; - int32x4_t wide_fy1; - int32x4_t wide_x, wide_y; - - while (count >= 4) { - /* RBE: it's good, but: - * -- we spill a constant that could be easily regnerated - * [perhaps tweak gcc's NEON constant costs?] - */ - - /* load src: x-y-x-y-x-y-x-y */ - { - register int32x4_t q0 asm ("q0"); - register int32x4_t q1 asm ("q1"); - asm ("vld2.32 {q0-q1},[%2] /* x=%q0 y=%q1 */" - : "=w" (q0), "=w" (q1) - : "r" (srcXY)); - wide_x = q0; wide_y = q1; - } - - /* do the X side, then the Y side, then interleave them */ - - wide_x = vsubq_s32(wide_x, vdupq_n_s32 (oneX>>1)); - - /* original expands to: - * unsigned i = SkClampMax((f) >> 16, max); - * i = (i << 4) | (((f) >> 12) & 0xF); - * return (i << 14) | (SkClampMax(((f + one)) >> 16, max)); - */ - - /* i = SkClampMax(f>>16, maxX) */ - wide_i = vmaxq_s32 (vshrq_n_s32 (wide_x, 16), vdupq_n_s32 (0)); - wide_i = vminq_s32 (wide_i, vdupq_n_s32 (maxX)); - - /* i<<4 | TILEX_LOW_BITS(fx) */ - wide_lo = vshrq_n_s32 (wide_x, 12); - wide_i = vsliq_n_s32 (wide_lo, wide_i, 4); - - /* i<<14 */ - wide_i = vshlq_n_s32 (wide_i, 14); - - /* SkClampMax(((f + one)) >> 16, max) */ - wide_fx1 = vaddq_s32 (wide_x, vdupq_n_s32(oneX)); - wide_fx1 = vmaxq_s32 (vshrq_n_s32 (wide_fx1, 16), vdupq_n_s32 (0)); - wide_fx1 = vminq_s32 (wide_fx1, vdupq_n_s32 (maxX)); - - /* final combination */ - wide_x = vorrq_s32 (wide_i, wide_fx1); - - - /* And now the Y side */ - - wide_y = vsubq_s32(wide_y, vdupq_n_s32 (oneY>>1)); - - /* i = SkClampMax(f>>16, maxX) */ - wide_i = vmaxq_s32 (vshrq_n_s32 (wide_y, 16), vdupq_n_s32 (0)); - wide_i = vminq_s32 (wide_i, vdupq_n_s32 (maxY)); - - /* i<<4 | TILEX_LOW_BITS(fx) */ - wide_lo = vshrq_n_s32 (wide_y, 12); - wide_i = vsliq_n_s32 (wide_lo, wide_i, 4); - - /* i<<14 */ - wide_i = vshlq_n_s32 (wide_i, 14); - - /* SkClampMax(((f + one)) >> 16, max) */ - - /* wide_fy1_1 and wide_fy1_2 are just temporary variables to - * work-around an ICE in debug */ - int32x4_t wide_fy1_1 = vaddq_s32 (wide_y, vdupq_n_s32(oneY)); - int32x4_t wide_fy1_2 = vmaxq_s32 (vshrq_n_s32 (wide_fy1_1, 16), - vdupq_n_s32 (0)); - wide_fy1 = vminq_s32 (wide_fy1_2, vdupq_n_s32 (maxY)); - - /* final combination */ - wide_y = vorrq_s32 (wide_i, wide_fy1); - - /* switch them around; have to do it this way to get them - * in the proper registers to match our instruction */ - - /* iteration bookkeeping, ahead of the asm() for scheduling */ - srcXY += 2*4; - count -= 4; - - /* store interleaved as y-x-y-x-y-x-y-x (NB != read order) */ - { - register int32x4_t q0 asm ("q0") = wide_y; - register int32x4_t q1 asm ("q1") = wide_x; - - asm ("vst2.32 {q0-q1},[%2] /* y=%q0 x=%q1 */" - : - : "w" (q0), "w" (q1), "r" (xy)); - } - - /* on to the next iteration */ - /* count, srcXY are handled above */ - xy += 2*4; - } - } - - /* was do-while; NEON code invalidates original count>0 assumption */ - while (--count >= 0) { - /* NB: we read x/y, we write y/x */ - *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY, - oneY PREAMBLE_ARG_Y); - *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX, - oneX PREAMBLE_ARG_X); - srcXY += 2; - } - } -} - -const SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = { - SCALE_NOFILTER_NAME, - SCALE_FILTER_NAME, - AFFINE_NOFILTER_NAME, - AFFINE_FILTER_NAME, - PERSP_NOFILTER_NAME, - PERSP_FILTER_NAME -}; - -#undef MAKENAME -#undef TILEX_PROCF -#undef TILEY_PROCF -#ifdef CHECK_FOR_DECAL - #undef CHECK_FOR_DECAL -#endif - -#undef SCALE_NOFILTER_NAME -#undef SCALE_FILTER_NAME -#undef AFFINE_NOFILTER_NAME -#undef AFFINE_FILTER_NAME -#undef PERSP_NOFILTER_NAME -#undef PERSP_FILTER_NAME - -#undef PREAMBLE -#undef PREAMBLE_PARAM_X -#undef PREAMBLE_PARAM_Y -#undef PREAMBLE_ARG_X -#undef PREAMBLE_ARG_Y - -#undef TILEX_LOW_BITS -#undef TILEY_LOW_BITS diff --git a/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_neon.h b/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_neon.h index aab9dbc61e36..72bf1bce3365 100644 --- a/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_neon.h +++ b/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_neon.h @@ -31,15 +31,15 @@ static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, // we store y, x, x, x, x, x const unsigned maxX = s.fBitmap->width() - 1; - SkFixed fx; + SkFractionalInt fx; { SkPoint pt; s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &pt); - fx = SkScalarToFixed(pt.fY); + fx = SkScalarToFractionalInt(pt.fY); const unsigned maxY = s.fBitmap->height() - 1; - *xy++ = TILEY_PROCF(fx, maxY); - fx = SkScalarToFixed(pt.fX); + *xy++ = TILEY_PROCF(SkFractionalIntToFixed(fx), maxY); + fx = SkScalarToFractionalInt(pt.fX); } if (0 == maxX) { @@ -48,23 +48,24 @@ static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, return; } - const SkFixed dx = s.fInvSx; + const SkFractionalInt dx = s.fInvSxFractionalInt; #ifdef CHECK_FOR_DECAL // test if we don't need to apply the tile proc if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { - decal_nofilter_scale_neon(xy, fx, dx, count); + decal_nofilter_scale_neon(xy, SkFractionalIntToFixed(fx), + SkFractionalIntToFixed(dx), count); return; } #endif if (count >= 8) { - SkFixed dx2 = dx+dx; - SkFixed dx4 = dx2+dx2; - SkFixed dx8 = dx4+dx4; + SkFractionalInt dx2 = dx+dx; + SkFractionalInt dx4 = dx2+dx2; + SkFractionalInt dx8 = dx4+dx4; // now build fx/fx+dx/fx+2dx/fx+3dx - SkFixed fx1, fx2, fx3; + SkFractionalInt fx1, fx2, fx3; int32x4_t lbase, hbase; int16_t *dst16 = (int16_t *)xy; @@ -72,11 +73,11 @@ static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, fx2 = fx1+dx; fx3 = fx2+dx; - lbase = vdupq_n_s32(fx); - lbase = vsetq_lane_s32(fx1, lbase, 1); - lbase = vsetq_lane_s32(fx2, lbase, 2); - lbase = vsetq_lane_s32(fx3, lbase, 3); - hbase = vaddq_s32(lbase, vdupq_n_s32(dx4)); + lbase = vdupq_n_s32(SkFractionalIntToFixed(fx)); + lbase = vsetq_lane_s32(SkFractionalIntToFixed(fx1), lbase, 1); + lbase = vsetq_lane_s32(SkFractionalIntToFixed(fx2), lbase, 2); + lbase = vsetq_lane_s32(SkFractionalIntToFixed(fx3), lbase, 3); + hbase = vaddq_s32(lbase, vdupq_n_s32(SkFractionalIntToFixed(dx4))); // store & bump while (count >= 8) { @@ -88,8 +89,8 @@ static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, vst1q_s16(dst16, fx8); // but preserving base & on to the next - lbase = vaddq_s32 (lbase, vdupq_n_s32(dx8)); - hbase = vaddq_s32 (hbase, vdupq_n_s32(dx8)); + lbase = vaddq_s32 (lbase, vdupq_n_s32(SkFractionalIntToFixed(dx8))); + hbase = vaddq_s32 (hbase, vdupq_n_s32(SkFractionalIntToFixed(dx8))); dst16 += 8; count -= 8; fx += dx8; @@ -99,7 +100,7 @@ static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, uint16_t* xx = (uint16_t*)xy; for (int i = count; i > 0; --i) { - *xx++ = TILEX_PROCF(fx, maxX); + *xx++ = TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; } } @@ -117,37 +118,37 @@ static void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - SkFixed fx = SkScalarToFixed(srcPt.fX); - SkFixed fy = SkScalarToFixed(srcPt.fY); - SkFixed dx = s.fInvSx; - SkFixed dy = s.fInvKy; + SkFractionalInt fx = SkScalarToFractionalInt(srcPt.fX); + SkFractionalInt fy = SkScalarToFractionalInt(srcPt.fY); + SkFractionalInt dx = s.fInvSxFractionalInt; + SkFractionalInt dy = s.fInvKyFractionalInt; int maxX = s.fBitmap->width() - 1; int maxY = s.fBitmap->height() - 1; if (count >= 8) { - SkFixed dx4 = dx * 4; - SkFixed dy4 = dy * 4; - SkFixed dx8 = dx * 8; - SkFixed dy8 = dy * 8; + SkFractionalInt dx4 = dx * 4; + SkFractionalInt dy4 = dy * 4; + SkFractionalInt dx8 = dx * 8; + SkFractionalInt dy8 = dy * 8; int32x4_t xbase, ybase; int32x4_t x2base, y2base; int16_t *dst16 = (int16_t *) xy; // now build fx, fx+dx, fx+2dx, fx+3dx - xbase = vdupq_n_s32(fx); - xbase = vsetq_lane_s32(fx+dx, xbase, 1); - xbase = vsetq_lane_s32(fx+dx+dx, xbase, 2); - xbase = vsetq_lane_s32(fx+dx+dx+dx, xbase, 3); + xbase = vdupq_n_s32(SkFractionalIntToFixed(fx)); + xbase = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx), xbase, 1); + xbase = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx+dx), xbase, 2); + xbase = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx+dx+dx), xbase, 3); // same for fy - ybase = vdupq_n_s32(fy); - ybase = vsetq_lane_s32(fy+dy, ybase, 1); - ybase = vsetq_lane_s32(fy+dy+dy, ybase, 2); - ybase = vsetq_lane_s32(fy+dy+dy+dy, ybase, 3); + ybase = vdupq_n_s32(SkFractionalIntToFixed(fy)); + ybase = vsetq_lane_s32(SkFractionalIntToFixed(fy+dy), ybase, 1); + ybase = vsetq_lane_s32(SkFractionalIntToFixed(fy+dy+dy), ybase, 2); + ybase = vsetq_lane_s32(SkFractionalIntToFixed(fy+dy+dy+dy), ybase, 3); - x2base = vaddq_s32(xbase, vdupq_n_s32(dx4)); - y2base = vaddq_s32(ybase, vdupq_n_s32(dy4)); + x2base = vaddq_s32(xbase, vdupq_n_s32(SkFractionalIntToFixed(dx4))); + y2base = vaddq_s32(ybase, vdupq_n_s32(SkFractionalIntToFixed(dy4))); // store & bump do { @@ -159,10 +160,10 @@ static void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, vst2q_s16(dst16, hi16); // moving base and on to the next - xbase = vaddq_s32(xbase, vdupq_n_s32(dx8)); - ybase = vaddq_s32(ybase, vdupq_n_s32(dy8)); - x2base = vaddq_s32(x2base, vdupq_n_s32(dx8)); - y2base = vaddq_s32(y2base, vdupq_n_s32(dy8)); + xbase = vaddq_s32(xbase, vdupq_n_s32(SkFractionalIntToFixed(dx8))); + ybase = vaddq_s32(ybase, vdupq_n_s32(SkFractionalIntToFixed(dy8))); + x2base = vaddq_s32(x2base, vdupq_n_s32(SkFractionalIntToFixed(dx8))); + y2base = vaddq_s32(y2base, vdupq_n_s32(SkFractionalIntToFixed(dy8))); dst16 += 16; // 8x32 aka 16x16 count -= 8; @@ -173,7 +174,8 @@ static void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, } for (int i = count; i > 0; --i) { - *xy++ = (TILEY_PROCF(fy, maxY) << 16) | TILEX_PROCF(fx, maxX); + *xy++ = (TILEY_PROCF(SkFractionalIntToFixed(fy), maxY) << 16) | + TILEX_PROCF(SkFractionalIntToFixed(fx), maxX); fx += dx; fy += dy; } } @@ -293,8 +295,8 @@ static void SCALE_FILTER_NAME(const SkBitmapProcState& s, const unsigned maxX = s.fBitmap->width() - 1; const SkFixed one = s.fFilterOneX; - const SkFixed dx = s.fInvSx; - SkFixed fx; + const SkFractionalInt dx = s.fInvSxFractionalInt; + SkFractionalInt fx; { SkPoint pt; @@ -305,13 +307,14 @@ static void SCALE_FILTER_NAME(const SkBitmapProcState& s, // compute our two Y values up front *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y); // now initialize fx - fx = SkScalarToFixed(pt.fX) - (one >> 1); + fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1); } #ifdef CHECK_FOR_DECAL // test if we don't need to apply the tile proc if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { - decal_filter_scale_neon(xy, fx, dx, count); + decal_filter_scale_neon(xy, SkFractionalIntToFixed(fx), + SkFractionalIntToFixed(dx), count); return; } #endif @@ -320,10 +323,10 @@ static void SCALE_FILTER_NAME(const SkBitmapProcState& s, if (count >= 4) { int32x4_t wide_fx; - wide_fx = vdupq_n_s32(fx); - wide_fx = vsetq_lane_s32(fx+dx, wide_fx, 1); - wide_fx = vsetq_lane_s32(fx+dx+dx, wide_fx, 2); - wide_fx = vsetq_lane_s32(fx+dx+dx+dx, wide_fx, 3); + wide_fx = vdupq_n_s32(SkFractionalIntToFixed(fx)); + wide_fx = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx), wide_fx, 1); + wide_fx = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx+dx), wide_fx, 2); + wide_fx = vsetq_lane_s32(SkFractionalIntToFixed(fx+dx+dx+dx), wide_fx, 3); while (count >= 4) { int32x4_t res; @@ -332,7 +335,7 @@ static void SCALE_FILTER_NAME(const SkBitmapProcState& s, vst1q_u32(xy, vreinterpretq_u32_s32(res)); - wide_fx += vdupq_n_s32(dx+dx+dx+dx); + wide_fx += vdupq_n_s32(SkFractionalIntToFixed(dx+dx+dx+dx)); fx += dx+dx+dx+dx; xy += 4; count -= 4; @@ -340,7 +343,7 @@ static void SCALE_FILTER_NAME(const SkBitmapProcState& s, } while (--count >= 0) { - *xy++ = PACK_FILTER_X_NAME(fx, maxX, one PREAMBLE_ARG_X); + *xy++ = PACK_FILTER_X_NAME(SkFractionalIntToFixed(fx), maxX, one PREAMBLE_ARG_X); fx += dx; } diff --git a/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_repeat_neon.h b/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_repeat_neon.h deleted file mode 100644 index 55e2997a5efb..000000000000 --- a/gfx/skia/trunk/src/opts/SkBitmapProcState_matrix_repeat_neon.h +++ /dev/null @@ -1,542 +0,0 @@ -/* NEON optimized code (C) COPYRIGHT 2009 Motorola - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* - * Modifications done in-house at Motorola - * - * this is a clone of SkBitmapProcState_matrix.h - * and has been tuned to work with the NEON unit. - * - * Still going back and forth between whether this approach - * (clone the entire SkBitmapProcState_matrix.h file or - * if I should put just the modified routines in here and - * then use a construct like #define DONT_DO_THIS_FUNCTION or - * something like that... - * - * This is for the RepeatX_RepeatY part of the world - */ - - -#include - -/* - * This has been modified on the knowledge that (at the time) - * we had the following macro definitions in the parent file - * - * #define MAKENAME(suffix) RepeatX_RepeatY ## suffix - * #define TILEX_PROCF(fx, max) (((fx) & 0xFFFF) * ((max) + 1) >> 16) - * #define TILEY_PROCF(fy, max) (((fy) & 0xFFFF) * ((max) + 1) >> 16) - * #define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) - * #define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF) - */ - -/* SkClampMax(val,max) -- bound to 0..max */ - -#define SCALE_NOFILTER_NAME MAKENAME(_nofilter_scale) -#define SCALE_FILTER_NAME MAKENAME(_filter_scale) -#define AFFINE_NOFILTER_NAME MAKENAME(_nofilter_affine) -#define AFFINE_FILTER_NAME MAKENAME(_filter_affine) -#define PERSP_NOFILTER_NAME MAKENAME(_nofilter_persp) -#define PERSP_FILTER_NAME MAKENAME(_filter_persp) - -#define PACK_FILTER_X_NAME MAKENAME(_pack_filter_x) -#define PACK_FILTER_Y_NAME MAKENAME(_pack_filter_y) - -#ifndef PREAMBLE - #define PREAMBLE(state) - #define PREAMBLE_PARAM_X - #define PREAMBLE_PARAM_Y - #define PREAMBLE_ARG_X - #define PREAMBLE_ARG_Y -#endif - -static void SCALE_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask)) == 0); - - PREAMBLE(s); - // we store y, x, x, x, x, x - - const unsigned maxX = s.fBitmap->width() - 1; - SkFixed fx; - { - SkPoint pt; - s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &pt); - fx = SkScalarToFixed(pt.fY); - const unsigned maxY = s.fBitmap->height() - 1; - *xy++ = TILEY_PROCF(fx, maxY); - fx = SkScalarToFixed(pt.fX); - } - - if (0 == maxX) { - // all of the following X values must be 0 - memset(xy, 0, count * sizeof(uint16_t)); - return; - } - - const SkFixed dx = s.fInvSx; - -#ifdef CHECK_FOR_DECAL - // test if we don't need to apply the tile proc - if ((unsigned)(fx >> 16) <= maxX && - (unsigned)((fx + dx * (count - 1)) >> 16) <= maxX) { - decal_nofilter_scale_neon(xy, fx, dx, count); - } else -#endif - { - int i; - - /* RBE: very much like done in decal_nofilter , - * but some processing of the 'fx' information - * TILEX_PROCF(fx, max) (((fx) & 0xFFFF) * ((max) + 1) >> 16) - */ - if (count >= 8) { - /* SkFixed is 16.16 fixed point */ - SkFixed dx2 = dx+dx; - SkFixed dx4 = dx2+dx2; - SkFixed dx8 = dx4+dx4; - - /* now build fx/fx+dx/fx+2dx/fx+3dx */ - SkFixed fx1, fx2, fx3; - int32x4_t lbase, hbase; - int16_t *dst16 = (int16_t *)xy; - - fx1 = fx+dx; - fx2 = fx1+dx; - fx3 = fx2+dx; - - lbase = vdupq_n_s32(fx); - lbase = vsetq_lane_s32(fx1, lbase, 1); - lbase = vsetq_lane_s32(fx2, lbase, 2); - lbase = vsetq_lane_s32(fx3, lbase, 3); - hbase = vaddq_s32(lbase, vdupq_n_s32(dx4)); - - /* store & bump */ - do - { - int32x4_t lout; - int32x4_t hout; - int16x8_t hi16; - - /* TILEX_PROCF(fx, max) (((fx)&0xFFFF)*((max)+1)>> 16) */ - /* mask to low 16 [would like to use uzp tricks) */ - lout = vandq_s32(lbase, vdupq_n_s32(0xffff)); - hout = vandq_s32(hbase, vdupq_n_s32(0xffff)); - /* bare multiplication, not SkFixedMul */ - lout = vmulq_s32(lout, vdupq_n_s32(maxX+1)); - hout = vmulq_s32(hout, vdupq_n_s32(maxX+1)); - - /* extraction, using uzp */ - /* this is ok -- we want all hi(lout)s then all hi(hout)s */ - asm ("vuzpq.16 %q0, %q1" : "+w" (lout), "+w" (hout)); - hi16 = vreinterpretq_s16_s32(hout); - vst1q_s16(dst16, hi16); - - /* bump our base on to the next */ - lbase = vaddq_s32 (lbase, vdupq_n_s32(dx8)); - hbase = vaddq_s32 (hbase, vdupq_n_s32(dx8)); - dst16 += 8; - count -= 8; - fx += dx8; - } while (count >= 8); - xy = (uint32_t *) dst16; - } - uint16_t* xx = (uint16_t*)xy; - for (i = count; i > 0; --i) { - *xx++ = TILEX_PROCF(fx, maxX); fx += dx; - } - } -} - -// note: we could special-case on a matrix which is skewed in X but not Y. -// this would require a more general setup thatn SCALE does, but could use -// SCALE's inner loop that only looks at dx - - -static void AFFINE_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask | - SkMatrix::kAffine_Mask)) == 0); - - PREAMBLE(s); - SkPoint srcPt; - s.fInvProc(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - - SkFixed fx = SkScalarToFixed(srcPt.fX); - SkFixed fy = SkScalarToFixed(srcPt.fY); - SkFixed dx = s.fInvSx; - SkFixed dy = s.fInvKy; - int maxX = s.fBitmap->width() - 1; - int maxY = s.fBitmap->height() - 1; - -#if 0 - int ocount = count; - uint32_t *oxy = xy; - SkFixed bfx = fx, bfy=fy, bdx=dx, bdy=dy; -#endif - - - if (0) { extern void rbe(void); rbe(); } - - /* RBE: benchmarks show this eats up time; can we neonize it? */ - /* RBE: very much like done in decal_nofilter , - * but some processing of the 'fx' information - * TILEX_PROCF(fx, max) (((fx) & 0xFFFF) * ((max) + 1) >> 16) - */ - if (count >= 4) { - /* SkFixed is 16.16 fixed point */ - SkFixed dx4 = dx*4; - SkFixed dy4 = dy*4; - - /* now build fx/fx+dx/fx+2dx/fx+3dx */ - int32x4_t xbase, ybase; - int16_t *dst16 = (int16_t *)xy; - - /* synthesize 4x for both X and Y */ - xbase = vdupq_n_s32(fx); - xbase = vsetq_lane_s32(fx+dx, xbase, 1); - xbase = vsetq_lane_s32(fx+dx+dx, xbase, 2); - xbase = vsetq_lane_s32(fx+dx+dx+dx, xbase, 3); - - ybase = vdupq_n_s32(fy); - ybase = vsetq_lane_s32(fy+dy, ybase, 1); - ybase = vsetq_lane_s32(fy+dy+dy, ybase, 2); - ybase = vsetq_lane_s32(fy+dy+dy+dy, ybase, 3); - - /* store & bump */ - do { - int32x4_t xout; - int32x4_t yout; - int16x8_t hi16; - - /* TILEX_PROCF(fx, max) (((fx)&0xFFFF)*((max)+1)>> 16) */ - /* mask to low 16 [would like to use uzp tricks) */ - xout = vandq_s32(xbase, vdupq_n_s32(0xffff)); - yout = vandq_s32(ybase, vdupq_n_s32(0xffff)); - /* bare multiplication, not SkFixedMul */ - xout = vmulq_s32(xout, vdupq_n_s32(maxX+1)); - yout = vmulq_s32(yout, vdupq_n_s32(maxY+1)); - - /* put hi16 from xout over low16 from yout */ - yout = vsriq_n_s32(yout, xout, 16); - - /* and then yout has the interleaved upper 16's */ - hi16 = vreinterpretq_s16_s32(yout); - vst1q_s16(dst16, hi16); - - /* bump preserved base & on to the next */ - xbase = vaddq_s32 (xbase, vdupq_n_s32(dx4)); - ybase = vaddq_s32 (ybase, vdupq_n_s32(dy4)); - dst16 += 8; /* 8 x16 aka 4x32 */ - count -= 4; - fx += dx4; - fy += dy4; - } while (count >= 4); - xy = (uint32_t *) dst16; - } - -#if 0 - /* diagnostics... see whether we agree with the NEON code */ - int bad = 0; - uint32_t *myxy = oxy; - int myi = (-1); - SkFixed ofx = bfx, ofy= bfy, odx= bdx, ody= bdy; - for (myi = ocount; myi > 0; --myi) { - uint32_t val = (TILEY_PROCF(ofy, maxY) << 16) | TILEX_PROCF(ofx, maxX); - if (val != *myxy++) { - bad++; - break; - } - ofx += odx; ofy += ody; - } - if (bad) { - SkDebugf("repeat-nofilter-affine fails\n"); - SkDebugf("count %d myi %d\n", ocount, myi); - SkDebugf(" bfx %08x, bdx %08x, bfy %08x bdy %08x\n", - bfx, bdx, bfy, bdy); - SkDebugf("maxX %08x maxY %08x\n", maxX, maxY); - } -#endif - - for (int i = count; i > 0; --i) { - /* fx, fy, dx, dy are all 32 bit 16.16 fixed point */ - /* (((fx) & 0xFFFF) * ((max) + 1) >> 16) */ - *xy++ = (TILEY_PROCF(fy, maxY) << 16) | TILEX_PROCF(fx, maxX); - fx += dx; fy += dy; - } -} - -static void PERSP_NOFILTER_NAME(const SkBitmapProcState& s, - uint32_t* SK_RESTRICT xy, - int count, int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); - - PREAMBLE(s); - int maxX = s.fBitmap->width() - 1; - int maxY = s.fBitmap->height() - 1; - - SkPerspIter iter(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, count); - - while ((count = iter.next()) != 0) { - const SkFixed* SK_RESTRICT srcXY = iter.getXY(); - - /* RBE: */ - /* TILEX_PROCF(fx, max) (((fx) & 0xFFFF) * ((max) + 1) >> 16) */ - /* it's a little more complicated than what I did for the - * clamp case -- where I could immediately snip to the top - * 16 bits and do my min/max games there. - * ... might only be able to get 4x unrolling here - */ - - /* vld2 to get a set of 32x4's ... */ - /* do the tile[xy]_procf operations */ - /* which includes doing vuzp to get hi16's */ - /* store it */ - /* -- inner loop (other than vld2) can be had from above */ - - /* srcXY is a batch of 32 bit numbers X0,Y0,X1,Y1... - * but we immediately discard the low 16 bits... - * so what we're going to do is vld4, which will give us - * xlo,xhi,ylo,yhi distribution and we can ignore the 'lo' - * parts.... - */ - if (0) { extern void rbe(void); rbe(); } - if (count >= 8) { - int32_t *mysrc = (int32_t *) srcXY; - int16_t *mydst = (int16_t *) xy; - do { - int32x4_t x, y, x2, y2; - int16x8_t hi, hi2; - - /* read array of x,y,x,y,x,y */ - /* vld2 does the de-interleaving for us */ - /* isolate reg-bound scopes; gcc will minimize register - * motion if possible; this ensures that we don't lose - * a register across a debugging call because it happens - * to be bound into a call-clobbered register - */ - { - register int32x4_t q0 asm("q0"); - register int32x4_t q1 asm("q1"); - asm ("vld2.32 {q0-q1},[%2] /* x=%q0 y=%q1 */" - : "=w" (q0), "=w" (q1) - : "r" (mysrc) - ); - x = q0; y = q1; - } - - /* offset == 256 bits == 32 bytes == 8 longs */ - { - register int32x4_t q2 asm("q2"); - register int32x4_t q3 asm("q3"); - asm ("vld2.32 {q2-q3},[%2] /* x=%q0 y=%q1 */" - : "=w" (q2), "=w" (q3) - : "r" (mysrc+8) - ); - x2 = q2; y2 = q3; - } - - /* TILEX_PROCF(fx, max) (((fx)&0xFFFF)*((max)+1)>> 16) */ - /* mask to low 16 [would like to use uzp tricks) */ - /* bare multiplication, not SkFixedMul */ - x = vandq_s32(x, vdupq_n_s32(0xffff)); - x = vmulq_s32(x, vdupq_n_s32(maxX+1)); - y = vandq_s32(y, vdupq_n_s32(0xffff)); - y = vmulq_s32(y, vdupq_n_s32(maxY+1)); - - x2 = vandq_s32(x2, vdupq_n_s32(0xffff)); - x2 = vmulq_s32(x2, vdupq_n_s32(maxX+1)); - y2 = vandq_s32(y2, vdupq_n_s32(0xffff)); - y2 = vmulq_s32(y2, vdupq_n_s32(maxY+1)); - - /* now collect interleaved high 16's */ - /* (hi-x, hi-y)4 (hi-x2; hi-y2)4 */ - - /* extraction, using uzp, leaves hi16's in y */ - y = vsriq_n_s32(y, x, 16); - hi = vreinterpretq_s16_s32(y); - vst1q_s16(mydst, hi); - - /* and likewise for the second 8 entries */ - y2 = vsriq_n_s32(y2, x2, 16); - hi2 = vreinterpretq_s16_s32(y2); - vst1q_s16(mydst+8, hi2); - - /* XXX: gcc isn't interleaving these with the NEON ops - * but i think that all the scoreboarding works out */ - count -= 8; /* 8 iterations */ - mysrc += 16; /* 16 longs */ - mydst += 16; /* 16 shorts, aka 8 longs */ - } while (count >= 8); - /* get xy and srcXY fixed up */ - srcXY = (const SkFixed *) mysrc; - xy = (uint32_t *) mydst; - } - while (--count >= 0) { - *xy++ = (TILEY_PROCF(srcXY[1], maxY) << 16) | - TILEX_PROCF(srcXY[0], maxX); - srcXY += 2; - } - } -} - -////////////////////////////////////////////////////////////////////////////// - -static inline uint32_t PACK_FILTER_Y_NAME(SkFixed f, unsigned max, - SkFixed one PREAMBLE_PARAM_Y) { - unsigned i = TILEY_PROCF(f, max); - i = (i << 4) | TILEY_LOW_BITS(f, max); - return (i << 14) | (TILEY_PROCF((f + one), max)); -} - -static inline uint32_t PACK_FILTER_X_NAME(SkFixed f, unsigned max, - SkFixed one PREAMBLE_PARAM_X) { - unsigned i = TILEX_PROCF(f, max); - i = (i << 4) | TILEX_LOW_BITS(f, max); - return (i << 14) | (TILEX_PROCF((f + one), max)); -} - -static void SCALE_FILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask)) == 0); - SkASSERT(s.fInvKy == 0); - - PREAMBLE(s); - - const unsigned maxX = s.fBitmap->width() - 1; - const SkFixed one = s.fFilterOneX; - const SkFractionalInt dx = s.fInvSxFractionalInt; - SkFractionalInt fx; - - { - SkPoint pt; - s.fInvProc(s.fInvMatrix, SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &pt); - const SkFixed fy = SkScalarToFixed(pt.fY) - (s.fFilterOneY >> 1); - const unsigned maxY = s.fBitmap->height() - 1; - // compute our two Y values up front - *xy++ = PACK_FILTER_Y_NAME(fy, maxY, s.fFilterOneY PREAMBLE_ARG_Y); - // now initialize fx - fx = SkScalarToFractionalInt(pt.fX) - (SkFixedToFractionalInt(one) >> 1); - } - -#ifdef CHECK_FOR_DECAL - // test if we don't need to apply the tile proc - if (can_truncate_to_fixed_for_decal(fx, dx, count, maxX)) { - decal_filter_scale_neon(xy, SkFractionalIntToFixed(fx), - SkFractionalIntToFixed(dx), count); - } else -#endif - { - do { - SkFixed fixedFx = SkFractionalIntToFixed(fx); - *xy++ = PACK_FILTER_X_NAME(fixedFx, maxX, one PREAMBLE_ARG_X); - fx += dx; - } while (--count != 0); - } -} - -static void AFFINE_FILTER_NAME(const SkBitmapProcState& s, - uint32_t xy[], int count, int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kAffine_Mask); - SkASSERT((s.fInvType & ~(SkMatrix::kTranslate_Mask | - SkMatrix::kScale_Mask | - SkMatrix::kAffine_Mask)) == 0); - - PREAMBLE(s); - SkPoint srcPt; - s.fInvProc(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, &srcPt); - - SkFixed oneX = s.fFilterOneX; - SkFixed oneY = s.fFilterOneY; - SkFixed fx = SkScalarToFixed(srcPt.fX) - (oneX >> 1); - SkFixed fy = SkScalarToFixed(srcPt.fY) - (oneY >> 1); - SkFixed dx = s.fInvSx; - SkFixed dy = s.fInvKy; - unsigned maxX = s.fBitmap->width() - 1; - unsigned maxY = s.fBitmap->height() - 1; - - do { - *xy++ = PACK_FILTER_Y_NAME(fy, maxY, oneY PREAMBLE_ARG_Y); - fy += dy; - *xy++ = PACK_FILTER_X_NAME(fx, maxX, oneX PREAMBLE_ARG_X); - fx += dx; - } while (--count != 0); -} - -static void PERSP_FILTER_NAME(const SkBitmapProcState& s, - uint32_t* SK_RESTRICT xy, int count, - int x, int y) { - SkASSERT(s.fInvType & SkMatrix::kPerspective_Mask); - - extern void rbe(void); - - PREAMBLE(s); - unsigned maxX = s.fBitmap->width() - 1; - unsigned maxY = s.fBitmap->height() - 1; - SkFixed oneX = s.fFilterOneX; - SkFixed oneY = s.fFilterOneY; - - - - SkPerspIter iter(s.fInvMatrix, - SkIntToScalar(x) + SK_ScalarHalf, - SkIntToScalar(y) + SK_ScalarHalf, count); - - while ((count = iter.next()) != 0) { - const SkFixed* SK_RESTRICT srcXY = iter.getXY(); - do { - *xy++ = PACK_FILTER_Y_NAME(srcXY[1] - (oneY >> 1), maxY, - oneY PREAMBLE_ARG_Y); - *xy++ = PACK_FILTER_X_NAME(srcXY[0] - (oneX >> 1), maxX, - oneX PREAMBLE_ARG_X); - srcXY += 2; - } while (--count != 0); - } -} - -const SkBitmapProcState::MatrixProc MAKENAME(_Procs)[] = { - SCALE_NOFILTER_NAME, - SCALE_FILTER_NAME, - AFFINE_NOFILTER_NAME, - AFFINE_FILTER_NAME, - PERSP_NOFILTER_NAME, - PERSP_FILTER_NAME -}; - -#undef MAKENAME -#undef TILEX_PROCF -#undef TILEY_PROCF -#ifdef CHECK_FOR_DECAL - #undef CHECK_FOR_DECAL -#endif - -#undef SCALE_NOFILTER_NAME -#undef SCALE_FILTER_NAME -#undef AFFINE_NOFILTER_NAME -#undef AFFINE_FILTER_NAME -#undef PERSP_NOFILTER_NAME -#undef PERSP_FILTER_NAME - -#undef PREAMBLE -#undef PREAMBLE_PARAM_X -#undef PREAMBLE_PARAM_Y -#undef PREAMBLE_ARG_X -#undef PREAMBLE_ARG_Y - -#undef TILEX_LOW_BITS -#undef TILEY_LOW_BITS diff --git a/gfx/skia/trunk/src/opts/SkBitmapProcState_opts_SSSE3.cpp b/gfx/skia/trunk/src/opts/SkBitmapProcState_opts_SSSE3.cpp index f8342ecaad55..ddc8ccc5ab5f 100644 --- a/gfx/skia/trunk/src/opts/SkBitmapProcState_opts_SSSE3.cpp +++ b/gfx/skia/trunk/src/opts/SkBitmapProcState_opts_SSSE3.cpp @@ -5,11 +5,19 @@ * found in the LICENSE file. */ -#include // SSSE3 #include "SkBitmapProcState_opts_SSSE3.h" #include "SkPaint.h" #include "SkUtils.h" +/* With the exception of the Android framework we always build the SSSE3 functions + * and enable the caller to determine SSSE3 support. However for the Android framework + * if the device does not support SSSE3 then the compiler will not supply the required + * -mssse3 option needed to build this file, so instead we provide a stub implementation. + */ +#if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3 + +#include // SSSE3 + // adding anonymous namespace seemed to force gcc to inline directly the // instantiation, instead of creating the functions // S32_generic_D32_filter_DX_SSSE3 and @@ -722,3 +730,31 @@ void S32_alpha_D32_filter_DXDY_SSSE3(const SkBitmapProcState& s, int count, uint32_t* colors) { S32_generic_D32_filter_DXDY_SSSE3(s, xy, count, colors); } + +#else // !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3 + +void S32_opaque_D32_filter_DX_SSSE3(const SkBitmapProcState& s, + const uint32_t* xy, + int count, uint32_t* colors) { + sk_throw(); +} + +void S32_alpha_D32_filter_DX_SSSE3(const SkBitmapProcState& s, + const uint32_t* xy, + int count, uint32_t* colors) { + sk_throw(); +} + +void S32_opaque_D32_filter_DXDY_SSSE3(const SkBitmapProcState& s, + const uint32_t* xy, + int count, uint32_t* colors) { + sk_throw(); +} + +void S32_alpha_D32_filter_DXDY_SSSE3(const SkBitmapProcState& s, + const uint32_t* xy, + int count, uint32_t* colors) { + sk_throw(); +} + +#endif diff --git a/gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.cpp b/gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.cpp index f3d010e3bc45..4aa08e81657a 100644 --- a/gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.cpp +++ b/gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.cpp @@ -9,6 +9,8 @@ #include "SkBlitRow_opts_SSE2.h" #include "SkBitmapProcState_opts_SSE2.h" #include "SkColorPriv.h" +#include "SkColor_opts_SSE2.h" +#include "SkDither.h" #include "SkUtils.h" #include @@ -851,3 +853,512 @@ void SkBlitLCD16OpaqueRow_SSE2(SkPMColor dst[], const uint16_t mask[], width--; } } + +/* SSE2 version of S32_D565_Opaque() + * portable version is in core/SkBlitRow_D16.cpp + */ +void S32_D565_Opaque_SSE2(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + U8CPU alpha, int /*x*/, int /*y*/) { + SkASSERT(255 == alpha); + + if (count <= 0) { + return; + } + + if (count >= 8) { + while (((size_t)dst & 0x0F) != 0) { + SkPMColor c = *src++; + SkPMColorAssert(c); + + *dst++ = SkPixel32ToPixel16_ToU16(c); + count--; + } + + const __m128i* s = reinterpret_cast(src); + __m128i* d = reinterpret_cast<__m128i*>(dst); + __m128i r16_mask = _mm_set1_epi32(SK_R16_MASK); + __m128i g16_mask = _mm_set1_epi32(SK_G16_MASK); + __m128i b16_mask = _mm_set1_epi32(SK_B16_MASK); + + while (count >= 8) { + // Load 8 pixels of src. + __m128i src_pixel1 = _mm_loadu_si128(s++); + __m128i src_pixel2 = _mm_loadu_si128(s++); + + // Calculate result r. + __m128i r1 = _mm_srli_epi32(src_pixel1, + SK_R32_SHIFT + (8 - SK_R16_BITS)); + r1 = _mm_and_si128(r1, r16_mask); + __m128i r2 = _mm_srli_epi32(src_pixel2, + SK_R32_SHIFT + (8 - SK_R16_BITS)); + r2 = _mm_and_si128(r2, r16_mask); + __m128i r = _mm_packs_epi32(r1, r2); + + // Calculate result g. + __m128i g1 = _mm_srli_epi32(src_pixel1, + SK_G32_SHIFT + (8 - SK_G16_BITS)); + g1 = _mm_and_si128(g1, g16_mask); + __m128i g2 = _mm_srli_epi32(src_pixel2, + SK_G32_SHIFT + (8 - SK_G16_BITS)); + g2 = _mm_and_si128(g2, g16_mask); + __m128i g = _mm_packs_epi32(g1, g2); + + // Calculate result b. + __m128i b1 = _mm_srli_epi32(src_pixel1, + SK_B32_SHIFT + (8 - SK_B16_BITS)); + b1 = _mm_and_si128(b1, b16_mask); + __m128i b2 = _mm_srli_epi32(src_pixel2, + SK_B32_SHIFT + (8 - SK_B16_BITS)); + b2 = _mm_and_si128(b2, b16_mask); + __m128i b = _mm_packs_epi32(b1, b2); + + // Store 8 16-bit colors in dst. + __m128i d_pixel = SkPackRGB16_SSE(r, g, b); + _mm_store_si128(d++, d_pixel); + count -= 8; + } + src = reinterpret_cast(s); + dst = reinterpret_cast(d); + } + + if (count > 0) { + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + *dst++ = SkPixel32ToPixel16_ToU16(c); + } while (--count != 0); + } +} + +/* SSE2 version of S32A_D565_Opaque() + * portable version is in core/SkBlitRow_D16.cpp + */ +void S32A_D565_Opaque_SSE2(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int /*x*/, int /*y*/) { + SkASSERT(255 == alpha); + + if (count <= 0) { + return; + } + + if (count >= 8) { + // Make dst 16 bytes alignment + while (((size_t)dst & 0x0F) != 0) { + SkPMColor c = *src++; + if (c) { + *dst = SkSrcOver32To16(c, *dst); + } + dst += 1; + count--; + } + + const __m128i* s = reinterpret_cast(src); + __m128i* d = reinterpret_cast<__m128i*>(dst); + __m128i var255 = _mm_set1_epi16(255); + __m128i r16_mask = _mm_set1_epi16(SK_R16_MASK); + __m128i g16_mask = _mm_set1_epi16(SK_G16_MASK); + __m128i b16_mask = _mm_set1_epi16(SK_B16_MASK); + + while (count >= 8) { + // Load 8 pixels of src. + __m128i src_pixel1 = _mm_loadu_si128(s++); + __m128i src_pixel2 = _mm_loadu_si128(s++); + + // Check whether src pixels are equal to 0 and get the highest bit + // of each byte of result, if src pixels are all zero, src_cmp1 and + // src_cmp2 will be 0xFFFF. + int src_cmp1 = _mm_movemask_epi8(_mm_cmpeq_epi16(src_pixel1, + _mm_setzero_si128())); + int src_cmp2 = _mm_movemask_epi8(_mm_cmpeq_epi16(src_pixel2, + _mm_setzero_si128())); + if (src_cmp1 == 0xFFFF && src_cmp2 == 0xFFFF) { + d++; + count -= 8; + continue; + } + + // Load 8 pixels of dst. + __m128i dst_pixel = _mm_load_si128(d); + + // Extract A from src. + __m128i sa1 = _mm_slli_epi32(src_pixel1,(24 - SK_A32_SHIFT)); + sa1 = _mm_srli_epi32(sa1, 24); + __m128i sa2 = _mm_slli_epi32(src_pixel2,(24 - SK_A32_SHIFT)); + sa2 = _mm_srli_epi32(sa2, 24); + __m128i sa = _mm_packs_epi32(sa1, sa2); + + // Extract R from src. + __m128i sr1 = _mm_slli_epi32(src_pixel1,(24 - SK_R32_SHIFT)); + sr1 = _mm_srli_epi32(sr1, 24); + __m128i sr2 = _mm_slli_epi32(src_pixel2,(24 - SK_R32_SHIFT)); + sr2 = _mm_srli_epi32(sr2, 24); + __m128i sr = _mm_packs_epi32(sr1, sr2); + + // Extract G from src. + __m128i sg1 = _mm_slli_epi32(src_pixel1,(24 - SK_G32_SHIFT)); + sg1 = _mm_srli_epi32(sg1, 24); + __m128i sg2 = _mm_slli_epi32(src_pixel2,(24 - SK_G32_SHIFT)); + sg2 = _mm_srli_epi32(sg2, 24); + __m128i sg = _mm_packs_epi32(sg1, sg2); + + // Extract B from src. + __m128i sb1 = _mm_slli_epi32(src_pixel1,(24 - SK_B32_SHIFT)); + sb1 = _mm_srli_epi32(sb1, 24); + __m128i sb2 = _mm_slli_epi32(src_pixel2,(24 - SK_B32_SHIFT)); + sb2 = _mm_srli_epi32(sb2, 24); + __m128i sb = _mm_packs_epi32(sb1, sb2); + + // Extract R G B from dst. + __m128i dr = _mm_srli_epi16(dst_pixel,SK_R16_SHIFT); + dr = _mm_and_si128(dr, r16_mask); + __m128i dg = _mm_srli_epi16(dst_pixel,SK_G16_SHIFT); + dg = _mm_and_si128(dg, g16_mask); + __m128i db = _mm_srli_epi16(dst_pixel,SK_B16_SHIFT); + db = _mm_and_si128(db, b16_mask); + + __m128i isa = _mm_sub_epi16(var255, sa); // 255 -sa + + // Calculate R G B of result. + // Original algorithm is in SkSrcOver32To16(). + dr = _mm_add_epi16(sr, SkMul16ShiftRound_SSE(dr, isa, SK_R16_BITS)); + dr = _mm_srli_epi16(dr, 8 - SK_R16_BITS); + dg = _mm_add_epi16(sg, SkMul16ShiftRound_SSE(dg, isa, SK_G16_BITS)); + dg = _mm_srli_epi16(dg, 8 - SK_G16_BITS); + db = _mm_add_epi16(sb, SkMul16ShiftRound_SSE(db, isa, SK_B16_BITS)); + db = _mm_srli_epi16(db, 8 - SK_B16_BITS); + + // Pack R G B into 16-bit color. + __m128i d_pixel = SkPackRGB16_SSE(dr, dg, db); + + // Store 8 16-bit colors in dst. + _mm_store_si128(d++, d_pixel); + count -= 8; + } + + src = reinterpret_cast(s); + dst = reinterpret_cast(d); + } + + if (count > 0) { + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + if (c) { + *dst = SkSrcOver32To16(c, *dst); + } + dst += 1; + } while (--count != 0); + } +} + +void S32_D565_Opaque_Dither_SSE2(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y) { + SkASSERT(255 == alpha); + + if (count <= 0) { + return; + } + + if (count >= 8) { + while (((size_t)dst & 0x0F) != 0) { + DITHER_565_SCAN(y); + SkPMColor c = *src++; + SkPMColorAssert(c); + + unsigned dither = DITHER_VALUE(x); + *dst++ = SkDitherRGB32To565(c, dither); + DITHER_INC_X(x); + count--; + } + + unsigned short dither_value[8]; + __m128i dither; +#ifdef ENABLE_DITHER_MATRIX_4X4 + const uint8_t* dither_scan = gDitherMatrix_3Bit_4X4[(y) & 3]; + dither_value[0] = dither_value[4] = dither_scan[(x) & 3]; + dither_value[1] = dither_value[5] = dither_scan[(x + 1) & 3]; + dither_value[2] = dither_value[6] = dither_scan[(x + 2) & 3]; + dither_value[3] = dither_value[7] = dither_scan[(x + 3) & 3]; +#else + const uint16_t dither_scan = gDitherMatrix_3Bit_16[(y) & 3]; + dither_value[0] = dither_value[4] = (dither_scan + >> (((x) & 3) << 2)) & 0xF; + dither_value[1] = dither_value[5] = (dither_scan + >> (((x + 1) & 3) << 2)) & 0xF; + dither_value[2] = dither_value[6] = (dither_scan + >> (((x + 2) & 3) << 2)) & 0xF; + dither_value[3] = dither_value[7] = (dither_scan + >> (((x + 3) & 3) << 2)) & 0xF; +#endif + dither = _mm_loadu_si128((__m128i*) dither_value); + + const __m128i* s = reinterpret_cast(src); + __m128i* d = reinterpret_cast<__m128i*>(dst); + + while (count >= 8) { + // Load 8 pixels of src. + __m128i src_pixel1 = _mm_loadu_si128(s++); + __m128i src_pixel2 = _mm_loadu_si128(s++); + + // Extract R from src. + __m128i sr1 = _mm_slli_epi32(src_pixel1, (24 - SK_R32_SHIFT)); + sr1 = _mm_srli_epi32(sr1, 24); + __m128i sr2 = _mm_slli_epi32(src_pixel2, (24 - SK_R32_SHIFT)); + sr2 = _mm_srli_epi32(sr2, 24); + __m128i sr = _mm_packs_epi32(sr1, sr2); + + // SkDITHER_R32To565(sr, dither) + __m128i sr_offset = _mm_srli_epi16(sr, 5); + sr = _mm_add_epi16(sr, dither); + sr = _mm_sub_epi16(sr, sr_offset); + sr = _mm_srli_epi16(sr, SK_R32_BITS - SK_R16_BITS); + + // Extract G from src. + __m128i sg1 = _mm_slli_epi32(src_pixel1, (24 - SK_G32_SHIFT)); + sg1 = _mm_srli_epi32(sg1, 24); + __m128i sg2 = _mm_slli_epi32(src_pixel2, (24 - SK_G32_SHIFT)); + sg2 = _mm_srli_epi32(sg2, 24); + __m128i sg = _mm_packs_epi32(sg1, sg2); + + // SkDITHER_R32To565(sg, dither) + __m128i sg_offset = _mm_srli_epi16(sg, 6); + sg = _mm_add_epi16(sg, _mm_srli_epi16(dither, 1)); + sg = _mm_sub_epi16(sg, sg_offset); + sg = _mm_srli_epi16(sg, SK_G32_BITS - SK_G16_BITS); + + // Extract B from src. + __m128i sb1 = _mm_slli_epi32(src_pixel1, (24 - SK_B32_SHIFT)); + sb1 = _mm_srli_epi32(sb1, 24); + __m128i sb2 = _mm_slli_epi32(src_pixel2, (24 - SK_B32_SHIFT)); + sb2 = _mm_srli_epi32(sb2, 24); + __m128i sb = _mm_packs_epi32(sb1, sb2); + + // SkDITHER_R32To565(sb, dither) + __m128i sb_offset = _mm_srli_epi16(sb, 5); + sb = _mm_add_epi16(sb, dither); + sb = _mm_sub_epi16(sb, sb_offset); + sb = _mm_srli_epi16(sb, SK_B32_BITS - SK_B16_BITS); + + // Pack and store 16-bit dst pixel. + __m128i d_pixel = SkPackRGB16_SSE(sr, sg, sb); + _mm_store_si128(d++, d_pixel); + + count -= 8; + x += 8; + } + + src = reinterpret_cast(s); + dst = reinterpret_cast(d); + } + + if (count > 0) { + DITHER_565_SCAN(y); + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + + unsigned dither = DITHER_VALUE(x); + *dst++ = SkDitherRGB32To565(c, dither); + DITHER_INC_X(x); + } while (--count != 0); + } +} + +/* SSE2 version of S32A_D565_Opaque_Dither() + * portable version is in core/SkBlitRow_D16.cpp + */ +void S32A_D565_Opaque_Dither_SSE2(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y) { + SkASSERT(255 == alpha); + + if (count <= 0) { + return; + } + + if (count >= 8) { + while (((size_t)dst & 0x0F) != 0) { + DITHER_565_SCAN(y); + SkPMColor c = *src++; + SkPMColorAssert(c); + if (c) { + unsigned a = SkGetPackedA32(c); + + int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); + + unsigned sr = SkGetPackedR32(c); + unsigned sg = SkGetPackedG32(c); + unsigned sb = SkGetPackedB32(c); + sr = SkDITHER_R32_FOR_565(sr, d); + sg = SkDITHER_G32_FOR_565(sg, d); + sb = SkDITHER_B32_FOR_565(sb, d); + + uint32_t src_expanded = (sg << 24) | (sr << 13) | (sb << 2); + uint32_t dst_expanded = SkExpand_rgb_16(*dst); + dst_expanded = dst_expanded * (SkAlpha255To256(255 - a) >> 3); + // now src and dst expanded are in g:11 r:10 x:1 b:10 + *dst = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); + } + dst += 1; + DITHER_INC_X(x); + count--; + } + + unsigned short dither_value[8]; + __m128i dither, dither_cur; +#ifdef ENABLE_DITHER_MATRIX_4X4 + const uint8_t* dither_scan = gDitherMatrix_3Bit_4X4[(y) & 3]; + dither_value[0] = dither_value[4] = dither_scan[(x) & 3]; + dither_value[1] = dither_value[5] = dither_scan[(x + 1) & 3]; + dither_value[2] = dither_value[6] = dither_scan[(x + 2) & 3]; + dither_value[3] = dither_value[7] = dither_scan[(x + 3) & 3]; +#else + const uint16_t dither_scan = gDitherMatrix_3Bit_16[(y) & 3]; + dither_value[0] = dither_value[4] = (dither_scan + >> (((x) & 3) << 2)) & 0xF; + dither_value[1] = dither_value[5] = (dither_scan + >> (((x + 1) & 3) << 2)) & 0xF; + dither_value[2] = dither_value[6] = (dither_scan + >> (((x + 2) & 3) << 2)) & 0xF; + dither_value[3] = dither_value[7] = (dither_scan + >> (((x + 3) & 3) << 2)) & 0xF; +#endif + dither = _mm_loadu_si128((__m128i*) dither_value); + + const __m128i* s = reinterpret_cast(src); + __m128i* d = reinterpret_cast<__m128i*>(dst); + __m128i var256 = _mm_set1_epi16(256); + __m128i r16_mask = _mm_set1_epi16(SK_R16_MASK); + __m128i g16_mask = _mm_set1_epi16(SK_G16_MASK); + __m128i b16_mask = _mm_set1_epi16(SK_B16_MASK); + + while (count >= 8) { + // Load 8 pixels of src and dst. + __m128i src_pixel1 = _mm_loadu_si128(s++); + __m128i src_pixel2 = _mm_loadu_si128(s++); + __m128i dst_pixel = _mm_load_si128(d); + + // Extract A from src. + __m128i sa1 = _mm_slli_epi32(src_pixel1,(24 - SK_A32_SHIFT)); + sa1 = _mm_srli_epi32(sa1, 24); + __m128i sa2 = _mm_slli_epi32(src_pixel2,(24 - SK_A32_SHIFT)); + sa2 = _mm_srli_epi32(sa2, 24); + __m128i sa = _mm_packs_epi32(sa1, sa2); + + // Calculate current dither value. + dither_cur = _mm_mullo_epi16(dither, + _mm_add_epi16(sa, _mm_set1_epi16(1))); + dither_cur = _mm_srli_epi16(dither_cur, 8); + + // Extract R from src. + __m128i sr1 = _mm_slli_epi32(src_pixel1, (24 - SK_R32_SHIFT)); + sr1 = _mm_srli_epi32(sr1, 24); + __m128i sr2 = _mm_slli_epi32(src_pixel2, (24 - SK_R32_SHIFT)); + sr2 = _mm_srli_epi32(sr2, 24); + __m128i sr = _mm_packs_epi32(sr1, sr2); + + // SkDITHER_R32_FOR_565(sr, d) + __m128i sr_offset = _mm_srli_epi16(sr, 5); + sr = _mm_add_epi16(sr, dither_cur); + sr = _mm_sub_epi16(sr, sr_offset); + + // Expand sr. + sr = _mm_slli_epi16(sr, 2); + + // Extract G from src. + __m128i sg1 = _mm_slli_epi32(src_pixel1, (24 - SK_G32_SHIFT)); + sg1 = _mm_srli_epi32(sg1, 24); + __m128i sg2 = _mm_slli_epi32(src_pixel2, (24 - SK_G32_SHIFT)); + sg2 = _mm_srli_epi32(sg2, 24); + __m128i sg = _mm_packs_epi32(sg1, sg2); + + // sg = SkDITHER_G32_FOR_565(sg, d). + __m128i sg_offset = _mm_srli_epi16(sg, 6); + sg = _mm_add_epi16(sg, _mm_srli_epi16(dither_cur, 1)); + sg = _mm_sub_epi16(sg, sg_offset); + + // Expand sg. + sg = _mm_slli_epi16(sg, 3); + + // Extract B from src. + __m128i sb1 = _mm_slli_epi32(src_pixel1, (24 - SK_B32_SHIFT)); + sb1 = _mm_srli_epi32(sb1, 24); + __m128i sb2 = _mm_slli_epi32(src_pixel2, (24 - SK_B32_SHIFT)); + sb2 = _mm_srli_epi32(sb2, 24); + __m128i sb = _mm_packs_epi32(sb1, sb2); + + // sb = SkDITHER_B32_FOR_565(sb, d). + __m128i sb_offset = _mm_srli_epi16(sb, 5); + sb = _mm_add_epi16(sb, dither_cur); + sb = _mm_sub_epi16(sb, sb_offset); + + // Expand sb. + sb = _mm_slli_epi16(sb, 2); + + // Extract R G B from dst. + __m128i dr = _mm_srli_epi16(dst_pixel, SK_R16_SHIFT); + dr = _mm_and_si128(dr, r16_mask); + __m128i dg = _mm_srli_epi16(dst_pixel, SK_G16_SHIFT); + dg = _mm_and_si128(dg, g16_mask); + __m128i db = _mm_srli_epi16(dst_pixel, SK_B16_SHIFT); + db = _mm_and_si128(db, b16_mask); + + // SkAlpha255To256(255 - a) >> 3 + __m128i isa = _mm_sub_epi16(var256, sa); + isa = _mm_srli_epi16(isa, 3); + + dr = _mm_mullo_epi16(dr, isa); + dr = _mm_add_epi16(dr, sr); + dr = _mm_srli_epi16(dr, 5); + + dg = _mm_mullo_epi16(dg, isa); + dg = _mm_add_epi16(dg, sg); + dg = _mm_srli_epi16(dg, 5); + + db = _mm_mullo_epi16(db, isa); + db = _mm_add_epi16(db, sb); + db = _mm_srli_epi16(db, 5); + + // Package and store dst pixel. + __m128i d_pixel = SkPackRGB16_SSE(dr, dg, db); + _mm_store_si128(d++, d_pixel); + + count -= 8; + x += 8; + } + + src = reinterpret_cast(s); + dst = reinterpret_cast(d); + } + + if (count > 0) { + DITHER_565_SCAN(y); + do { + SkPMColor c = *src++; + SkPMColorAssert(c); + if (c) { + unsigned a = SkGetPackedA32(c); + + int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); + + unsigned sr = SkGetPackedR32(c); + unsigned sg = SkGetPackedG32(c); + unsigned sb = SkGetPackedB32(c); + sr = SkDITHER_R32_FOR_565(sr, d); + sg = SkDITHER_G32_FOR_565(sg, d); + sb = SkDITHER_B32_FOR_565(sb, d); + + uint32_t src_expanded = (sg << 24) | (sr << 13) | (sb << 2); + uint32_t dst_expanded = SkExpand_rgb_16(*dst); + dst_expanded = dst_expanded * (SkAlpha255To256(255 - a) >> 3); + // now src and dst expanded are in g:11 r:10 x:1 b:10 + *dst = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); + } + dst += 1; + DITHER_INC_X(x); + } while (--count != 0); + } +} diff --git a/gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.h b/gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.h index b443ec7f2133..fcf82d08e578 100644 --- a/gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.h +++ b/gfx/skia/trunk/src/opts/SkBlitRow_opts_SSE2.h @@ -28,3 +28,16 @@ void SkBlitLCD16Row_SSE2(SkPMColor dst[], const uint16_t src[], SkColor color, int width, SkPMColor); void SkBlitLCD16OpaqueRow_SSE2(SkPMColor dst[], const uint16_t src[], SkColor color, int width, SkPMColor opaqueDst); + +void S32_D565_Opaque_SSE2(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, int count, + U8CPU alpha, int /*x*/, int /*y*/); +void S32A_D565_Opaque_SSE2(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int /*x*/, int /*y*/); +void S32_D565_Opaque_Dither_SSE2(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y); +void S32A_D565_Opaque_Dither_SSE2(uint16_t* SK_RESTRICT dst, + const SkPMColor* SK_RESTRICT src, + int count, U8CPU alpha, int x, int y); diff --git a/gfx/skia/trunk/src/opts/SkBlitRow_opts_arm_neon.cpp b/gfx/skia/trunk/src/opts/SkBlitRow_opts_arm_neon.cpp index 672980d0d263..67b42c9e2671 100644 --- a/gfx/skia/trunk/src/opts/SkBlitRow_opts_arm_neon.cpp +++ b/gfx/skia/trunk/src/opts/SkBlitRow_opts_arm_neon.cpp @@ -230,113 +230,123 @@ void S32A_D565_Opaque_neon(uint16_t* SK_RESTRICT dst, } } +static inline uint16x8_t SkDiv255Round_neon8(uint16x8_t prod) { + prod += vdupq_n_u16(128); + prod += vshrq_n_u16(prod, 8); + return vshrq_n_u16(prod, 8); +} + void S32A_D565_Blend_neon(uint16_t* SK_RESTRICT dst, const SkPMColor* SK_RESTRICT src, int count, U8CPU alpha, int /*x*/, int /*y*/) { + SkASSERT(255 > alpha); - U8CPU alpha_for_asm = alpha; - - asm volatile ( - /* This code implements a Neon version of S32A_D565_Blend. The output differs from - * the original in two respects: - * 1. The results have a few mismatches compared to the original code. These mismatches - * never exceed 1. It's possible to improve accuracy vs. a floating point - * implementation by introducing rounding right shifts (vrshr) for the final stage. - * Rounding is not present in the code below, because although results would be closer - * to a floating point implementation, the number of mismatches compared to the - * original code would be far greater. - * 2. On certain inputs, the original code can overflow, causing colour channels to - * mix. Although the Neon code can also overflow, it doesn't allow one colour channel - * to affect another. + /* This code implements a Neon version of S32A_D565_Blend. The results have + * a few mismatches compared to the original code. These mismatches never + * exceed 1. */ -#if 1 - /* reflects SkAlpha255To256()'s change from a+a>>7 to a+1 */ - "add %[alpha], %[alpha], #1 \n\t" // adjust range of alpha 0-256 -#else - "add %[alpha], %[alpha], %[alpha], lsr #7 \n\t" // adjust range of alpha 0-256 -#endif - "vmov.u16 q3, #255 \n\t" // set up constant - "movs r4, %[count], lsr #3 \n\t" // calc. count>>3 - "vmov.u16 d2[0], %[alpha] \n\t" // move alpha to Neon - "beq 2f \n\t" // if count8 == 0, exit - "vmov.u16 q15, #0x1f \n\t" // set up blue mask + if (count >= 8) { + uint16x8_t valpha_max, vmask_blue; + uint8x8_t valpha; - "1: \n\t" - "vld1.u16 {d0, d1}, [%[dst]] \n\t" // load eight dst RGB565 pixels - "subs r4, r4, #1 \n\t" // decrement loop counter - "vld4.u8 {d24, d25, d26, d27}, [%[src]]! \n\t" // load eight src ABGR32 pixels - // and deinterleave + // prepare constants + valpha_max = vmovq_n_u16(255); + valpha = vdup_n_u8(alpha); + vmask_blue = vmovq_n_u16(SK_B16_MASK); - "vshl.u16 q9, q0, #5 \n\t" // shift green to top of lanes - "vand q10, q0, q15 \n\t" // extract blue - "vshr.u16 q8, q0, #11 \n\t" // extract red - "vshr.u16 q9, q9, #10 \n\t" // extract green - // dstrgb = {q8, q9, q10} - - "vshr.u8 d24, d24, #3 \n\t" // shift red to 565 range - "vshr.u8 d25, d25, #2 \n\t" // shift green to 565 range - "vshr.u8 d26, d26, #3 \n\t" // shift blue to 565 range - - "vmovl.u8 q11, d24 \n\t" // widen red to 16 bits - "vmovl.u8 q12, d25 \n\t" // widen green to 16 bits - "vmovl.u8 q14, d27 \n\t" // widen alpha to 16 bits - "vmovl.u8 q13, d26 \n\t" // widen blue to 16 bits - // srcrgba = {q11, q12, q13, q14} - - "vmul.u16 q2, q14, d2[0] \n\t" // sa * src_scale - "vmul.u16 q11, q11, d2[0] \n\t" // red result = src_red * src_scale - "vmul.u16 q12, q12, d2[0] \n\t" // grn result = src_grn * src_scale - "vmul.u16 q13, q13, d2[0] \n\t" // blu result = src_blu * src_scale - - "vshr.u16 q2, q2, #8 \n\t" // sa * src_scale >> 8 - "vsub.u16 q2, q3, q2 \n\t" // 255 - (sa * src_scale >> 8) - // dst_scale = q2 - - "vmla.u16 q11, q8, q2 \n\t" // red result += dst_red * dst_scale - "vmla.u16 q12, q9, q2 \n\t" // grn result += dst_grn * dst_scale - "vmla.u16 q13, q10, q2 \n\t" // blu result += dst_blu * dst_scale - -#if 1 - // trying for a better match with SkDiv255Round(a) - // C alg is: a+=128; (a+a>>8)>>8 - // we'll use just a rounding shift [q2 is available for scratch] - "vrshr.u16 q11, q11, #8 \n\t" // shift down red - "vrshr.u16 q12, q12, #8 \n\t" // shift down green - "vrshr.u16 q13, q13, #8 \n\t" // shift down blue -#else - // arm's original "truncating divide by 256" - "vshr.u16 q11, q11, #8 \n\t" // shift down red - "vshr.u16 q12, q12, #8 \n\t" // shift down green - "vshr.u16 q13, q13, #8 \n\t" // shift down blue -#endif - - "vsli.u16 q13, q12, #5 \n\t" // insert green into blue - "vsli.u16 q13, q11, #11 \n\t" // insert red into green/blue - "vst1.16 {d26, d27}, [%[dst]]! \n\t" // write pixel back to dst, update ptr - - "bne 1b \n\t" // if counter != 0, loop - "2: \n\t" // exit - - : [src] "+r" (src), [dst] "+r" (dst), [count] "+r" (count), [alpha] "+r" (alpha_for_asm) - : - : "cc", "memory", "r4", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31" - ); - - count &= 7; - if (count > 0) { do { - SkPMColor sc = *src++; - if (sc) { - uint16_t dc = *dst; - unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); - unsigned dr = SkMulS16(SkPacked32ToR16(sc), alpha) + SkMulS16(SkGetPackedR16(dc), dst_scale); - unsigned dg = SkMulS16(SkPacked32ToG16(sc), alpha) + SkMulS16(SkGetPackedG16(dc), dst_scale); - unsigned db = SkMulS16(SkPacked32ToB16(sc), alpha) + SkMulS16(SkGetPackedB16(dc), dst_scale); - *dst = SkPackRGB16(SkDiv255Round(dr), SkDiv255Round(dg), SkDiv255Round(db)); - } - dst += 1; - } while (--count != 0); + uint16x8_t vdst, vdst_r, vdst_g, vdst_b; + uint16x8_t vres_a, vres_r, vres_g, vres_b; + uint8x8x4_t vsrc; + + // load pixels + vdst = vld1q_u16(dst); +#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)) + asm ( + "vld4.u8 %h[vsrc], [%[src]]!" + : [vsrc] "=w" (vsrc), [src] "+&r" (src) + : : + ); +#else + register uint8x8_t d0 asm("d0"); + register uint8x8_t d1 asm("d1"); + register uint8x8_t d2 asm("d2"); + register uint8x8_t d3 asm("d3"); + + asm volatile ( + "vld4.u8 {d0-d3},[%[src]]!;" + : "=w" (d0), "=w" (d1), "=w" (d2), "=w" (d3), + [src] "+&r" (src) + : : + ); + vsrc.val[0] = d0; + vsrc.val[1] = d1; + vsrc.val[2] = d2; + vsrc.val[3] = d3; +#endif + + + // deinterleave dst + vdst_g = vshlq_n_u16(vdst, SK_R16_BITS); // shift green to top of lanes + vdst_b = vdst & vmask_blue; // extract blue + vdst_r = vshrq_n_u16(vdst, SK_R16_SHIFT); // extract red + vdst_g = vshrq_n_u16(vdst_g, SK_R16_BITS + SK_B16_BITS); // extract green + + // shift src to 565 + vsrc.val[NEON_R] = vshr_n_u8(vsrc.val[NEON_R], 8 - SK_R16_BITS); + vsrc.val[NEON_G] = vshr_n_u8(vsrc.val[NEON_G], 8 - SK_G16_BITS); + vsrc.val[NEON_B] = vshr_n_u8(vsrc.val[NEON_B], 8 - SK_B16_BITS); + + // calc src * src_scale + vres_a = vmull_u8(vsrc.val[NEON_A], valpha); + vres_r = vmull_u8(vsrc.val[NEON_R], valpha); + vres_g = vmull_u8(vsrc.val[NEON_G], valpha); + vres_b = vmull_u8(vsrc.val[NEON_B], valpha); + + // prepare dst_scale + vres_a = SkDiv255Round_neon8(vres_a); + vres_a = valpha_max - vres_a; // 255 - (sa * src_scale) / 255 + + // add dst * dst_scale to previous result + vres_r = vmlaq_u16(vres_r, vdst_r, vres_a); + vres_g = vmlaq_u16(vres_g, vdst_g, vres_a); + vres_b = vmlaq_u16(vres_b, vdst_b, vres_a); + +#ifdef S32A_D565_BLEND_EXACT + // It is possible to get exact results with this but it is slow, + // even slower than C code in some cases + vres_r = SkDiv255Round_neon8(vres_r); + vres_g = SkDiv255Round_neon8(vres_g); + vres_b = SkDiv255Round_neon8(vres_b); +#else + vres_r = vrshrq_n_u16(vres_r, 8); + vres_g = vrshrq_n_u16(vres_g, 8); + vres_b = vrshrq_n_u16(vres_b, 8); +#endif + // pack result + vres_b = vsliq_n_u16(vres_b, vres_g, SK_G16_SHIFT); // insert green into blue + vres_b = vsliq_n_u16(vres_b, vres_r, SK_R16_SHIFT); // insert red into green/blue + + // store + vst1q_u16(dst, vres_b); + dst += 8; + count -= 8; + } while (count >= 8); + } + + // leftovers + while (count-- > 0) { + SkPMColor sc = *src++; + if (sc) { + uint16_t dc = *dst; + unsigned dst_scale = 255 - SkMulDiv255Round(SkGetPackedA32(sc), alpha); + unsigned dr = SkMulS16(SkPacked32ToR16(sc), alpha) + SkMulS16(SkGetPackedR16(dc), dst_scale); + unsigned dg = SkMulS16(SkPacked32ToG16(sc), alpha) + SkMulS16(SkGetPackedG16(dc), dst_scale); + unsigned db = SkMulS16(SkPacked32ToB16(sc), alpha) + SkMulS16(SkGetPackedB16(dc), dst_scale); + *dst = SkPackRGB16(SkDiv255Round(dr), SkDiv255Round(dg), SkDiv255Round(db)); + } + dst += 1; } } @@ -766,73 +776,63 @@ void S32_Blend_BlitRow32_neon(SkPMColor* SK_RESTRICT dst, const SkPMColor* SK_RESTRICT src, int count, U8CPU alpha) { SkASSERT(alpha <= 255); - if (count > 0) { - uint16_t src_scale = SkAlpha255To256(alpha); - uint16_t dst_scale = 256 - src_scale; - /* run them N at a time through the NEON unit */ - /* note that each 1 is 4 bytes, each treated exactly the same, - * so we can work under that guise. We *do* know that the src&dst - * will be 32-bit aligned quantities, so we can specify that on - * the load/store ops and do a neon 'reinterpret' to get us to - * byte-sized (pun intended) pieces that we widen/multiply/shift - * we're limited at 128 bits in the wide ops, which is 8x16bits - * or a pair of 32 bit src/dsts. - */ - /* we *could* manually unroll this loop so that we load 128 bits - * (as a pair of 64s) from each of src and dst, processing them - * in pieces. This might give us a little better management of - * the memory latency, but my initial attempts here did not - * produce an instruction stream that looked all that nice. - */ -#define UNROLL 2 - while (count >= UNROLL) { - uint8x8_t src_raw, dst_raw, dst_final; - uint16x8_t src_wide, dst_wide; - - /* get 64 bits of src, widen it, multiply by src_scale */ - src_raw = vreinterpret_u8_u32(vld1_u32(src)); - src_wide = vmovl_u8(src_raw); - /* gcc hoists vdupq_n_u16(), better than using vmulq_n_u16() */ - src_wide = vmulq_u16 (src_wide, vdupq_n_u16(src_scale)); - - /* ditto with dst */ - dst_raw = vreinterpret_u8_u32(vld1_u32(dst)); - dst_wide = vmovl_u8(dst_raw); - - /* combine add with dst multiply into mul-accumulate */ - dst_wide = vmlaq_u16(src_wide, dst_wide, vdupq_n_u16(dst_scale)); - - dst_final = vshrn_n_u16(dst_wide, 8); - vst1_u32(dst, vreinterpret_u32_u8(dst_final)); - - src += UNROLL; - dst += UNROLL; - count -= UNROLL; + if (count <= 0) { + return; + } + + uint16_t src_scale = SkAlpha255To256(alpha); + uint16_t dst_scale = 256 - src_scale; + + while (count >= 2) { + uint8x8_t vsrc, vdst, vres; + uint16x8_t vsrc_wide, vdst_wide; + + /* These commented prefetches are a big win for count + * values > 64 on an A9 (Pandaboard) but hurt by 10% for count = 4. + * They also hurt a little (<5%) on an A15 + */ + //__builtin_prefetch(src+32); + //__builtin_prefetch(dst+32); + + // Load + vsrc = vreinterpret_u8_u32(vld1_u32(src)); + vdst = vreinterpret_u8_u32(vld1_u32(dst)); + + // Process src + vsrc_wide = vmovl_u8(vsrc); + vsrc_wide = vmulq_u16(vsrc_wide, vdupq_n_u16(src_scale)); + + // Process dst + vdst_wide = vmull_u8(vdst, vdup_n_u8(dst_scale)); + + // Combine + vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8); + + // Store + vst1_u32(dst, vreinterpret_u32_u8(vres)); + + src += 2; + dst += 2; + count -= 2; } - /* RBE: well, i don't like how gcc manages src/dst across the above - * loop it's constantly calculating src+bias, dst+bias and it only - * adjusts the real ones when we leave the loop. Not sure why - * it's "hoisting down" (hoisting implies above in my lexicon ;)) - * the adjustments to src/dst/count, but it does... - * (might be SSA-style internal logic... - */ -#if UNROLL == 2 if (count == 1) { - *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale); - } -#else - if (count > 0) { - do { - *dst = SkAlphaMulQ(*src, src_scale) + SkAlphaMulQ(*dst, dst_scale); - src += 1; - dst += 1; - } while (--count > 0); - } -#endif + uint8x8_t vsrc = vdup_n_u8(0), vdst = vdup_n_u8(0), vres; + uint16x8_t vsrc_wide, vdst_wide; -#undef UNROLL + // Load + vsrc = vreinterpret_u8_u32(vld1_lane_u32(src, vreinterpret_u32_u8(vsrc), 0)); + vdst = vreinterpret_u8_u32(vld1_lane_u32(dst, vreinterpret_u32_u8(vdst), 0)); + + // Process + vsrc_wide = vmovl_u8(vsrc); + vsrc_wide = vmulq_u16(vsrc_wide, vdupq_n_u16(src_scale)); + vdst_wide = vmull_u8(vdst, vdup_n_u8(dst_scale)); + vres = vshrn_n_u16(vdst_wide, 8) + vshrn_n_u16(vsrc_wide, 8); + + // Store + vst1_lane_u32(dst, vreinterpret_u32_u8(vres), 0); } } @@ -970,9 +970,8 @@ void S32A_D565_Opaque_Dither_neon (uint16_t * SK_RESTRICT dst, #define UNROLL 8 if (count >= UNROLL) { - uint8x8_t dbase; -#if defined(DEBUG_OPAQUE_DITHER) +#if defined(DEBUG_OPAQUE_DITHER) uint16_t tmpbuf[UNROLL]; int td[UNROLL]; int tdv[UNROLL]; @@ -983,6 +982,7 @@ void S32A_D565_Opaque_Dither_neon (uint16_t * SK_RESTRICT dst, int noisy = 0; #endif + uint8x8_t dbase; const uint8_t *dstart = &gDitherMatrix_Neon[(y&3)*12 + (x&3)]; dbase = vld1_u8(dstart); @@ -991,27 +991,27 @@ void S32A_D565_Opaque_Dither_neon (uint16_t * SK_RESTRICT dst, uint16x8_t dst8, scale8, alpha8; uint16x8_t dst_r, dst_g, dst_b; -#if defined(DEBUG_OPAQUE_DITHER) - /* calculate 8 elements worth into a temp buffer */ - { - int my_y = y; - int my_x = x; - SkPMColor* my_src = (SkPMColor*)src; - uint16_t* my_dst = dst; - int i; +#if defined(DEBUG_OPAQUE_DITHER) + // calculate 8 elements worth into a temp buffer + { + int my_y = y; + int my_x = x; + SkPMColor* my_src = (SkPMColor*)src; + uint16_t* my_dst = dst; + int i; - DITHER_565_SCAN(my_y); - for(i=0;i> 3); // now src and dst expanded are in g:11 r:10 x:1 b:10 tmpbuf[i] = SkCompact_rgb_16((src_expanded + dst_expanded) >> 5); - td[i] = d; - + td[i] = d; } else { - tmpbuf[i] = *my_dst; - ta[i] = tdv[i] = td[i] = 0xbeef; - } - in_dst[i] = *my_dst; + tmpbuf[i] = *my_dst; + ta[i] = tdv[i] = td[i] = 0xbeef; + } + in_dst[i] = *my_dst; my_dst += 1; DITHER_INC_X(my_x); - } - } + } + } #endif - /* source is in ABGR */ + { register uint8x8_t d0 asm("d0"); register uint8x8_t d1 asm("d1"); register uint8x8_t d2 asm("d2"); register uint8x8_t d3 asm("d3"); - asm ("vld4.8 {d0-d3},[%4] /* r=%P0 g=%P1 b=%P2 a=%P3 */" - : "=w" (d0), "=w" (d1), "=w" (d2), "=w" (d3) - : "r" (src) - ); + asm ("vld4.8 {d0-d3},[%[src]]! /* r=%P0 g=%P1 b=%P2 a=%P3 */" + : "=w" (d0), "=w" (d1), "=w" (d2), "=w" (d3), [src] "+r" (src) + : + ); +#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) + sr = d2; sg = d1; sb = d0; sa = d3; +#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) sr = d0; sg = d1; sb = d2; sa = d3; +#endif } - /* calculate 'd', which will be 0..7 */ - /* dbase[] is 0..7; alpha is 0..256; 16 bits suffice */ -#if defined(SK_BUILD_FOR_ANDROID) - /* SkAlpha255To256() semantic a+1 vs a+a>>7 */ - alpha8 = vaddw_u8(vmovl_u8(sa), vdup_n_u8(1)); -#else - alpha8 = vaddw_u8(vmovl_u8(sa), vshr_n_u8(sa, 7)); -#endif - alpha8 = vmulq_u16(alpha8, vmovl_u8(dbase)); - d = vshrn_n_u16(alpha8, 8); /* narrowing too */ + /* calculate 'd', which will be 0..7 + * dbase[] is 0..7; alpha is 0..256; 16 bits suffice + */ + alpha8 = vmovl_u8(dbase); + alpha8 = vmlal_u8(alpha8, sa, dbase); + d = vshrn_n_u16(alpha8, 8); // narrowing too - /* sr = sr - (sr>>5) + d */ + // sr = sr - (sr>>5) + d /* watching for 8-bit overflow. d is 0..7; risky range of * sr is >248; and then (sr>>5) is 7 so it offsets 'd'; - * safe as long as we do ((sr-sr>>5) + d) */ + * safe as long as we do ((sr-sr>>5) + d) + */ sr = vsub_u8(sr, vshr_n_u8(sr, 5)); sr = vadd_u8(sr, d); - /* sb = sb - (sb>>5) + d */ + // sb = sb - (sb>>5) + d sb = vsub_u8(sb, vshr_n_u8(sb, 5)); sb = vadd_u8(sb, d); - /* sg = sg - (sg>>6) + d>>1; similar logic for overflows */ + // sg = sg - (sg>>6) + d>>1; similar logic for overflows sg = vsub_u8(sg, vshr_n_u8(sg, 6)); sg = vadd_u8(sg, vshr_n_u8(d,1)); - /* need to pick up 8 dst's -- at 16 bits each, 128 bits */ + // need to pick up 8 dst's -- at 16 bits each, 128 bits dst8 = vld1q_u16(dst); - dst_b = vandq_u16(dst8, vdupq_n_u16(0x001F)); - dst_g = vandq_u16(vshrq_n_u16(dst8,5), vdupq_n_u16(0x003F)); - dst_r = vshrq_n_u16(dst8,11); /* clearing hi bits */ + dst_b = vandq_u16(dst8, vdupq_n_u16(SK_B16_MASK)); + dst_g = vshrq_n_u16(vshlq_n_u16(dst8, SK_R16_BITS), SK_R16_BITS + SK_B16_BITS); + dst_r = vshrq_n_u16(dst8, SK_R16_SHIFT); // clearing hi bits - /* blend */ -#if 1 - /* SkAlpha255To256() semantic a+1 vs a+a>>7 */ - /* originally 255-sa + 1 */ + // blend scale8 = vsubw_u8(vdupq_n_u16(256), sa); -#else - scale8 = vsubw_u8(vdupq_n_u16(255), sa); - scale8 = vaddq_u16(scale8, vshrq_n_u16(scale8, 7)); -#endif -#if 1 - /* combine the addq and mul, save 3 insns */ + // combine the addq and mul, save 3 insns scale8 = vshrq_n_u16(scale8, 3); dst_b = vmlaq_u16(vshll_n_u8(sb,2), dst_b, scale8); dst_g = vmlaq_u16(vshll_n_u8(sg,3), dst_g, scale8); dst_r = vmlaq_u16(vshll_n_u8(sr,2), dst_r, scale8); -#else - /* known correct, but +3 insns over above */ - scale8 = vshrq_n_u16(scale8, 3); - dst_b = vmulq_u16(dst_b, scale8); - dst_g = vmulq_u16(dst_g, scale8); - dst_r = vmulq_u16(dst_r, scale8); - /* combine */ - /* NB: vshll widens, need to preserve those bits */ - dst_b = vaddq_u16(dst_b, vshll_n_u8(sb,2)); - dst_g = vaddq_u16(dst_g, vshll_n_u8(sg,3)); - dst_r = vaddq_u16(dst_r, vshll_n_u8(sr,2)); -#endif - - /* repack to store */ - dst8 = vandq_u16(vshrq_n_u16(dst_b, 5), vdupq_n_u16(0x001F)); + // repack to store + dst8 = vshrq_n_u16(dst_b, 5); dst8 = vsliq_n_u16(dst8, vshrq_n_u16(dst_g, 5), 5); dst8 = vsliq_n_u16(dst8, vshrq_n_u16(dst_r,5), 11); vst1q_u16(dst, dst8); -#if defined(DEBUG_OPAQUE_DITHER) - /* verify my 8 elements match the temp buffer */ - { - int i, bad=0; - static int invocation; +#if defined(DEBUG_OPAQUE_DITHER) + // verify my 8 elements match the temp buffer + { + int i, bad=0; + static int invocation; - for (i=0;i= UNROLL); } #undef UNROLL - /* residuals */ + // residuals if (count > 0) { DITHER_565_SCAN(y); do { diff --git a/gfx/skia/trunk/src/opts/SkColor_opts_SSE2.h b/gfx/skia/trunk/src/opts/SkColor_opts_SSE2.h new file mode 100644 index 000000000000..13a5be565563 --- /dev/null +++ b/gfx/skia/trunk/src/opts/SkColor_opts_SSE2.h @@ -0,0 +1,31 @@ +/* + * Copyright 2014 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 SkColor_opts_SSE2_DEFINED +#define SkColor_opts_SSE2_DEFINED + +#include + +static inline __m128i SkMul16ShiftRound_SSE(__m128i a, __m128i b, int shift) { + __m128i prod = _mm_mullo_epi16(a, b); + prod = _mm_add_epi16(prod, _mm_set1_epi16(1 << (shift - 1))); + prod = _mm_add_epi16(prod, _mm_srli_epi16(prod, shift)); + prod = _mm_srli_epi16(prod, shift); + + return prod; +} + +static inline __m128i SkPackRGB16_SSE(__m128i r, __m128i g, __m128i b) { + r = _mm_slli_epi16(r, SK_R16_SHIFT); + g = _mm_slli_epi16(g, SK_G16_SHIFT); + b = _mm_slli_epi16(b, SK_B16_SHIFT); + + __m128i c = _mm_or_si128(r, g); + return _mm_or_si128(c, b); +} + +#endif//SkColor_opts_SSE2_DEFINED diff --git a/gfx/skia/trunk/src/opts/SkXfermode_opts_arm_neon.cpp b/gfx/skia/trunk/src/opts/SkXfermode_opts_arm_neon.cpp index da14e6631d9c..17a82f554b6f 100644 --- a/gfx/skia/trunk/src/opts/SkXfermode_opts_arm_neon.cpp +++ b/gfx/skia/trunk/src/opts/SkXfermode_opts_arm_neon.cpp @@ -835,7 +835,7 @@ void SkNEONProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst, } } -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING void SkNEONProcCoeffXfermode::toString(SkString* str) const { this->INHERITED::toString(str); } diff --git a/gfx/skia/trunk/src/opts/SkXfermode_opts_arm_neon.h b/gfx/skia/trunk/src/opts/SkXfermode_opts_arm_neon.h index d87748464d6e..8f3aaaea9d9b 100644 --- a/gfx/skia/trunk/src/opts/SkXfermode_opts_arm_neon.h +++ b/gfx/skia/trunk/src/opts/SkXfermode_opts_arm_neon.h @@ -14,7 +14,7 @@ public: virtual void xfer16(uint16_t* SK_RESTRICT dst, const SkPMColor* SK_RESTRICT src, int count, const SkAlpha* SK_RESTRICT aa) const SK_OVERRIDE; - SK_DEVELOPER_TO_STRING() + SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNEONProcCoeffXfermode) private: diff --git a/gfx/skia/trunk/src/opts/opts_check_SSE2.cpp b/gfx/skia/trunk/src/opts/opts_check_SSE2.cpp index d0d88fe4a090..b63a2ffa0fe6 100644 --- a/gfx/skia/trunk/src/opts/opts_check_SSE2.cpp +++ b/gfx/skia/trunk/src/opts/opts_check_SSE2.cpp @@ -165,6 +165,17 @@ void SkBitmapProcState::platformProcs() { } } +static SkBlitRow::Proc platform_16_procs[] = { + S32_D565_Opaque_SSE2, // S32_D565_Opaque + NULL, // S32_D565_Blend + S32A_D565_Opaque_SSE2, // S32A_D565_Opaque + NULL, // S32A_D565_Blend + S32_D565_Opaque_Dither_SSE2, // S32_D565_Opaque_Dither + NULL, // S32_D565_Blend_Dither + S32A_D565_Opaque_Dither_SSE2, // S32A_D565_Opaque_Dither + NULL, // S32A_D565_Blend_Dither +}; + static SkBlitRow::Proc32 platform_32_procs[] = { NULL, // S32_Opaque, S32_Blend_BlitRow32_SSE2, // S32_Blend, @@ -173,7 +184,11 @@ static SkBlitRow::Proc32 platform_32_procs[] = { }; SkBlitRow::Proc SkBlitRow::PlatformProcs565(unsigned flags) { - return NULL; + if (cachedHasSSE2()) { + return platform_16_procs[flags]; + } else { + return NULL; + } } SkBlitRow::ColorProc SkBlitRow::PlatformColorProc() { diff --git a/gfx/skia/trunk/src/pathops/SkDCubicToQuads.cpp b/gfx/skia/trunk/src/pathops/SkDCubicToQuads.cpp index 3cf63f31d029..b2a9b6202ca4 100644 --- a/gfx/skia/trunk/src/pathops/SkDCubicToQuads.cpp +++ b/gfx/skia/trunk/src/pathops/SkDCubicToQuads.cpp @@ -136,17 +136,16 @@ void SkDCubic::toQuadraticTs(double precision, SkTArray* ts) const memmove(inflectT, &inflectT[1], sizeof(inflectT[0]) * --inflections); } int start = 0; - do { - int next = start + 1; - if (next >= inflections) { - break; - } + int next = 1; + while (next < inflections) { if (!approximately_equal(inflectT[start], inflectT[next])) { ++start; + ++next; continue; } memmove(&inflectT[start], &inflectT[next], sizeof(inflectT[0]) * (--inflections - start)); - } while (true); + } + while (inflections && approximately_greater_than_one(inflectT[inflections - 1])) { --inflections; } diff --git a/gfx/skia/trunk/src/pathops/main.cpp b/gfx/skia/trunk/src/pathops/main.cpp deleted file mode 100644 index 65479c25282c..000000000000 --- a/gfx/skia/trunk/src/pathops/main.cpp +++ /dev/null @@ -1,16 +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. - */ - -#include "Test.h" - -using namespace skiatest; - -int main(int /*argc*/, char** /*argv*/) { - Test tester; - tester.run(); - return 0; -} diff --git a/gfx/skia/trunk/src/pdf/SkPDFDevice.cpp b/gfx/skia/trunk/src/pdf/SkPDFDevice.cpp index d227dd7d1cb9..efd2b02b5070 100644 --- a/gfx/skia/trunk/src/pdf/SkPDFDevice.cpp +++ b/gfx/skia/trunk/src/pdf/SkPDFDevice.cpp @@ -404,10 +404,8 @@ static bool get_clip_stack_path(const SkMatrix& transform, outClipPath->reset(); outClipPath->setFillType(SkPath::kInverseWinding_FillType); continue; - } else if (SkClipStack::Element::kRect_Type == clipEntry->getType()) { - entryPath.addRect(clipEntry->getRect()); - } else if (SkClipStack::Element::kPath_Type == clipEntry->getType()) { - entryPath = clipEntry->getPath(); + } else { + clipEntry->asPath(&entryPath); } entryPath.transform(transform); @@ -505,14 +503,13 @@ void GraphicStackState::updateClip(const SkClipStack& clipStack, emit_clip(NULL, &translatedClip, fContentStream); break; } - case SkClipStack::Element::kPath_Type: { + default: { SkPath translatedPath; - clipEntry->getPath().transform(transform, &translatedPath); + clipEntry->asPath(&translatedPath); + translatedPath.transform(transform, &translatedPath); emit_clip(&translatedPath, NULL, fContentStream); break; } - default: - SkASSERT(false); } } } @@ -585,13 +582,10 @@ void GraphicStackState::updateDrawingState(const GraphicStateEntry& state) { } } -SkBaseDevice* SkPDFDevice::onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) { +SkBaseDevice* SkPDFDevice::onCreateDevice(const SkImageInfo& info, Usage usage) { SkMatrix initialTransform; initialTransform.reset(); - SkISize size = SkISize::Make(width, height); + SkISize size = SkISize::Make(info.width(), info.height()); return SkNEW_ARGS(SkPDFDevice, (size, size, initialTransform)); } @@ -710,7 +704,7 @@ private: static inline SkBitmap makeContentBitmap(const SkISize& contentSize, const SkMatrix* initialTransform) { - SkBitmap bitmap; + SkImageInfo info; if (initialTransform) { // Compute the size of the drawing area. SkVector drawingSize; @@ -724,17 +718,19 @@ static inline SkBitmap makeContentBitmap(const SkISize& contentSize, } inverse.mapVectors(&drawingSize, 1); SkISize size = SkSize::Make(drawingSize.fX, drawingSize.fY).toRound(); - bitmap.setConfig(SkBitmap::kNo_Config, abs(size.fWidth), - abs(size.fHeight)); + info = SkImageInfo::MakeUnknown(abs(size.fWidth), abs(size.fHeight)); } else { - bitmap.setConfig(SkBitmap::kNo_Config, abs(contentSize.fWidth), - abs(contentSize.fHeight)); + info = SkImageInfo::MakeUnknown(abs(contentSize.fWidth), + abs(contentSize.fHeight)); } + SkBitmap bitmap; + bitmap.setConfig(info); return bitmap; } // TODO(vandebo) change pageSize to SkSize. +// TODO: inherit from SkBaseDevice instead of SkBitmapDevice SkPDFDevice::SkPDFDevice(const SkISize& pageSize, const SkISize& contentSize, const SkMatrix& initialTransform) : SkBitmapDevice(makeContentBitmap(contentSize, &initialTransform)), @@ -811,10 +807,6 @@ void SkPDFDevice::cleanUp(bool clearFontUsage) { } } -uint32_t SkPDFDevice::getDeviceCapabilities() { - return kVector_Capability; -} - void SkPDFDevice::clear(SkColor color) { this->cleanUp(true); this->init(); @@ -1345,13 +1337,7 @@ void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode, void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device, int x, int y, const SkPaint& paint) { - if ((device->getDeviceCapabilities() & kVector_Capability) == 0) { - // If we somehow get a raster device, do what our parent would do. - INHERITED::drawDevice(d, device, x, y, paint); - return; - } - - // Assume that a vector capable device means that it's a PDF Device. + // our onCreateDevice() always creates SkPDFDevice subclasses. SkPDFDevice* pdfDevice = static_cast(device); if (pdfDevice->isContentEmpty()) { return; diff --git a/gfx/skia/trunk/src/pdf/SkPDFFontImpl.h b/gfx/skia/trunk/src/pdf/SkPDFFontImpl.h old mode 100755 new mode 100644 diff --git a/gfx/skia/trunk/src/pdf/SkPDFImage.cpp b/gfx/skia/trunk/src/pdf/SkPDFImage.cpp index 81adcc20d6b4..f39dc5908502 100644 --- a/gfx/skia/trunk/src/pdf/SkPDFImage.cpp +++ b/gfx/skia/trunk/src/pdf/SkPDFImage.cpp @@ -507,7 +507,7 @@ SkPDFImage::SkPDFImage(SkStream* stream, if (bitmap.isImmutable()) { fBitmap = bitmap; } else { - bitmap.deepCopyTo(&fBitmap, bitmap.config()); + bitmap.deepCopyTo(&fBitmap); fBitmap.setImmutable(); } diff --git a/gfx/skia/trunk/src/pipe/SkGPipePriv.h b/gfx/skia/trunk/src/pipe/SkGPipePriv.h index d1970c4a69bb..5e0b1893cd8d 100644 --- a/gfx/skia/trunk/src/pipe/SkGPipePriv.h +++ b/gfx/skia/trunk/src/pipe/SkGPipePriv.h @@ -45,6 +45,7 @@ enum DrawOps { kDrawBitmapRectToRect_DrawOp, kDrawClear_DrawOp, kDrawData_DrawOp, + kDrawDRRect_DrawOp, kDrawOval_DrawOp, kDrawPaint_DrawOp, kDrawPath_DrawOp, diff --git a/gfx/skia/trunk/src/pipe/SkGPipeRead.cpp b/gfx/skia/trunk/src/pipe/SkGPipeRead.cpp index 513a34d6394c..aaa6b4c9c1d2 100644 --- a/gfx/skia/trunk/src/pipe/SkGPipeRead.cpp +++ b/gfx/skia/trunk/src/pipe/SkGPipeRead.cpp @@ -396,6 +396,16 @@ static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, } } +static void drawDRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, + SkGPipeState* state) { + SkRRect outer, inner; + reader->readRRect(&outer); + reader->readRRect(&inner); + if (state->shouldDraw()) { + canvas->drawDRRect(outer, inner, state->paint()); + } +} + static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { SkPath path; @@ -697,7 +707,7 @@ static void annotation_rp(SkCanvas*, SkReader32* reader, uint32_t op32, const size_t size = DrawOp_unpackData(op32); if (size > 0) { SkReadBuffer buffer(reader->skip(size), size); - p->setAnnotation(SkNEW_ARGS(SkAnnotation, (buffer)))->unref(); + p->setAnnotation(SkAnnotation::Create(buffer))->unref(); SkASSERT(buffer.offset() == size); } else { p->setAnnotation(NULL); @@ -763,6 +773,7 @@ static const ReadProc gReadTable[] = { drawBitmapRect_rp, drawClear_rp, drawData_rp, + drawDRRect_rp, drawOval_rp, drawPaint_rp, drawPath_rp, diff --git a/gfx/skia/trunk/src/pipe/SkGPipeWrite.cpp b/gfx/skia/trunk/src/pipe/SkGPipeWrite.cpp index 54e3bead69d8..637778500a20 100644 --- a/gfx/skia/trunk/src/pipe/SkGPipeWrite.cpp +++ b/gfx/skia/trunk/src/pipe/SkGPipeWrite.cpp @@ -153,7 +153,7 @@ const SkFlatData* FlattenableHeap::flatToReplace() const { /////////////////////////////////////////////////////////////////////////////// struct SkFlattenableTraits { - static void flatten(SkWriteBuffer& buffer, const SkFlattenable& flattenable) { + static void Flatten(SkWriteBuffer& buffer, const SkFlattenable& flattenable) { buffer.writeFlattenable(&flattenable); } // No need to define unflatten if we never call it. @@ -229,22 +229,7 @@ public: } // overrides from SkCanvas - virtual int save(SaveFlags) SK_OVERRIDE; - virtual int saveLayer(const SkRect* bounds, const SkPaint*, - SaveFlags) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; virtual bool isDrawingToLayer() const SK_OVERRIDE; - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - virtual bool clipRect(const SkRect&, SkRegion::Op op, bool doAntiAlias = false) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect&, SkRegion::Op op, bool doAntiAlias = false) SK_OVERRIDE; - virtual bool clipPath(const SkPath& path, SkRegion::Op op, - bool doAntiAlias = false) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE; virtual void clear(SkColor) SK_OVERRIDE; virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE; virtual void drawPoints(PointMode, size_t count, const SkPoint pts[], @@ -290,6 +275,26 @@ public: * according to slot. */ bool shuttleBitmap(const SkBitmap&, int32_t slot); + +protected: + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; + private: enum { kNoSaveLayer = -1, @@ -425,11 +430,13 @@ int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) { SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, SkWriter32* writer, uint32_t flags, uint32_t width, uint32_t height) -: fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL) -, fWriter(*writer) -, fFlags(flags) -, fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, isCrossProcess(flags)) -, fFlatDictionary(&fFlattenableHeap) { + : SkCanvas(width, height) + , fFactorySet(isCrossProcess(flags) ? SkNEW(SkNamedFactorySet) : NULL) + , fWriter(*writer) + , fFlags(flags) + , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, isCrossProcess(flags)) + , fFlatDictionary(&fFlattenableHeap) +{ fController = controller; fDone = false; fBlockSize = 0; // need first block from controller @@ -437,13 +444,6 @@ SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, fFirstSaveLayerStackLevel = kNoSaveLayer; sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex)); - // we need a device to limit our clip - // We don't allocate pixels for the bitmap - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); - SkBaseDevice* device = SkNEW_ARGS(SkBitmapDevice, (bitmap)); - this->setDevice(device)->unref(); - // Tell the reader the appropriate flags to use. if (this->needOpBytes()) { this->writeOp(kReportFlags_DrawOp, fFlags, 0); @@ -515,16 +515,17 @@ uint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) { #define NOTIFY_SETUP(canvas) \ AutoPipeNotify apn(canvas) -int SkGPipeCanvas::save(SaveFlags flags) { +void SkGPipeCanvas::willSave(SaveFlags flags) { NOTIFY_SETUP(this); if (this->needOpBytes()) { this->writeOp(kSave_DrawOp, 0, flags); } - return this->INHERITED::save(flags); + + this->INHERITED::willSave(flags); } -int SkGPipeCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags saveFlags) { +SkCanvas::SaveLayerStrategy SkGPipeCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags saveFlags) { NOTIFY_SETUP(this); size_t size = 0; unsigned opFlags = 0; @@ -548,28 +549,30 @@ int SkGPipeCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, if (kNoSaveLayer == fFirstSaveLayerStackLevel){ fFirstSaveLayerStackLevel = this->getSaveCount(); } - // we just pass on the save, so we don't create a layer - return this->INHERITED::save(saveFlags); + + this->INHERITED::willSaveLayer(bounds, paint, saveFlags); + // we don't create a layer + return kNoLayer_SaveLayerStrategy; } -void SkGPipeCanvas::restore() { +void SkGPipeCanvas::willRestore() { NOTIFY_SETUP(this); if (this->needOpBytes()) { this->writeOp(kRestore_DrawOp); } - this->INHERITED::restore(); - - if (this->getSaveCount() == fFirstSaveLayerStackLevel){ + if (this->getSaveCount() - 1 == fFirstSaveLayerStackLevel){ fFirstSaveLayerStackLevel = kNoSaveLayer; } + + this->INHERITED::willRestore(); } bool SkGPipeCanvas::isDrawingToLayer() const { return kNoSaveLayer != fFirstSaveLayerStackLevel; } -bool SkGPipeCanvas::translate(SkScalar dx, SkScalar dy) { +void SkGPipeCanvas::didTranslate(SkScalar dx, SkScalar dy) { if (dx || dy) { NOTIFY_SETUP(this); if (this->needOpBytes(2 * sizeof(SkScalar))) { @@ -578,10 +581,10 @@ bool SkGPipeCanvas::translate(SkScalar dx, SkScalar dy) { fWriter.writeScalar(dy); } } - return this->INHERITED::translate(dx, dy); + this->INHERITED::didTranslate(dx, dy); } -bool SkGPipeCanvas::scale(SkScalar sx, SkScalar sy) { +void SkGPipeCanvas::didScale(SkScalar sx, SkScalar sy) { if (sx || sy) { NOTIFY_SETUP(this); if (this->needOpBytes(2 * sizeof(SkScalar))) { @@ -590,10 +593,10 @@ bool SkGPipeCanvas::scale(SkScalar sx, SkScalar sy) { fWriter.writeScalar(sy); } } - return this->INHERITED::scale(sx, sy); + this->INHERITED::didScale(sx, sy); } -bool SkGPipeCanvas::rotate(SkScalar degrees) { +void SkGPipeCanvas::didRotate(SkScalar degrees) { if (degrees) { NOTIFY_SETUP(this); if (this->needOpBytes(sizeof(SkScalar))) { @@ -601,10 +604,10 @@ bool SkGPipeCanvas::rotate(SkScalar degrees) { fWriter.writeScalar(degrees); } } - return this->INHERITED::rotate(degrees); + this->INHERITED::didRotate(degrees); } -bool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) { +void SkGPipeCanvas::didSkew(SkScalar sx, SkScalar sy) { if (sx || sy) { NOTIFY_SETUP(this); if (this->needOpBytes(2 * sizeof(SkScalar))) { @@ -613,10 +616,10 @@ bool SkGPipeCanvas::skew(SkScalar sx, SkScalar sy) { fWriter.writeScalar(sy); } } - return this->INHERITED::skew(sx, sy); + this->INHERITED::didSkew(sx, sy); } -bool SkGPipeCanvas::concat(const SkMatrix& matrix) { +void SkGPipeCanvas::didConcat(const SkMatrix& matrix) { if (!matrix.isIdentity()) { NOTIFY_SETUP(this); if (this->needOpBytes(matrix.writeToMemory(NULL))) { @@ -624,59 +627,68 @@ bool SkGPipeCanvas::concat(const SkMatrix& matrix) { fWriter.writeMatrix(matrix); } } - return this->INHERITED::concat(matrix); + this->INHERITED::didConcat(matrix); } -void SkGPipeCanvas::setMatrix(const SkMatrix& matrix) { +void SkGPipeCanvas::didSetMatrix(const SkMatrix& matrix) { NOTIFY_SETUP(this); if (this->needOpBytes(matrix.writeToMemory(NULL))) { this->writeOp(kSetMatrix_DrawOp); fWriter.writeMatrix(matrix); } - this->INHERITED::setMatrix(matrix); + this->INHERITED::didSetMatrix(matrix); } -bool SkGPipeCanvas::clipRect(const SkRect& rect, SkRegion::Op rgnOp, - bool doAntiAlias) { +void SkGPipeCanvas::onClipRect(const SkRect& rect, SkRegion::Op rgnOp, + ClipEdgeStyle edgeStyle) { NOTIFY_SETUP(this); if (this->needOpBytes(sizeof(SkRect))) { - unsigned flags = doAntiAlias & kClip_HasAntiAlias_DrawOpFlag; + unsigned flags = 0; + if (kSoft_ClipEdgeStyle == edgeStyle) { + flags = kClip_HasAntiAlias_DrawOpFlag; + } this->writeOp(kClipRect_DrawOp, flags, rgnOp); fWriter.writeRect(rect); } - return this->INHERITED::clipRect(rect, rgnOp, doAntiAlias); + this->INHERITED::onClipRect(rect, rgnOp, edgeStyle); } -bool SkGPipeCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op rgnOp, - bool doAntiAlias) { +void SkGPipeCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op rgnOp, + ClipEdgeStyle edgeStyle) { NOTIFY_SETUP(this); if (this->needOpBytes(kSizeOfFlatRRect)) { - unsigned flags = doAntiAlias & kClip_HasAntiAlias_DrawOpFlag; + unsigned flags = 0; + if (kSoft_ClipEdgeStyle == edgeStyle) { + flags = kClip_HasAntiAlias_DrawOpFlag; + } this->writeOp(kClipRRect_DrawOp, flags, rgnOp); fWriter.writeRRect(rrect); } - return this->INHERITED::clipRRect(rrect, rgnOp, doAntiAlias); + this->INHERITED::onClipRRect(rrect, rgnOp, edgeStyle); } -bool SkGPipeCanvas::clipPath(const SkPath& path, SkRegion::Op rgnOp, - bool doAntiAlias) { +void SkGPipeCanvas::onClipPath(const SkPath& path, SkRegion::Op rgnOp, + ClipEdgeStyle edgeStyle) { NOTIFY_SETUP(this); if (this->needOpBytes(path.writeToMemory(NULL))) { - unsigned flags = doAntiAlias & kClip_HasAntiAlias_DrawOpFlag; + unsigned flags = 0; + if (kSoft_ClipEdgeStyle == edgeStyle) { + flags = kClip_HasAntiAlias_DrawOpFlag; + } this->writeOp(kClipPath_DrawOp, flags, rgnOp); fWriter.writePath(path); } // we just pass on the bounds of the path - return this->INHERITED::clipRect(path.getBounds(), rgnOp, doAntiAlias); + this->INHERITED::onClipRect(path.getBounds(), rgnOp, edgeStyle); } -bool SkGPipeCanvas::clipRegion(const SkRegion& region, SkRegion::Op rgnOp) { +void SkGPipeCanvas::onClipRegion(const SkRegion& region, SkRegion::Op rgnOp) { NOTIFY_SETUP(this); if (this->needOpBytes(region.writeToMemory(NULL))) { this->writeOp(kClipRegion_DrawOp, 0, rgnOp); fWriter.writeRegion(region); } - return this->INHERITED::clipRegion(region, rgnOp); + this->INHERITED::onClipRegion(region, rgnOp); } /////////////////////////////////////////////////////////////////////////////// @@ -743,6 +755,17 @@ void SkGPipeCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { } } +void SkGPipeCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + NOTIFY_SETUP(this); + this->writePaint(paint); + if (this->needOpBytes(kSizeOfFlatRRect * 2)) { + this->writeOp(kDrawDRRect_DrawOp); + fWriter.writeRRect(outer); + fWriter.writeRRect(inner); + } +} + void SkGPipeCanvas::drawPath(const SkPath& path, const SkPaint& paint) { NOTIFY_SETUP(this); this->writePaint(paint); diff --git a/gfx/skia/trunk/src/ports/SkFontHost_FreeType.cpp b/gfx/skia/trunk/src/ports/SkFontHost_FreeType.cpp index cb7ce8028dcc..fce8259a39ce 100644 --- a/gfx/skia/trunk/src/ports/SkFontHost_FreeType.cpp +++ b/gfx/skia/trunk/src/ports/SkFontHost_FreeType.cpp @@ -1390,6 +1390,7 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx, // pull from format-specific metrics as needed SkScalar ascent, descent, leading, xmin, xmax, ymin, ymax; + SkScalar underlineThickness, underlinePosition; if (face->face_flags & FT_FACE_FLAG_SCALABLE) { // scalable outline font ascent = -SkIntToScalar(face->ascender) / upem; descent = -SkIntToScalar(face->descender) / upem; @@ -1398,6 +1399,17 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx, xmax = SkIntToScalar(face->bbox.xMax) / upem; ymin = -SkIntToScalar(face->bbox.yMin) / upem; ymax = -SkIntToScalar(face->bbox.yMax) / upem; + underlineThickness = SkIntToScalar(face->underline_thickness) / upem; + underlinePosition = -SkIntToScalar(face->underline_position) / upem; + + if(mx) { + mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; + } + if(my){ + my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; + } // we may be able to synthesize x_height and cap_height from outline if (!x_height) { FT_BBox bbox; @@ -1422,6 +1434,17 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx, xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem; ymin = descent + leading; ymax = ascent - descent; + underlineThickness = 0; + underlinePosition = 0; + + if(mx) { + mx->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + mx->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; + } + if(my){ + my->fFlags &= ~SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + my->fFlags &= ~SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; + } } else { goto ERROR; } @@ -1453,6 +1476,8 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx, mx->fXMax = xmax; mx->fXHeight = x_height; mx->fCapHeight = cap_height; + mx->fUnderlineThickness = underlineThickness; + mx->fUnderlinePosition = underlinePosition; } if (my) { my->fTop = ymax * myy; @@ -1465,6 +1490,8 @@ void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx, my->fXMax = xmax; my->fXHeight = x_height; my->fCapHeight = cap_height; + my->fUnderlineThickness = underlineThickness; + my->fUnderlinePosition = underlinePosition; } } diff --git a/gfx/skia/trunk/src/ports/SkFontHost_linux.cpp b/gfx/skia/trunk/src/ports/SkFontHost_linux.cpp index 2f962d7d40d3..4d4e6f171e3a 100644 --- a/gfx/skia/trunk/src/ports/SkFontHost_linux.cpp +++ b/gfx/skia/trunk/src/ports/SkFontHost_linux.cpp @@ -24,9 +24,6 @@ #ifndef SK_FONT_FILE_PREFIX # define SK_FONT_FILE_PREFIX "/usr/share/fonts/truetype/" #endif -#ifndef SK_FONT_FILE_DIR_SEPERATOR -# define SK_FONT_FILE_DIR_SEPERATOR "/" -#endif bool find_name_and_attributes(SkStream* stream, SkString* name, SkTypeface::Style* style, bool* isFixedPitch); @@ -326,8 +323,8 @@ private: SkString name; while (iter.next(&name, false)) { - SkString filename(directory); - filename.append(name); + SkString filename( + SkOSPath::SkPathJoin(directory.c_str(), name.c_str())); bool isFixedPitch; SkString realname; @@ -358,9 +355,8 @@ private: if (name.startsWith(".")) { continue; } - SkString dirname(directory); - dirname.append(name); - dirname.append(SK_FONT_FILE_DIR_SEPERATOR); + SkString dirname( + SkOSPath::SkPathJoin(directory.c_str(), name.c_str())); load_directory_fonts(dirname); } } @@ -377,7 +373,7 @@ private: // Try to pick a default font. static const char* gDefaultNames[] = { - "Arial", "Verdana", "Times New Roman", NULL + "Arial", "Verdana", "Times New Roman", "Droid Sans", NULL }; for (size_t i = 0; i < SK_ARRAY_COUNT(gDefaultNames); ++i) { SkFontStyleSet_Custom* set = this->onMatchFamily(gDefaultNames[i]); diff --git a/gfx/skia/trunk/src/ports/SkFontHost_mac.cpp b/gfx/skia/trunk/src/ports/SkFontHost_mac.cpp index ab6efdf6070c..26d30d726a27 100755 --- a/gfx/skia/trunk/src/ports/SkFontHost_mac.cpp +++ b/gfx/skia/trunk/src/ports/SkFontHost_mac.cpp @@ -1379,6 +1379,11 @@ void SkScalerContext_Mac::generateFontMetrics(SkPaint::FontMetrics* mx, theMetrics.fXMin = CGToScalar( CGRectGetMinX_inline(theBounds)); theMetrics.fXMax = CGToScalar( CGRectGetMaxX_inline(theBounds)); theMetrics.fXHeight = CGToScalar( CTFontGetXHeight(fCTFont)); + theMetrics.fUnderlineThickness = CGToScalar( CTFontGetUnderlineThickness(fCTFont)); + theMetrics.fUnderlinePosition = -CGToScalar( CTFontGetUnderlinePosition(fCTFont)); + + theMetrics.fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + theMetrics.fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; if (mx != NULL) { *mx = theMetrics; @@ -2312,24 +2317,3 @@ SkFontMgr* SkFontMgr::Factory() { return SkNEW(SkFontMgr_Mac); } #endif - -SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, - const char famillyName[], - SkTypeface::Style style) -{ - SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented"); - return NULL; -} - -SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*) -{ - SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented"); - return NULL; -} - -SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) -{ - SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented"); - return NULL; -} - diff --git a/gfx/skia/trunk/src/ports/SkFontHost_sandbox_none.cpp b/gfx/skia/trunk/src/ports/SkFontHost_sandbox_none.cpp deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/gfx/skia/trunk/src/ports/SkFontHost_win.cpp b/gfx/skia/trunk/src/ports/SkFontHost_win.cpp index 4ca0fb918140..9dc720a643b5 100755 --- a/gfx/skia/trunk/src/ports/SkFontHost_win.cpp +++ b/gfx/skia/trunk/src/ports/SkFontHost_win.cpp @@ -1061,6 +1061,11 @@ void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint: mx->fDescent = SkIntToScalar(-otm.otmDescent); mx->fBottom = SkIntToScalar(otm.otmrcFontBox.right); mx->fLeading = SkIntToScalar(otm.otmLineGap); + mx->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize); + mx->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition); + + mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; } if (my) { @@ -1074,6 +1079,11 @@ void SkScalerContext_GDI::generateFontMetrics(SkPaint::FontMetrics* mx, SkPaint: my->fMaxCharWidth = SkIntToScalar(otm.otmTextMetrics.tmMaxCharWidth); my->fXMin = SkIntToScalar(otm.otmrcFontBox.left); my->fXMax = SkIntToScalar(otm.otmrcFontBox.right); + my->fUnderlineThickness = SkIntToScalar(otm.otmsUnderscoreSize); + my->fUnderlinePosition = -SkIntToScalar(otm.otmsUnderscorePosition); + + my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; #endif my->fXHeight = SkIntToScalar(otm.otmsXHeight); diff --git a/gfx/skia/trunk/src/ports/SkFontHost_win_dw.cpp b/gfx/skia/trunk/src/ports/SkFontHost_win_dw.cpp index ce5e49b358c3..b80154aa6154 100644 --- a/gfx/skia/trunk/src/ports/SkFontHost_win_dw.cpp +++ b/gfx/skia/trunk/src/ports/SkFontHost_win_dw.cpp @@ -874,6 +874,11 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx, mx->fBottom = mx->fDescent; mx->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem; mx->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem; + mx->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlinePosition) / upem; + mx->fUnderlinePosition = -(fRec.fTextSize * SkIntToScalar(dwfm.underlineThickness) / upem); + + mx->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + mx->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; } if (my) { @@ -883,6 +888,11 @@ void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx, my->fBottom = my->fDescent; my->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem; my->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem; + my->fUnderlineThickness = fRec.fTextSize * SkIntToScalar(dwfm.underlinePosition) / upem; + my->fUnderlinePosition = -(fRec.fTextSize * SkIntToScalar(dwfm.underlineThickness) / upem); + + my->fFlags |= SkPaint::FontMetrics::kUnderlineThinknessIsValid_Flag; + my->fFlags |= SkPaint::FontMetrics::kUnderlinePositionIsValid_Flag; } } diff --git a/gfx/skia/trunk/src/ports/SkGlobalInitialization_chromium.cpp b/gfx/skia/trunk/src/ports/SkGlobalInitialization_chromium.cpp index 79ed46c70e9b..dd24eaf5e5cb 100644 --- a/gfx/skia/trunk/src/ports/SkGlobalInitialization_chromium.cpp +++ b/gfx/skia/trunk/src/ports/SkGlobalInitialization_chromium.cpp @@ -50,6 +50,7 @@ #include "SkOffsetImageFilter.h" #include "SkOnce.h" #include "SkPerlinNoiseShader.h" +#include "SkPictureImageFilter.h" #include "SkPixelXorXfermode.h" #include "SkRectShaderImageFilter.h" #include "SkResizeImageFilter.h" @@ -88,6 +89,7 @@ static void InitializeFlattenables(int*) { SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader) + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkResizeImageFilter) diff --git a/gfx/skia/trunk/src/ports/SkGlobalInitialization_default.cpp b/gfx/skia/trunk/src/ports/SkGlobalInitialization_default.cpp index 79ed46c70e9b..dd24eaf5e5cb 100644 --- a/gfx/skia/trunk/src/ports/SkGlobalInitialization_default.cpp +++ b/gfx/skia/trunk/src/ports/SkGlobalInitialization_default.cpp @@ -50,6 +50,7 @@ #include "SkOffsetImageFilter.h" #include "SkOnce.h" #include "SkPerlinNoiseShader.h" +#include "SkPictureImageFilter.h" #include "SkPixelXorXfermode.h" #include "SkRectShaderImageFilter.h" #include "SkResizeImageFilter.h" @@ -88,6 +89,7 @@ static void InitializeFlattenables(int*) { SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLine2DPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPath2DPathEffect) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPerlinNoiseShader) + SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPictureImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkPixelXorXfermode) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRectShaderImageFilter) SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkResizeImageFilter) diff --git a/gfx/skia/trunk/src/ports/SkImageDecoder_CG.cpp b/gfx/skia/trunk/src/ports/SkImageDecoder_CG.cpp index 90c282dc9b05..c61ce98a8bc5 100644 --- a/gfx/skia/trunk/src/ports/SkImageDecoder_CG.cpp +++ b/gfx/skia/trunk/src/ports/SkImageDecoder_CG.cpp @@ -208,8 +208,8 @@ bool SkImageEncoder_CG::onEncode(SkWStream* stream, const SkBitmap& bm, // format. // : CGImageDestinationFinalize image destination does not have enough images // So instead we copy to 8888. - if (bm.config() == SkBitmap::kARGB_4444_Config) { - bm.copyTo(&bitmap8888, SkBitmap::kARGB_8888_Config); + if (bm.colorType() == kARGB_4444_SkColorType) { + bm.copyTo(&bitmap8888, kPMColor_SkColorType); bmPtr = &bitmap8888; } type = kUTTypePNG; diff --git a/gfx/skia/trunk/src/ports/SkImageDecoder_WIC.cpp b/gfx/skia/trunk/src/ports/SkImageDecoder_WIC.cpp index 9aaed869e363..9d5479497ea3 100644 --- a/gfx/skia/trunk/src/ports/SkImageDecoder_WIC.cpp +++ b/gfx/skia/trunk/src/ports/SkImageDecoder_WIC.cpp @@ -186,7 +186,7 @@ bool SkImageDecoder_WIC::decodeStream(SkStream* stream, SkBitmap* bm, WICModes w //Exit early if we're only looking for the bitmap bounds. if (SUCCEEDED(hr)) { - bm->setConfig(SkBitmap::kARGB_8888_Config, width, height); + bm->setConfig(SkImageInfo::MakeN32Premul(width, height)); if (kDecodeBounds_WICMode == wicMode) { return true; } @@ -306,10 +306,10 @@ bool SkImageEncoder_WIC::onEncode(SkWStream* stream //Convert to 8888 if needed. const SkBitmap* bitmap; SkBitmap bitmapCopy; - if (SkBitmap::kARGB_8888_Config == bitmapOrig.config() && bitmapOrig.isOpaque()) { + if (kPMColor_SkColorType == bitmapOrig.colorType() && bitmapOrig.isOpaque()) { bitmap = &bitmapOrig; } else { - if (!bitmapOrig.copyTo(&bitmapCopy, SkBitmap::kARGB_8888_Config)) { + if (!bitmapOrig.copyTo(&bitmapCopy, kPMColor_SkColorType)) { return false; } bitmap = &bitmapCopy; diff --git a/gfx/skia/trunk/src/ports/SkThread_none.cpp b/gfx/skia/trunk/src/ports/SkThread_none.cpp deleted file mode 100644 index 638d7d017dd9..000000000000 --- a/gfx/skia/trunk/src/ports/SkThread_none.cpp +++ /dev/null @@ -1,43 +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. - */ - -#include "SkThread.h" - -int32_t sk_atomic_inc(int32_t* addr) { - int32_t value = *addr; - *addr = value + 1; - return value; -} - -int32_t sk_atomic_add(int32_t* addr, int32_t inc) { - int32_t value = *addr; - *addr = value + inc; - return value; -} - -int32_t sk_atomic_dec(int32_t* addr) { - int32_t value = *addr; - *addr = value - 1; - return value; -} -void sk_membar_aquire__after_atomic_dec() { } - -int32_t sk_atomic_conditional_inc(int32_t* addr) { - int32_t value = *addr; - if (value != 0) ++*addr; - return value; -} -void sk_membar_aquire__after_atomic_conditional_inc() { } - -SkMutex::SkMutex() {} - -SkMutex::~SkMutex() {} - -#ifndef SK_USE_POSIX_THREADS -void SkMutex::acquire() {} -void SkMutex::release() {} -#endif diff --git a/gfx/skia/trunk/src/ports/SkThread_pthread.cpp b/gfx/skia/trunk/src/ports/SkThread_pthread.cpp deleted file mode 100644 index a78c7b2f14e3..000000000000 --- a/gfx/skia/trunk/src/ports/SkThread_pthread.cpp +++ /dev/null @@ -1,197 +0,0 @@ - -/* - * Copyright 2011 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ -#include "SkThread.h" - -#include -#include - -#ifndef SK_BUILD_FOR_ANDROID - -/** - We prefer the GCC intrinsic implementation of the atomic operations over the - SkMutex-based implementation. The SkMutex version suffers from static - destructor ordering problems. - Note clang also defines the GCC version macros and implements the intrinsics. - TODO: Verify that gcc-style __sync_* intrinsics work on ARM - According to this the intrinsics are supported on ARM in LLVM 2.7+ - http://llvm.org/releases/2.7/docs/ReleaseNotes.html -*/ -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || __GNUC__ > 4 - #if (defined(__x86_64) || defined(__i386__)) - #define GCC_INTRINSIC - #endif -#endif - -#if defined(GCC_INTRINSIC) - -int32_t sk_atomic_inc(int32_t* addr) -{ - return __sync_fetch_and_add(addr, 1); -} - -int32_t sk_atomic_add(int32_t* addr, int32_t inc) -{ - return __sync_fetch_and_add(addr, inc); -} - -int32_t sk_atomic_dec(int32_t* addr) -{ - return __sync_fetch_and_add(addr, -1); -} -void sk_membar_aquire__after_atomic_dec() { } - -int32_t sk_atomic_conditional_inc(int32_t* addr) -{ - int32_t value = *addr; - - while (true) { - if (value == 0) { - return 0; - } - - int32_t before = __sync_val_compare_and_swap(addr, value, value + 1); - - if (before == value) { - return value; - } else { - value = before; - } - } -} -void sk_membar_aquire__after_atomic_conditional_inc() { } - -#else - -SkMutex gAtomicMutex; - -int32_t sk_atomic_inc(int32_t* addr) -{ - SkAutoMutexAcquire ac(gAtomicMutex); - - int32_t value = *addr; - *addr = value + 1; - return value; -} - -int32_t sk_atomic_add(int32_t* addr, int32_t inc) -{ - SkAutoMutexAcquire ac(gAtomicMutex); - - int32_t value = *addr; - *addr = value + inc; - return value; -} - -int32_t sk_atomic_dec(int32_t* addr) -{ - SkAutoMutexAcquire ac(gAtomicMutex); - - int32_t value = *addr; - *addr = value - 1; - return value; -} -void sk_membar_aquire__after_atomic_dec() { } - -int32_t sk_atomic_conditional_inc(int32_t* addr) -{ - SkAutoMutexAcquire ac(gAtomicMutex); - - int32_t value = *addr; - if (value != 0) ++*addr; - return value; -} -void sk_membar_aquire__after_atomic_conditional_inc() { } - -#endif - -#endif // SK_BUILD_FOR_ANDROID - -////////////////////////////////////////////////////////////////////////////// - -static void print_pthread_error(int status) { - switch (status) { - case 0: // success - break; - case EINVAL: - SkDebugf("pthread error [%d] EINVAL\n", status); - break; - case EBUSY: - SkDebugf("pthread error [%d] EBUSY\n", status); - break; - default: - SkDebugf("pthread error [%d] unknown\n", status); - break; - } -} - -#ifdef SK_USE_POSIX_THREADS - -SkMutex::SkMutex() { - int status; - - status = pthread_mutex_init(&fMutex, NULL); - if (status != 0) { - print_pthread_error(status); - SkASSERT(0 == status); - } -} - -SkMutex::~SkMutex() { - int status = pthread_mutex_destroy(&fMutex); - - // only report errors on non-global mutexes - if (status != 0) { - print_pthread_error(status); - SkASSERT(0 == status); - } -} - -#else // !SK_USE_POSIX_THREADS - -SkMutex::SkMutex() { - if (sizeof(pthread_mutex_t) > sizeof(fStorage)) { - SkDEBUGF(("pthread mutex size = %d\n", sizeof(pthread_mutex_t))); - SkDEBUGFAIL("mutex storage is too small"); - } - - int status; - pthread_mutexattr_t attr; - - status = pthread_mutexattr_init(&attr); - print_pthread_error(status); - SkASSERT(0 == status); - - status = pthread_mutex_init((pthread_mutex_t*)fStorage, &attr); - print_pthread_error(status); - SkASSERT(0 == status); -} - -SkMutex::~SkMutex() { - int status = pthread_mutex_destroy((pthread_mutex_t*)fStorage); -#if 0 - // only report errors on non-global mutexes - if (!fIsGlobal) { - print_pthread_error(status); - SkASSERT(0 == status); - } -#endif -} - -void SkMutex::acquire() { - int status = pthread_mutex_lock((pthread_mutex_t*)fStorage); - print_pthread_error(status); - SkASSERT(0 == status); -} - -void SkMutex::release() { - int status = pthread_mutex_unlock((pthread_mutex_t*)fStorage); - print_pthread_error(status); - SkASSERT(0 == status); -} - -#endif // !SK_USE_POSIX_THREADS diff --git a/gfx/skia/trunk/src/ports/SkThread_win.cpp b/gfx/skia/trunk/src/ports/SkThread_win.cpp deleted file mode 100644 index 708db24ab99d..000000000000 --- a/gfx/skia/trunk/src/ports/SkThread_win.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2008 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. - */ - -#include -#include -#include "SkThread.h" - -//MSDN says in order to declare an interlocked function for use as an -//intrinsic, include intrin.h and put the function in a #pragma intrinsic -//directive. -//The pragma appears to be unnecessary, but doesn't hurt. -#pragma intrinsic(_InterlockedIncrement, _InterlockedExchangeAdd, _InterlockedDecrement) -#pragma intrinsic(_InterlockedCompareExchange) - -int32_t sk_atomic_inc(int32_t* addr) { - // InterlockedIncrement returns the new value, we want to return the old. - return _InterlockedIncrement(reinterpret_cast(addr)) - 1; -} - -int32_t sk_atomic_add(int32_t* addr, int32_t inc) { - return _InterlockedExchangeAdd(reinterpret_cast(addr), - static_cast(inc)); -} - -int32_t sk_atomic_dec(int32_t* addr) { - return _InterlockedDecrement(reinterpret_cast(addr)) + 1; -} -void sk_membar_aquire__after_atomic_dec() { } - -int32_t sk_atomic_conditional_inc(int32_t* addr) { - while (true) { - LONG value = static_cast(*addr); - if (value == 0) { - return 0; - } - if (_InterlockedCompareExchange(reinterpret_cast(addr), - value + 1, - value) == value) { - return value; - } - } -} -void sk_membar_aquire__after_atomic_conditional_inc() { } - -SkMutex::SkMutex() { - SK_COMPILE_ASSERT(sizeof(fStorage) > sizeof(CRITICAL_SECTION), - NotEnoughSizeForCriticalSection); - InitializeCriticalSection(reinterpret_cast(&fStorage)); -} - -SkMutex::~SkMutex() { - DeleteCriticalSection(reinterpret_cast(&fStorage)); -} - -void SkMutex::acquire() { - EnterCriticalSection(reinterpret_cast(&fStorage)); -} - -void SkMutex::release() { - LeaveCriticalSection(reinterpret_cast(&fStorage)); -} diff --git a/gfx/skia/trunk/src/sfnt/SkOTTableTypes.h b/gfx/skia/trunk/src/sfnt/SkOTTableTypes.h index 9adec9b81e4c..c978cc017911 100644 --- a/gfx/skia/trunk/src/sfnt/SkOTTableTypes.h +++ b/gfx/skia/trunk/src/sfnt/SkOTTableTypes.h @@ -8,6 +8,7 @@ #ifndef SkOTTableTypes_DEFINED #define SkOTTableTypes_DEFINED +#include "SkTemplates.h" #include "SkTypes.h" #include "SkEndian.h" @@ -45,4 +46,16 @@ public: ); }; +/** SkOTSetUSHORTBit::value is an SK_OT_USHORT with the Nth BE bit set. */ +template struct SkOTSetUSHORTBit { + static const uint16_t bit = SkTSetBit::value; + static const SK_OT_USHORT value = SkTEndian_SwapBE16(bit); +}; + +/** SkOTSetUSHORTBit::value is an SK_OT_ULONG with the Nth BE bit set. */ +template struct SkOTSetULONGBit { + static const uint32_t bit = SkTSetBit::value; + static const SK_OT_ULONG value = SkTEndian_SwapBE32(bit); +}; + #endif diff --git a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V0.h b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V0.h index 14d322f7ce09..b65bcf7f6319 100644 --- a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V0.h +++ b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V0.h @@ -76,10 +76,10 @@ struct SkOTTableOS2_V0 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT Installable = SkTEndian_SwapBE16(0); - static const SK_OT_USHORT RestrictedMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT PreviewPrintMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT EditableMask = SkTEndian_SwapBE16(1 << 3); + static const SK_OT_USHORT Installable = 0; + static const SK_OT_USHORT RestrictedMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT PreviewPrintMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT EditableMask = SkOTSetUSHORTBit<3>::value; SK_OT_USHORT value; } raw; } fsType; @@ -121,13 +121,13 @@ struct SkOTTableOS2_V0 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT ItalicMask = SkTEndian_SwapBE16(1 << 0); - static const SK_OT_USHORT UnderscoreMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT NegativeMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT OutlinedMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT StrikeoutMask = SkTEndian_SwapBE16(1 << 4); - static const SK_OT_USHORT BoldMask = SkTEndian_SwapBE16(1 << 5); - static const SK_OT_USHORT RegularMask = SkTEndian_SwapBE16(1 << 6); + static const SK_OT_USHORT ItalicMask = SkOTSetUSHORTBit<0>::value; + static const SK_OT_USHORT UnderscoreMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT NegativeMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT OutlinedMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT StrikeoutMask = SkOTSetUSHORTBit<4>::value; + static const SK_OT_USHORT BoldMask = SkOTSetUSHORTBit<5>::value; + static const SK_OT_USHORT RegularMask = SkOTSetUSHORTBit<6>::value; SK_OT_USHORT value; } raw; } fsSelection; diff --git a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V1.h b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V1.h index 52a60c0a4d4a..e53c0e67a5e5 100644 --- a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V1.h +++ b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V1.h @@ -74,10 +74,10 @@ struct SkOTTableOS2_V1 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT Installable = SkTEndian_SwapBE16(0); - static const SK_OT_USHORT RestrictedMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT PreviewPrintMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT EditableMask = SkTEndian_SwapBE16(1 << 3); + static const SK_OT_USHORT Installable = 0; + static const SK_OT_USHORT RestrictedMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT PreviewPrintMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT EditableMask = SkOTSetUSHORTBit<3>::value; SK_OT_USHORT value; } raw; } fsType; @@ -261,80 +261,80 @@ struct SkOTTableOS2_V1 { } field; struct Raw { struct l0 { - static const SK_OT_ULONG BasicLatinMask = SkTEndian_SwapBE32(1 << 0); - static const SK_OT_ULONG Latin1SupplementMask = SkTEndian_SwapBE32(1 << 1); - static const SK_OT_ULONG LatinExtendedAMask = SkTEndian_SwapBE32(1 << 2); - static const SK_OT_ULONG LatinExtendedBMask = SkTEndian_SwapBE32(1 << 3); - static const SK_OT_ULONG IPAExtensionsMask = SkTEndian_SwapBE32(1 << 4); - static const SK_OT_ULONG SpacingModifierLettersMask = SkTEndian_SwapBE32(1 << 5); - static const SK_OT_ULONG CombiningDiacriticalMarksMask = SkTEndian_SwapBE32(1 << 6); - static const SK_OT_ULONG BasicGreekMask = SkTEndian_SwapBE32(1 << 7); - static const SK_OT_ULONG GreekSymbolsAndCCopticMask = SkTEndian_SwapBE32(1 << 8); - static const SK_OT_ULONG CyrillicMask = SkTEndian_SwapBE32(1 << 9); - static const SK_OT_ULONG ArmenianMask = SkTEndian_SwapBE32(1 << 10); - static const SK_OT_ULONG BasicHebrewMask = SkTEndian_SwapBE32(1 << 11); - static const SK_OT_ULONG HebrewExtendedABMask = SkTEndian_SwapBE32(1 << 12); - static const SK_OT_ULONG BasicArabicMask = SkTEndian_SwapBE32(1 << 13); - static const SK_OT_ULONG ArabicExtendedMask = SkTEndian_SwapBE32(1 << 14); - static const SK_OT_ULONG DevanagariMask = SkTEndian_SwapBE32(1 << 15); - static const SK_OT_ULONG BengaliMask = SkTEndian_SwapBE32(1 << 16); - static const SK_OT_ULONG GurmukhiMask = SkTEndian_SwapBE32(1 << 17); - static const SK_OT_ULONG GujaratiMask = SkTEndian_SwapBE32(1 << 18); - static const SK_OT_ULONG OriyaMask = SkTEndian_SwapBE32(1 << 19); - static const SK_OT_ULONG TamilMask = SkTEndian_SwapBE32(1 << 20); - static const SK_OT_ULONG TeluguMask = SkTEndian_SwapBE32(1 << 21); - static const SK_OT_ULONG KannadaMask = SkTEndian_SwapBE32(1 << 22); - static const SK_OT_ULONG MalayalamMask = SkTEndian_SwapBE32(1 << 23); - static const SK_OT_ULONG ThaiMask = SkTEndian_SwapBE32(1 << 24); - static const SK_OT_ULONG LaoMask = SkTEndian_SwapBE32(1 << 25); - static const SK_OT_ULONG BasicGeorgianMask = SkTEndian_SwapBE32(1 << 26); - static const SK_OT_ULONG GeorgianExtendedMask = SkTEndian_SwapBE32(1 << 27); - static const SK_OT_ULONG HangulJamoMask = SkTEndian_SwapBE32(1 << 28); - static const SK_OT_ULONG LatinExtendedAdditionalMask = SkTEndian_SwapBE32(1 << 29); - static const SK_OT_ULONG GreekExtendedMask = SkTEndian_SwapBE32(1 << 30); - static const SK_OT_ULONG GeneralPunctuationMask = SkTEndian_SwapBE32(1 << 31); + static const SK_OT_ULONG BasicLatinMask = SkOTSetULONGBit<0>::value; + static const SK_OT_ULONG Latin1SupplementMask = SkOTSetULONGBit<1>::value; + static const SK_OT_ULONG LatinExtendedAMask = SkOTSetULONGBit<2>::value; + static const SK_OT_ULONG LatinExtendedBMask = SkOTSetULONGBit<3>::value; + static const SK_OT_ULONG IPAExtensionsMask = SkOTSetULONGBit<4>::value; + static const SK_OT_ULONG SpacingModifierLettersMask = SkOTSetULONGBit<5>::value; + static const SK_OT_ULONG CombiningDiacriticalMarksMask = SkOTSetULONGBit<6>::value; + static const SK_OT_ULONG BasicGreekMask = SkOTSetULONGBit<7>::value; + static const SK_OT_ULONG GreekSymbolsAndCCopticMask = SkOTSetULONGBit<8>::value; + static const SK_OT_ULONG CyrillicMask = SkOTSetULONGBit<9>::value; + static const SK_OT_ULONG ArmenianMask = SkOTSetULONGBit<10>::value; + static const SK_OT_ULONG BasicHebrewMask = SkOTSetULONGBit<11>::value; + static const SK_OT_ULONG HebrewExtendedABMask = SkOTSetULONGBit<12>::value; + static const SK_OT_ULONG BasicArabicMask = SkOTSetULONGBit<13>::value; + static const SK_OT_ULONG ArabicExtendedMask = SkOTSetULONGBit<14>::value; + static const SK_OT_ULONG DevanagariMask = SkOTSetULONGBit<15>::value; + static const SK_OT_ULONG BengaliMask = SkOTSetULONGBit<16>::value; + static const SK_OT_ULONG GurmukhiMask = SkOTSetULONGBit<17>::value; + static const SK_OT_ULONG GujaratiMask = SkOTSetULONGBit<18>::value; + static const SK_OT_ULONG OriyaMask = SkOTSetULONGBit<19>::value; + static const SK_OT_ULONG TamilMask = SkOTSetULONGBit<20>::value; + static const SK_OT_ULONG TeluguMask = SkOTSetULONGBit<21>::value; + static const SK_OT_ULONG KannadaMask = SkOTSetULONGBit<22>::value; + static const SK_OT_ULONG MalayalamMask = SkOTSetULONGBit<23>::value; + static const SK_OT_ULONG ThaiMask = SkOTSetULONGBit<24>::value; + static const SK_OT_ULONG LaoMask = SkOTSetULONGBit<25>::value; + static const SK_OT_ULONG BasicGeorgianMask = SkOTSetULONGBit<26>::value; + static const SK_OT_ULONG GeorgianExtendedMask = SkOTSetULONGBit<27>::value; + static const SK_OT_ULONG HangulJamoMask = SkOTSetULONGBit<28>::value; + static const SK_OT_ULONG LatinExtendedAdditionalMask = SkOTSetULONGBit<29>::value; + static const SK_OT_ULONG GreekExtendedMask = SkOTSetULONGBit<30>::value; + static const SK_OT_ULONG GeneralPunctuationMask = SkOTSetULONGBit<31>::value; }; struct l1 { - static const SK_OT_ULONG SuperscriptsAndSubscriptsMask = SkTEndian_SwapBE32(1 << (32 - 32)); - static const SK_OT_ULONG CurrencySymbolsMask = SkTEndian_SwapBE32(1 << (33 - 32)); - static const SK_OT_ULONG CombiningDiacriticalMarksForSymbolsMask = SkTEndian_SwapBE32(1 << (34 - 32)); - static const SK_OT_ULONG LetterlikeSymbolsMask = SkTEndian_SwapBE32(1 << (35 - 32)); - static const SK_OT_ULONG NumberFormsMask = SkTEndian_SwapBE32(1 << (36 - 32)); - static const SK_OT_ULONG ArrowsMask = SkTEndian_SwapBE32(1 << (37 - 32)); - static const SK_OT_ULONG MathematicalOperatorsMask = SkTEndian_SwapBE32(1 << (38 - 32)); - static const SK_OT_ULONG MiscellaneousTechnicalMask = SkTEndian_SwapBE32(1 << (39 - 32)); - static const SK_OT_ULONG ControlPicturesMask = SkTEndian_SwapBE32(1 << (40 - 32)); - static const SK_OT_ULONG OpticalCharacterRecognitionMask = SkTEndian_SwapBE32(1 << (41 - 32)); - static const SK_OT_ULONG EnclosedAlphanumericsMask = SkTEndian_SwapBE32(1 << (42 - 32)); - static const SK_OT_ULONG BoxDrawingMask = SkTEndian_SwapBE32(1 << (43 - 32)); - static const SK_OT_ULONG BlockElementsMask = SkTEndian_SwapBE32(1 << (44 - 32)); - static const SK_OT_ULONG GeometricShapesMask = SkTEndian_SwapBE32(1 << (45 - 32)); - static const SK_OT_ULONG MiscellaneousSymbolsMask = SkTEndian_SwapBE32(1 << (46 - 32)); - static const SK_OT_ULONG DingbatsMask = SkTEndian_SwapBE32(1 << (47 - 32)); - static const SK_OT_ULONG CJKSymbolsAndPunctuationMask = SkTEndian_SwapBE32(1 << (48 - 32)); - static const SK_OT_ULONG HiraganaMask = SkTEndian_SwapBE32(1 << (49 - 32)); - static const SK_OT_ULONG KatakanaMask = SkTEndian_SwapBE32(1 << (50 - 32)); - static const SK_OT_ULONG BopomofoMask = SkTEndian_SwapBE32(1 << (51 - 32)); - static const SK_OT_ULONG HangulCompatibilityJamoMask = SkTEndian_SwapBE32(1 << (52 - 32)); - static const SK_OT_ULONG CJKMiscellaneousMask = SkTEndian_SwapBE32(1 << (53 - 32)); - static const SK_OT_ULONG EnclosedCJKLettersAndMonthsMask = SkTEndian_SwapBE32(1 << (54 - 32)); - static const SK_OT_ULONG CJKCompatibilityMask = SkTEndian_SwapBE32(1 << (55 - 32)); - static const SK_OT_ULONG HangulMask = SkTEndian_SwapBE32(1 << (56 - 32)); + static const SK_OT_ULONG SuperscriptsAndSubscriptsMask = SkOTSetULONGBit<32 - 32>::value; + static const SK_OT_ULONG CurrencySymbolsMask = SkOTSetULONGBit<33 - 32>::value; + static const SK_OT_ULONG CombiningDiacriticalMarksForSymbolsMask = SkOTSetULONGBit<34 - 32>::value; + static const SK_OT_ULONG LetterlikeSymbolsMask = SkOTSetULONGBit<35 - 32>::value; + static const SK_OT_ULONG NumberFormsMask = SkOTSetULONGBit<36 - 32>::value; + static const SK_OT_ULONG ArrowsMask = SkOTSetULONGBit<37 - 32>::value; + static const SK_OT_ULONG MathematicalOperatorsMask = SkOTSetULONGBit<38 - 32>::value; + static const SK_OT_ULONG MiscellaneousTechnicalMask = SkOTSetULONGBit<39 - 32>::value; + static const SK_OT_ULONG ControlPicturesMask = SkOTSetULONGBit<40 - 32>::value; + static const SK_OT_ULONG OpticalCharacterRecognitionMask = SkOTSetULONGBit<41 - 32>::value; + static const SK_OT_ULONG EnclosedAlphanumericsMask = SkOTSetULONGBit<42 - 32>::value; + static const SK_OT_ULONG BoxDrawingMask = SkOTSetULONGBit<43 - 32>::value; + static const SK_OT_ULONG BlockElementsMask = SkOTSetULONGBit<44 - 32>::value; + static const SK_OT_ULONG GeometricShapesMask = SkOTSetULONGBit<45 - 32>::value; + static const SK_OT_ULONG MiscellaneousSymbolsMask = SkOTSetULONGBit<46 - 32>::value; + static const SK_OT_ULONG DingbatsMask = SkOTSetULONGBit<47 - 32>::value; + static const SK_OT_ULONG CJKSymbolsAndPunctuationMask = SkOTSetULONGBit<48 - 32>::value; + static const SK_OT_ULONG HiraganaMask = SkOTSetULONGBit<49 - 32>::value; + static const SK_OT_ULONG KatakanaMask = SkOTSetULONGBit<50 - 32>::value; + static const SK_OT_ULONG BopomofoMask = SkOTSetULONGBit<51 - 32>::value; + static const SK_OT_ULONG HangulCompatibilityJamoMask = SkOTSetULONGBit<52 - 32>::value; + static const SK_OT_ULONG CJKMiscellaneousMask = SkOTSetULONGBit<53 - 32>::value; + static const SK_OT_ULONG EnclosedCJKLettersAndMonthsMask = SkOTSetULONGBit<54 - 32>::value; + static const SK_OT_ULONG CJKCompatibilityMask = SkOTSetULONGBit<55 - 32>::value; + static const SK_OT_ULONG HangulMask = SkOTSetULONGBit<56 - 32>::value; //Reserved //Reserved - static const SK_OT_ULONG CJKUnifiedIdeographsMask = SkTEndian_SwapBE32(1 << (59 - 32)); - static const SK_OT_ULONG PrivateUseAreaMask = SkTEndian_SwapBE32(1 << (60 - 32)); - static const SK_OT_ULONG CJKCompatibilityIdeographsMask = SkTEndian_SwapBE32(1 << (61 - 32)); - static const SK_OT_ULONG AlphabeticPresentationFormsMask = SkTEndian_SwapBE32(1 << (62 - 32)); - static const SK_OT_ULONG ArabicPresentationFormsAMask = SkTEndian_SwapBE32(1 << (63 - 32)); + static const SK_OT_ULONG CJKUnifiedIdeographsMask = SkOTSetULONGBit<59 - 32>::value; + static const SK_OT_ULONG PrivateUseAreaMask = SkOTSetULONGBit<60 - 32>::value; + static const SK_OT_ULONG CJKCompatibilityIdeographsMask = SkOTSetULONGBit<61 - 32>::value; + static const SK_OT_ULONG AlphabeticPresentationFormsMask = SkOTSetULONGBit<62 - 32>::value; + static const SK_OT_ULONG ArabicPresentationFormsAMask = SkOTSetULONGBit<63 - 32>::value; }; struct l2 { - static const SK_OT_ULONG CombiningHalfMarksMask = SkTEndian_SwapBE32(1 << (64 - 64)); - static const SK_OT_ULONG CJKCompatibilityFormsMask = SkTEndian_SwapBE32(1 << (65 - 64)); - static const SK_OT_ULONG SmallFormVariantsMask = SkTEndian_SwapBE32(1 << (66 - 64)); - static const SK_OT_ULONG ArabicPresentationFormsBMask = SkTEndian_SwapBE32(1 << (67 - 64)); - static const SK_OT_ULONG HalfwidthAndFullwidthFormsMask = SkTEndian_SwapBE32(1 << (68 - 64)); - static const SK_OT_ULONG SpecialsMask = SkTEndian_SwapBE32(1 << (69 - 64)); + static const SK_OT_ULONG CombiningHalfMarksMask = SkOTSetULONGBit<64 - 64>::value; + static const SK_OT_ULONG CJKCompatibilityFormsMask = SkOTSetULONGBit<65 - 64>::value; + static const SK_OT_ULONG SmallFormVariantsMask = SkOTSetULONGBit<66 - 64>::value; + static const SK_OT_ULONG ArabicPresentationFormsBMask = SkOTSetULONGBit<67 - 64>::value; + static const SK_OT_ULONG HalfwidthAndFullwidthFormsMask = SkOTSetULONGBit<68 - 64>::value; + static const SK_OT_ULONG SpecialsMask = SkOTSetULONGBit<69 - 64>::value; }; SK_OT_ULONG value[4]; } raw; @@ -364,13 +364,13 @@ struct SkOTTableOS2_V1 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT ItalicMask = SkTEndian_SwapBE16(1 << 0); - static const SK_OT_USHORT UnderscoreMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT NegativeMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT OutlinedMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT StrikeoutMask = SkTEndian_SwapBE16(1 << 4); - static const SK_OT_USHORT BoldMask = SkTEndian_SwapBE16(1 << 5); - static const SK_OT_USHORT RegularMask = SkTEndian_SwapBE16(1 << 6); + static const SK_OT_USHORT ItalicMask = SkOTSetUSHORTBit<0>::value; + static const SK_OT_USHORT UnderscoreMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT NegativeMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT OutlinedMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT StrikeoutMask = SkOTSetUSHORTBit<4>::value; + static const SK_OT_USHORT BoldMask = SkOTSetUSHORTBit<5>::value; + static const SK_OT_USHORT RegularMask = SkOTSetUSHORTBit<6>::value; SK_OT_USHORT value; } raw; } fsSelection; @@ -469,41 +469,41 @@ struct SkOTTableOS2_V1 { } field; struct Raw { struct l0 { - static const SK_OT_ULONG Latin1_1252Mask = SkTEndian_SwapBE32(1 << 0); - static const SK_OT_ULONG Latin2EasternEurope_1250Mask = SkTEndian_SwapBE32(1 << 1); - static const SK_OT_ULONG Cyrillic_1251Mask = SkTEndian_SwapBE32(1 << 2); - static const SK_OT_ULONG Greek_1253Mask = SkTEndian_SwapBE32(1 << 3); - static const SK_OT_ULONG Turkish_1254Mask = SkTEndian_SwapBE32(1 << 4); - static const SK_OT_ULONG Hebrew_1255Mask = SkTEndian_SwapBE32(1 << 5); - static const SK_OT_ULONG Arabic_1256Mask = SkTEndian_SwapBE32(1 << 6); - static const SK_OT_ULONG WindowsBaltic_1257Mask = SkTEndian_SwapBE32(1 << 7); - static const SK_OT_ULONG Thai_874Mask = SkTEndian_SwapBE32(1 << 16); - static const SK_OT_ULONG JISJapan_932Mask = SkTEndian_SwapBE32(1 << 17); - static const SK_OT_ULONG ChineseSimplified_936Mask = SkTEndian_SwapBE32(1 << 18); - static const SK_OT_ULONG KoreanWansung_949Mask = SkTEndian_SwapBE32(1 << 19); - static const SK_OT_ULONG ChineseTraditional_950Mask = SkTEndian_SwapBE32(1 << 20); - static const SK_OT_ULONG KoreanJohab_1361Mask = SkTEndian_SwapBE32(1 << 21); - static const SK_OT_ULONG MacintoshCharacterSetMask = SkTEndian_SwapBE32(1 << 29); - static const SK_OT_ULONG OEMCharacterSetMask = SkTEndian_SwapBE32(1 << 30); - static const SK_OT_ULONG SymbolCharacterSetMask = SkTEndian_SwapBE32(1 << 31); + static const SK_OT_ULONG Latin1_1252Mask = SkOTSetULONGBit<0>::value; + static const SK_OT_ULONG Latin2EasternEurope_1250Mask = SkOTSetULONGBit<1>::value; + static const SK_OT_ULONG Cyrillic_1251Mask = SkOTSetULONGBit<2>::value; + static const SK_OT_ULONG Greek_1253Mask = SkOTSetULONGBit<3>::value; + static const SK_OT_ULONG Turkish_1254Mask = SkOTSetULONGBit<4>::value; + static const SK_OT_ULONG Hebrew_1255Mask = SkOTSetULONGBit<5>::value; + static const SK_OT_ULONG Arabic_1256Mask = SkOTSetULONGBit<6>::value; + static const SK_OT_ULONG WindowsBaltic_1257Mask = SkOTSetULONGBit<7>::value; + static const SK_OT_ULONG Thai_874Mask = SkOTSetULONGBit<16>::value; + static const SK_OT_ULONG JISJapan_932Mask = SkOTSetULONGBit<17>::value; + static const SK_OT_ULONG ChineseSimplified_936Mask = SkOTSetULONGBit<18>::value; + static const SK_OT_ULONG KoreanWansung_949Mask = SkOTSetULONGBit<19>::value; + static const SK_OT_ULONG ChineseTraditional_950Mask = SkOTSetULONGBit<20>::value; + static const SK_OT_ULONG KoreanJohab_1361Mask = SkOTSetULONGBit<21>::value; + static const SK_OT_ULONG MacintoshCharacterSetMask = SkOTSetULONGBit<29>::value; + static const SK_OT_ULONG OEMCharacterSetMask = SkOTSetULONGBit<30>::value; + static const SK_OT_ULONG SymbolCharacterSetMask = SkOTSetULONGBit<31>::value; }; struct l1 { - static const SK_OT_ULONG IBMGreek_869Mask = SkTEndian_SwapBE32(1 << (48 - 32)); - static const SK_OT_ULONG MSDOSRussian_866Mask = SkTEndian_SwapBE32(1 << (49 - 32)); - static const SK_OT_ULONG MSDOSNordic_865Mask = SkTEndian_SwapBE32(1 << (50 - 32)); - static const SK_OT_ULONG Arabic_864Mask = SkTEndian_SwapBE32(1 << (51 - 32)); - static const SK_OT_ULONG MSDOSCanadianFrench_863Mask = SkTEndian_SwapBE32(1 << (52 - 32)); - static const SK_OT_ULONG Hebrew_862Mask = SkTEndian_SwapBE32(1 << (53 - 32)); - static const SK_OT_ULONG MSDOSIcelandic_861Mask = SkTEndian_SwapBE32(1 << (54 - 32)); - static const SK_OT_ULONG MSDOSPortuguese_860Mask = SkTEndian_SwapBE32(1 << (55 - 32)); - static const SK_OT_ULONG IBMTurkish_857Mask = SkTEndian_SwapBE32(1 << (56 - 32)); - static const SK_OT_ULONG IBMCyrillic_855Mask = SkTEndian_SwapBE32(1 << (57 - 32)); - static const SK_OT_ULONG Latin2_852Mask = SkTEndian_SwapBE32(1 << (58 - 32)); - static const SK_OT_ULONG MSDOSBaltic_775Mask = SkTEndian_SwapBE32(1 << (59 - 32)); - static const SK_OT_ULONG Greek_737Mask = SkTEndian_SwapBE32(1 << (60 - 32)); - static const SK_OT_ULONG Arabic_708Mask = SkTEndian_SwapBE32(1 << (61 - 32)); - static const SK_OT_ULONG WELatin1_850Mask = SkTEndian_SwapBE32(1 << (62 - 32)); - static const SK_OT_ULONG US_437Mask = SkTEndian_SwapBE32(1 << (63 - 32)); + static const SK_OT_ULONG IBMGreek_869Mask = SkOTSetULONGBit<48 - 32>::value; + static const SK_OT_ULONG MSDOSRussian_866Mask = SkOTSetULONGBit<49 - 32>::value; + static const SK_OT_ULONG MSDOSNordic_865Mask = SkOTSetULONGBit<50 - 32>::value; + static const SK_OT_ULONG Arabic_864Mask = SkOTSetULONGBit<51 - 32>::value; + static const SK_OT_ULONG MSDOSCanadianFrench_863Mask = SkOTSetULONGBit<52 - 32>::value; + static const SK_OT_ULONG Hebrew_862Mask = SkOTSetULONGBit<53 - 32>::value; + static const SK_OT_ULONG MSDOSIcelandic_861Mask = SkOTSetULONGBit<54 - 32>::value; + static const SK_OT_ULONG MSDOSPortuguese_860Mask = SkOTSetULONGBit<55 - 32>::value; + static const SK_OT_ULONG IBMTurkish_857Mask = SkOTSetULONGBit<56 - 32>::value; + static const SK_OT_ULONG IBMCyrillic_855Mask = SkOTSetULONGBit<57 - 32>::value; + static const SK_OT_ULONG Latin2_852Mask = SkOTSetULONGBit<58 - 32>::value; + static const SK_OT_ULONG MSDOSBaltic_775Mask = SkOTSetULONGBit<59 - 32>::value; + static const SK_OT_ULONG Greek_737Mask = SkOTSetULONGBit<60 - 32>::value; + static const SK_OT_ULONG Arabic_708Mask = SkOTSetULONGBit<61 - 32>::value; + static const SK_OT_ULONG WELatin1_850Mask = SkOTSetULONGBit<62 - 32>::value; + static const SK_OT_ULONG US_437Mask = SkOTSetULONGBit<63 - 32>::value; }; SK_OT_ULONG value[2]; } raw; diff --git a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V2.h b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V2.h index 4be2e199a6a0..52f946057a85 100644 --- a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V2.h +++ b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V2.h @@ -73,12 +73,12 @@ struct SkOTTableOS2_V2 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT Installable = SkTEndian_SwapBE16(0); - static const SK_OT_USHORT RestrictedMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT PreviewPrintMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT EditableMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT NoSubsettingMask = SkTEndian_SwapBE16(1 << 8); - static const SK_OT_USHORT BitmapMask = SkTEndian_SwapBE16(1 << 9); + static const SK_OT_USHORT Installable = 0; + static const SK_OT_USHORT RestrictedMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT PreviewPrintMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT EditableMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT NoSubsettingMask = SkOTSetUSHORTBit<8>::value; + static const SK_OT_USHORT BitmapMask = SkOTSetUSHORTBit<9>::value; SK_OT_USHORT value; } raw; } fsType; @@ -262,94 +262,94 @@ struct SkOTTableOS2_V2 { } field; struct Raw { struct l0 { - static const SK_OT_ULONG BasicLatinMask = SkTEndian_SwapBE32(1 << 0); - static const SK_OT_ULONG Latin1SupplementMask = SkTEndian_SwapBE32(1 << 1); - static const SK_OT_ULONG LatinExtendedAMask = SkTEndian_SwapBE32(1 << 2); - static const SK_OT_ULONG LatinExtendedBMask = SkTEndian_SwapBE32(1 << 3); - static const SK_OT_ULONG IPAExtensionsMask = SkTEndian_SwapBE32(1 << 4); - static const SK_OT_ULONG SpacingModifierLettersMask = SkTEndian_SwapBE32(1 << 5); - static const SK_OT_ULONG CombiningDiacriticalMarksMask = SkTEndian_SwapBE32(1 << 6); - static const SK_OT_ULONG GreekMask = SkTEndian_SwapBE32(1 << 7); + static const SK_OT_ULONG BasicLatinMask = SkOTSetULONGBit<0>::value; + static const SK_OT_ULONG Latin1SupplementMask = SkOTSetULONGBit<1>::value; + static const SK_OT_ULONG LatinExtendedAMask = SkOTSetULONGBit<2>::value; + static const SK_OT_ULONG LatinExtendedBMask = SkOTSetULONGBit<3>::value; + static const SK_OT_ULONG IPAExtensionsMask = SkOTSetULONGBit<4>::value; + static const SK_OT_ULONG SpacingModifierLettersMask = SkOTSetULONGBit<5>::value; + static const SK_OT_ULONG CombiningDiacriticalMarksMask = SkOTSetULONGBit<6>::value; + static const SK_OT_ULONG GreekMask = SkOTSetULONGBit<7>::value; //Reserved - static const SK_OT_ULONG CyrillicMask = SkTEndian_SwapBE32(1 << 9); - static const SK_OT_ULONG ArmenianMask = SkTEndian_SwapBE32(1 << 10); - static const SK_OT_ULONG HebrewMask = SkTEndian_SwapBE32(1 << 11); + static const SK_OT_ULONG CyrillicMask = SkOTSetULONGBit<9>::value; + static const SK_OT_ULONG ArmenianMask = SkOTSetULONGBit<10>::value; + static const SK_OT_ULONG HebrewMask = SkOTSetULONGBit<11>::value; //Reserved - static const SK_OT_ULONG ArabicMask = SkTEndian_SwapBE32(1 << 13); + static const SK_OT_ULONG ArabicMask = SkOTSetULONGBit<13>::value; //Reserved - static const SK_OT_ULONG DevanagariMask = SkTEndian_SwapBE32(1 << 15); - static const SK_OT_ULONG BengaliMask = SkTEndian_SwapBE32(1 << 16); - static const SK_OT_ULONG GurmukhiMask = SkTEndian_SwapBE32(1 << 17); - static const SK_OT_ULONG GujaratiMask = SkTEndian_SwapBE32(1 << 18); - static const SK_OT_ULONG OriyaMask = SkTEndian_SwapBE32(1 << 19); - static const SK_OT_ULONG TamilMask = SkTEndian_SwapBE32(1 << 20); - static const SK_OT_ULONG TeluguMask = SkTEndian_SwapBE32(1 << 21); - static const SK_OT_ULONG KannadaMask = SkTEndian_SwapBE32(1 << 22); - static const SK_OT_ULONG MalayalamMask = SkTEndian_SwapBE32(1 << 23); - static const SK_OT_ULONG ThaiMask = SkTEndian_SwapBE32(1 << 24); - static const SK_OT_ULONG LaoMask = SkTEndian_SwapBE32(1 << 25); - static const SK_OT_ULONG GeorgianMask = SkTEndian_SwapBE32(1 << 26); + static const SK_OT_ULONG DevanagariMask = SkOTSetULONGBit<15>::value; + static const SK_OT_ULONG BengaliMask = SkOTSetULONGBit<16>::value; + static const SK_OT_ULONG GurmukhiMask = SkOTSetULONGBit<17>::value; + static const SK_OT_ULONG GujaratiMask = SkOTSetULONGBit<18>::value; + static const SK_OT_ULONG OriyaMask = SkOTSetULONGBit<19>::value; + static const SK_OT_ULONG TamilMask = SkOTSetULONGBit<20>::value; + static const SK_OT_ULONG TeluguMask = SkOTSetULONGBit<21>::value; + static const SK_OT_ULONG KannadaMask = SkOTSetULONGBit<22>::value; + static const SK_OT_ULONG MalayalamMask = SkOTSetULONGBit<23>::value; + static const SK_OT_ULONG ThaiMask = SkOTSetULONGBit<24>::value; + static const SK_OT_ULONG LaoMask = SkOTSetULONGBit<25>::value; + static const SK_OT_ULONG GeorgianMask = SkOTSetULONGBit<26>::value; //Reserved - static const SK_OT_ULONG HangulJamoMask = SkTEndian_SwapBE32(1 << 28); - static const SK_OT_ULONG LatinExtendedAdditionalMask = SkTEndian_SwapBE32(1 << 29); - static const SK_OT_ULONG GreekExtendedMask = SkTEndian_SwapBE32(1 << 30); - static const SK_OT_ULONG GeneralPunctuationMask = SkTEndian_SwapBE32(1 << 31); + static const SK_OT_ULONG HangulJamoMask = SkOTSetULONGBit<28>::value; + static const SK_OT_ULONG LatinExtendedAdditionalMask = SkOTSetULONGBit<29>::value; + static const SK_OT_ULONG GreekExtendedMask = SkOTSetULONGBit<30>::value; + static const SK_OT_ULONG GeneralPunctuationMask = SkOTSetULONGBit<31>::value; }; struct l1 { - static const SK_OT_ULONG SuperscriptsAndSubscriptsMask = SkTEndian_SwapBE32(1 << (32 - 32)); - static const SK_OT_ULONG CurrencySymbolsMask = SkTEndian_SwapBE32(1 << (33 - 32)); - static const SK_OT_ULONG CombiningDiacriticalMarksForSymbolsMask = SkTEndian_SwapBE32(1 << (34 - 32)); - static const SK_OT_ULONG LetterlikeSymbolsMask = SkTEndian_SwapBE32(1 << (35 - 32)); - static const SK_OT_ULONG NumberFormsMask = SkTEndian_SwapBE32(1 << (36 - 32)); - static const SK_OT_ULONG ArrowsMask = SkTEndian_SwapBE32(1 << (37 - 32)); - static const SK_OT_ULONG MathematicalOperatorsMask = SkTEndian_SwapBE32(1 << (38 - 32)); - static const SK_OT_ULONG MiscellaneousTechnicalMask = SkTEndian_SwapBE32(1 << (39 - 32)); - static const SK_OT_ULONG ControlPicturesMask = SkTEndian_SwapBE32(1 << (40 - 32)); - static const SK_OT_ULONG OpticalCharacterRecognitionMask = SkTEndian_SwapBE32(1 << (41 - 32)); - static const SK_OT_ULONG EnclosedAlphanumericsMask = SkTEndian_SwapBE32(1 << (42 - 32)); - static const SK_OT_ULONG BoxDrawingMask = SkTEndian_SwapBE32(1 << (43 - 32)); - static const SK_OT_ULONG BlockElementsMask = SkTEndian_SwapBE32(1 << (44 - 32)); - static const SK_OT_ULONG GeometricShapesMask = SkTEndian_SwapBE32(1 << (45 - 32)); - static const SK_OT_ULONG MiscellaneousSymbolsMask = SkTEndian_SwapBE32(1 << (46 - 32)); - static const SK_OT_ULONG DingbatsMask = SkTEndian_SwapBE32(1 << (47 - 32)); - static const SK_OT_ULONG CJKSymbolsAndPunctuationMask = SkTEndian_SwapBE32(1 << (48 - 32)); - static const SK_OT_ULONG HiraganaMask = SkTEndian_SwapBE32(1 << (49 - 32)); - static const SK_OT_ULONG KatakanaMask = SkTEndian_SwapBE32(1 << (50 - 32)); - static const SK_OT_ULONG BopomofoMask = SkTEndian_SwapBE32(1 << (51 - 32)); - static const SK_OT_ULONG HangulCompatibilityJamoMask = SkTEndian_SwapBE32(1 << (52 - 32)); - static const SK_OT_ULONG CJKMiscellaneousMask = SkTEndian_SwapBE32(1 << (53 - 32)); - static const SK_OT_ULONG EnclosedCJKLettersAndMonthsMask = SkTEndian_SwapBE32(1 << (54 - 32)); - static const SK_OT_ULONG CJKCompatibilityMask = SkTEndian_SwapBE32(1 << (55 - 32)); - static const SK_OT_ULONG HangulMask = SkTEndian_SwapBE32(1 << (56 - 32)); - static const SK_OT_ULONG SurrogatesMask = SkTEndian_SwapBE32(1 << (57 - 32)); + static const SK_OT_ULONG SuperscriptsAndSubscriptsMask = SkOTSetULONGBit<32 - 32>::value; + static const SK_OT_ULONG CurrencySymbolsMask = SkOTSetULONGBit<33 - 32>::value; + static const SK_OT_ULONG CombiningDiacriticalMarksForSymbolsMask = SkOTSetULONGBit<34 - 32>::value; + static const SK_OT_ULONG LetterlikeSymbolsMask = SkOTSetULONGBit<35 - 32>::value; + static const SK_OT_ULONG NumberFormsMask = SkOTSetULONGBit<36 - 32>::value; + static const SK_OT_ULONG ArrowsMask = SkOTSetULONGBit<37 - 32>::value; + static const SK_OT_ULONG MathematicalOperatorsMask = SkOTSetULONGBit<38 - 32>::value; + static const SK_OT_ULONG MiscellaneousTechnicalMask = SkOTSetULONGBit<39 - 32>::value; + static const SK_OT_ULONG ControlPicturesMask = SkOTSetULONGBit<40 - 32>::value; + static const SK_OT_ULONG OpticalCharacterRecognitionMask = SkOTSetULONGBit<41 - 32>::value; + static const SK_OT_ULONG EnclosedAlphanumericsMask = SkOTSetULONGBit<42 - 32>::value; + static const SK_OT_ULONG BoxDrawingMask = SkOTSetULONGBit<43 - 32>::value; + static const SK_OT_ULONG BlockElementsMask = SkOTSetULONGBit<44 - 32>::value; + static const SK_OT_ULONG GeometricShapesMask = SkOTSetULONGBit<45 - 32>::value; + static const SK_OT_ULONG MiscellaneousSymbolsMask = SkOTSetULONGBit<46 - 32>::value; + static const SK_OT_ULONG DingbatsMask = SkOTSetULONGBit<47 - 32>::value; + static const SK_OT_ULONG CJKSymbolsAndPunctuationMask = SkOTSetULONGBit<48 - 32>::value; + static const SK_OT_ULONG HiraganaMask = SkOTSetULONGBit<49 - 32>::value; + static const SK_OT_ULONG KatakanaMask = SkOTSetULONGBit<50 - 32>::value; + static const SK_OT_ULONG BopomofoMask = SkOTSetULONGBit<51 - 32>::value; + static const SK_OT_ULONG HangulCompatibilityJamoMask = SkOTSetULONGBit<52 - 32>::value; + static const SK_OT_ULONG CJKMiscellaneousMask = SkOTSetULONGBit<53 - 32>::value; + static const SK_OT_ULONG EnclosedCJKLettersAndMonthsMask = SkOTSetULONGBit<54 - 32>::value; + static const SK_OT_ULONG CJKCompatibilityMask = SkOTSetULONGBit<55 - 32>::value; + static const SK_OT_ULONG HangulMask = SkOTSetULONGBit<56 - 32>::value; + static const SK_OT_ULONG SurrogatesMask = SkOTSetULONGBit<57 - 32>::value; //Reserved - static const SK_OT_ULONG CJKUnifiedIdeographsMask = SkTEndian_SwapBE32(1 << (59 - 32)); - static const SK_OT_ULONG PrivateUseAreaMask = SkTEndian_SwapBE32(1 << (60 - 32)); - static const SK_OT_ULONG CJKCompatibilityIdeographsMask = SkTEndian_SwapBE32(1 << (61 - 32)); - static const SK_OT_ULONG AlphabeticPresentationFormsMask = SkTEndian_SwapBE32(1 << (62 - 32)); - static const SK_OT_ULONG ArabicPresentationFormsAMask = SkTEndian_SwapBE32(1 << (63 - 32)); + static const SK_OT_ULONG CJKUnifiedIdeographsMask = SkOTSetULONGBit<59 - 32>::value; + static const SK_OT_ULONG PrivateUseAreaMask = SkOTSetULONGBit<60 - 32>::value; + static const SK_OT_ULONG CJKCompatibilityIdeographsMask = SkOTSetULONGBit<61 - 32>::value; + static const SK_OT_ULONG AlphabeticPresentationFormsMask = SkOTSetULONGBit<62 - 32>::value; + static const SK_OT_ULONG ArabicPresentationFormsAMask = SkOTSetULONGBit<63 - 32>::value; }; struct l2 { - static const SK_OT_ULONG CombiningHalfMarksMask = SkTEndian_SwapBE32(1 << (64 - 64)); - static const SK_OT_ULONG CJKCompatibilityFormsMask = SkTEndian_SwapBE32(1 << (65 - 64)); - static const SK_OT_ULONG SmallFormVariantsMask = SkTEndian_SwapBE32(1 << (66 - 64)); - static const SK_OT_ULONG ArabicPresentationFormsBMask = SkTEndian_SwapBE32(1 << (67 - 64)); - static const SK_OT_ULONG HalfwidthAndFullwidthFormsMask = SkTEndian_SwapBE32(1 << (68 - 64)); - static const SK_OT_ULONG SpecialsMask = SkTEndian_SwapBE32(1 << (69 - 64)); - static const SK_OT_ULONG TibetanMask = SkTEndian_SwapBE32(1 << (70 - 64)); - static const SK_OT_ULONG SyriacMask = SkTEndian_SwapBE32(1 << (71 - 64)); - static const SK_OT_ULONG ThaanaMask = SkTEndian_SwapBE32(1 << (72 - 64)); - static const SK_OT_ULONG SinhalaMask = SkTEndian_SwapBE32(1 << (73 - 64)); - static const SK_OT_ULONG MyanmarMask = SkTEndian_SwapBE32(1 << (74 - 64)); - static const SK_OT_ULONG EthiopicMask = SkTEndian_SwapBE32(1 << (75 - 64)); - static const SK_OT_ULONG CherokeeMask = SkTEndian_SwapBE32(1 << (76 - 64)); - static const SK_OT_ULONG UnifiedCanadianSyllabicsMask = SkTEndian_SwapBE32(1 << (77 - 64)); - static const SK_OT_ULONG OghamMask = SkTEndian_SwapBE32(1 << (78 - 64)); - static const SK_OT_ULONG RunicMask = SkTEndian_SwapBE32(1 << (79 - 64)); - static const SK_OT_ULONG KhmerMask = SkTEndian_SwapBE32(1 << (80 - 64)); - static const SK_OT_ULONG MongolianMask = SkTEndian_SwapBE32(1 << (81 - 64)); - static const SK_OT_ULONG BrailleMask = SkTEndian_SwapBE32(1 << (82 - 64)); - static const SK_OT_ULONG YiMask = SkTEndian_SwapBE32(1 << (83 - 64)); + static const SK_OT_ULONG CombiningHalfMarksMask = SkOTSetULONGBit<64 - 64>::value; + static const SK_OT_ULONG CJKCompatibilityFormsMask = SkOTSetULONGBit<65 - 64>::value; + static const SK_OT_ULONG SmallFormVariantsMask = SkOTSetULONGBit<66 - 64>::value; + static const SK_OT_ULONG ArabicPresentationFormsBMask = SkOTSetULONGBit<67 - 64>::value; + static const SK_OT_ULONG HalfwidthAndFullwidthFormsMask = SkOTSetULONGBit<68 - 64>::value; + static const SK_OT_ULONG SpecialsMask = SkOTSetULONGBit<69 - 64>::value; + static const SK_OT_ULONG TibetanMask = SkOTSetULONGBit<70 - 64>::value; + static const SK_OT_ULONG SyriacMask = SkOTSetULONGBit<71 - 64>::value; + static const SK_OT_ULONG ThaanaMask = SkOTSetULONGBit<72 - 64>::value; + static const SK_OT_ULONG SinhalaMask = SkOTSetULONGBit<73 - 64>::value; + static const SK_OT_ULONG MyanmarMask = SkOTSetULONGBit<74 - 64>::value; + static const SK_OT_ULONG EthiopicMask = SkOTSetULONGBit<75 - 64>::value; + static const SK_OT_ULONG CherokeeMask = SkOTSetULONGBit<76 - 64>::value; + static const SK_OT_ULONG UnifiedCanadianSyllabicsMask = SkOTSetULONGBit<77 - 64>::value; + static const SK_OT_ULONG OghamMask = SkOTSetULONGBit<78 - 64>::value; + static const SK_OT_ULONG RunicMask = SkOTSetULONGBit<79 - 64>::value; + static const SK_OT_ULONG KhmerMask = SkOTSetULONGBit<80 - 64>::value; + static const SK_OT_ULONG MongolianMask = SkOTSetULONGBit<81 - 64>::value; + static const SK_OT_ULONG BrailleMask = SkOTSetULONGBit<82 - 64>::value; + static const SK_OT_ULONG YiMask = SkOTSetULONGBit<83 - 64>::value; }; SK_OT_ULONG value[4]; } raw; @@ -379,13 +379,13 @@ struct SkOTTableOS2_V2 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT ItalicMask = SkTEndian_SwapBE16(1 << 0); - static const SK_OT_USHORT UnderscoreMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT NegativeMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT OutlinedMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT StrikeoutMask = SkTEndian_SwapBE16(1 << 4); - static const SK_OT_USHORT BoldMask = SkTEndian_SwapBE16(1 << 5); - static const SK_OT_USHORT RegularMask = SkTEndian_SwapBE16(1 << 6); + static const SK_OT_USHORT ItalicMask = SkOTSetUSHORTBit<0>::value; + static const SK_OT_USHORT UnderscoreMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT NegativeMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT OutlinedMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT StrikeoutMask = SkOTSetUSHORTBit<4>::value; + static const SK_OT_USHORT BoldMask = SkOTSetUSHORTBit<5>::value; + static const SK_OT_USHORT RegularMask = SkOTSetUSHORTBit<6>::value; SK_OT_USHORT value; } raw; } fsSelection; @@ -484,42 +484,42 @@ struct SkOTTableOS2_V2 { } field; struct Raw { struct l0 { - static const SK_OT_ULONG Latin1_1252Mask = SkTEndian_SwapBE32(1 << 0); - static const SK_OT_ULONG Latin2EasternEurope_1250Mask = SkTEndian_SwapBE32(1 << 1); - static const SK_OT_ULONG Cyrillic_1251Mask = SkTEndian_SwapBE32(1 << 2); - static const SK_OT_ULONG Greek_1253Mask = SkTEndian_SwapBE32(1 << 3); - static const SK_OT_ULONG Turkish_1254Mask = SkTEndian_SwapBE32(1 << 4); - static const SK_OT_ULONG Hebrew_1255Mask = SkTEndian_SwapBE32(1 << 5); - static const SK_OT_ULONG Arabic_1256Mask = SkTEndian_SwapBE32(1 << 6); - static const SK_OT_ULONG WindowsBaltic_1257Mask = SkTEndian_SwapBE32(1 << 7); - static const SK_OT_ULONG Vietnamese_1258Mask = SkTEndian_SwapBE32(1 << 8); - static const SK_OT_ULONG Thai_874Mask = SkTEndian_SwapBE32(1 << 16); - static const SK_OT_ULONG JISJapan_932Mask = SkTEndian_SwapBE32(1 << 17); - static const SK_OT_ULONG ChineseSimplified_936Mask = SkTEndian_SwapBE32(1 << 18); - static const SK_OT_ULONG KoreanWansung_949Mask = SkTEndian_SwapBE32(1 << 19); - static const SK_OT_ULONG ChineseTraditional_950Mask = SkTEndian_SwapBE32(1 << 20); - static const SK_OT_ULONG KoreanJohab_1361Mask = SkTEndian_SwapBE32(1 << 21); - static const SK_OT_ULONG MacintoshCharacterSetMask = SkTEndian_SwapBE32(1 << 29); - static const SK_OT_ULONG OEMCharacterSetMask = SkTEndian_SwapBE32(1 << 30); - static const SK_OT_ULONG SymbolCharacterSetMask = SkTEndian_SwapBE32(1 << 31); + static const SK_OT_ULONG Latin1_1252Mask = SkOTSetULONGBit<0>::value; + static const SK_OT_ULONG Latin2EasternEurope_1250Mask = SkOTSetULONGBit<1>::value; + static const SK_OT_ULONG Cyrillic_1251Mask = SkOTSetULONGBit<2>::value; + static const SK_OT_ULONG Greek_1253Mask = SkOTSetULONGBit<3>::value; + static const SK_OT_ULONG Turkish_1254Mask = SkOTSetULONGBit<4>::value; + static const SK_OT_ULONG Hebrew_1255Mask = SkOTSetULONGBit<5>::value; + static const SK_OT_ULONG Arabic_1256Mask = SkOTSetULONGBit<6>::value; + static const SK_OT_ULONG WindowsBaltic_1257Mask = SkOTSetULONGBit<7>::value; + static const SK_OT_ULONG Vietnamese_1258Mask = SkOTSetULONGBit<8>::value; + static const SK_OT_ULONG Thai_874Mask = SkOTSetULONGBit<16>::value; + static const SK_OT_ULONG JISJapan_932Mask = SkOTSetULONGBit<17>::value; + static const SK_OT_ULONG ChineseSimplified_936Mask = SkOTSetULONGBit<18>::value; + static const SK_OT_ULONG KoreanWansung_949Mask = SkOTSetULONGBit<19>::value; + static const SK_OT_ULONG ChineseTraditional_950Mask = SkOTSetULONGBit<20>::value; + static const SK_OT_ULONG KoreanJohab_1361Mask = SkOTSetULONGBit<21>::value; + static const SK_OT_ULONG MacintoshCharacterSetMask = SkOTSetULONGBit<29>::value; + static const SK_OT_ULONG OEMCharacterSetMask = SkOTSetULONGBit<30>::value; + static const SK_OT_ULONG SymbolCharacterSetMask = SkOTSetULONGBit<31>::value; }; struct l1 { - static const SK_OT_ULONG IBMGreek_869Mask = SkTEndian_SwapBE32(1 << (48 - 32)); - static const SK_OT_ULONG MSDOSRussian_866Mask = SkTEndian_SwapBE32(1 << (49 - 32)); - static const SK_OT_ULONG MSDOSNordic_865Mask = SkTEndian_SwapBE32(1 << (50 - 32)); - static const SK_OT_ULONG Arabic_864Mask = SkTEndian_SwapBE32(1 << (51 - 32)); - static const SK_OT_ULONG MSDOSCanadianFrench_863Mask = SkTEndian_SwapBE32(1 << (52 - 32)); - static const SK_OT_ULONG Hebrew_862Mask = SkTEndian_SwapBE32(1 << (53 - 32)); - static const SK_OT_ULONG MSDOSIcelandic_861Mask = SkTEndian_SwapBE32(1 << (54 - 32)); - static const SK_OT_ULONG MSDOSPortuguese_860Mask = SkTEndian_SwapBE32(1 << (55 - 32)); - static const SK_OT_ULONG IBMTurkish_857Mask = SkTEndian_SwapBE32(1 << (56 - 32)); - static const SK_OT_ULONG IBMCyrillic_855Mask = SkTEndian_SwapBE32(1 << (57 - 32)); - static const SK_OT_ULONG Latin2_852Mask = SkTEndian_SwapBE32(1 << (58 - 32)); - static const SK_OT_ULONG MSDOSBaltic_775Mask = SkTEndian_SwapBE32(1 << (59 - 32)); - static const SK_OT_ULONG Greek_737Mask = SkTEndian_SwapBE32(1 << (60 - 32)); - static const SK_OT_ULONG Arabic_708Mask = SkTEndian_SwapBE32(1 << (61 - 32)); - static const SK_OT_ULONG WELatin1_850Mask = SkTEndian_SwapBE32(1 << (62 - 32)); - static const SK_OT_ULONG US_437Mask = SkTEndian_SwapBE32(1 << (63 - 32)); + static const SK_OT_ULONG IBMGreek_869Mask = SkOTSetULONGBit<48 - 32>::value; + static const SK_OT_ULONG MSDOSRussian_866Mask = SkOTSetULONGBit<49 - 32>::value; + static const SK_OT_ULONG MSDOSNordic_865Mask = SkOTSetULONGBit<50 - 32>::value; + static const SK_OT_ULONG Arabic_864Mask = SkOTSetULONGBit<51 - 32>::value; + static const SK_OT_ULONG MSDOSCanadianFrench_863Mask = SkOTSetULONGBit<52 - 32>::value; + static const SK_OT_ULONG Hebrew_862Mask = SkOTSetULONGBit<53 - 32>::value; + static const SK_OT_ULONG MSDOSIcelandic_861Mask = SkOTSetULONGBit<54 - 32>::value; + static const SK_OT_ULONG MSDOSPortuguese_860Mask = SkOTSetULONGBit<55 - 32>::value; + static const SK_OT_ULONG IBMTurkish_857Mask = SkOTSetULONGBit<56 - 32>::value; + static const SK_OT_ULONG IBMCyrillic_855Mask = SkOTSetULONGBit<57 - 32>::value; + static const SK_OT_ULONG Latin2_852Mask = SkOTSetULONGBit<58 - 32>::value; + static const SK_OT_ULONG MSDOSBaltic_775Mask = SkOTSetULONGBit<59 - 32>::value; + static const SK_OT_ULONG Greek_737Mask = SkOTSetULONGBit<60 - 32>::value; + static const SK_OT_ULONG Arabic_708Mask = SkOTSetULONGBit<61 - 32>::value; + static const SK_OT_ULONG WELatin1_850Mask = SkOTSetULONGBit<62 - 32>::value; + static const SK_OT_ULONG US_437Mask = SkOTSetULONGBit<63 - 32>::value; }; SK_OT_ULONG value[2]; } raw; diff --git a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V3.h b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V3.h index 637eb378ad65..8d4fa6b574c1 100644 --- a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V3.h +++ b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V3.h @@ -74,12 +74,12 @@ struct SkOTTableOS2_V3 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT Installable = SkTEndian_SwapBE16(0); - static const SK_OT_USHORT RestrictedMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT PreviewPrintMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT EditableMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT NoSubsettingMask = SkTEndian_SwapBE16(1 << 8); - static const SK_OT_USHORT BitmapMask = SkTEndian_SwapBE16(1 << 9); + static const SK_OT_USHORT Installable = 0; + static const SK_OT_USHORT RestrictedMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT PreviewPrintMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT EditableMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT NoSubsettingMask = SkOTSetUSHORTBit<8>::value; + static const SK_OT_USHORT BitmapMask = SkOTSetUSHORTBit<9>::value; SK_OT_USHORT value; } raw; } fsType; @@ -263,103 +263,103 @@ struct SkOTTableOS2_V3 { } field; struct Raw { struct l0 { - static const SK_OT_ULONG BasicLatinMask = SkTEndian_SwapBE32(1 << 0); - static const SK_OT_ULONG Latin1SupplementMask = SkTEndian_SwapBE32(1 << 1); - static const SK_OT_ULONG LatinExtendedAMask = SkTEndian_SwapBE32(1 << 2); - static const SK_OT_ULONG LatinExtendedBMask = SkTEndian_SwapBE32(1 << 3); - static const SK_OT_ULONG IPAExtensionsMask = SkTEndian_SwapBE32(1 << 4); - static const SK_OT_ULONG SpacingModifierLettersMask = SkTEndian_SwapBE32(1 << 5); - static const SK_OT_ULONG CombiningDiacriticalMarksMask = SkTEndian_SwapBE32(1 << 6); - static const SK_OT_ULONG GreekAndCopticMask = SkTEndian_SwapBE32(1 << 7); + static const SK_OT_ULONG BasicLatinMask = SkOTSetULONGBit<0>::value; + static const SK_OT_ULONG Latin1SupplementMask = SkOTSetULONGBit<1>::value; + static const SK_OT_ULONG LatinExtendedAMask = SkOTSetULONGBit<2>::value; + static const SK_OT_ULONG LatinExtendedBMask = SkOTSetULONGBit<3>::value; + static const SK_OT_ULONG IPAExtensionsMask = SkOTSetULONGBit<4>::value; + static const SK_OT_ULONG SpacingModifierLettersMask = SkOTSetULONGBit<5>::value; + static const SK_OT_ULONG CombiningDiacriticalMarksMask = SkOTSetULONGBit<6>::value; + static const SK_OT_ULONG GreekAndCopticMask = SkOTSetULONGBit<7>::value; //Reserved - static const SK_OT_ULONG CyrillicMask = SkTEndian_SwapBE32(1 << 9); - static const SK_OT_ULONG ArmenianMask = SkTEndian_SwapBE32(1 << 10); - static const SK_OT_ULONG HebrewMask = SkTEndian_SwapBE32(1 << 11); + static const SK_OT_ULONG CyrillicMask = SkOTSetULONGBit<9>::value; + static const SK_OT_ULONG ArmenianMask = SkOTSetULONGBit<10>::value; + static const SK_OT_ULONG HebrewMask = SkOTSetULONGBit<11>::value; //Reserved - static const SK_OT_ULONG ArabicMask = SkTEndian_SwapBE32(1 << 13); + static const SK_OT_ULONG ArabicMask = SkOTSetULONGBit<13>::value; //Reserved - static const SK_OT_ULONG DevanagariMask = SkTEndian_SwapBE32(1 << 15); - static const SK_OT_ULONG BengaliMask = SkTEndian_SwapBE32(1 << 16); - static const SK_OT_ULONG GurmukhiMask = SkTEndian_SwapBE32(1 << 17); - static const SK_OT_ULONG GujaratiMask = SkTEndian_SwapBE32(1 << 18); - static const SK_OT_ULONG OriyaMask = SkTEndian_SwapBE32(1 << 19); - static const SK_OT_ULONG TamilMask = SkTEndian_SwapBE32(1 << 20); - static const SK_OT_ULONG TeluguMask = SkTEndian_SwapBE32(1 << 21); - static const SK_OT_ULONG KannadaMask = SkTEndian_SwapBE32(1 << 22); - static const SK_OT_ULONG MalayalamMask = SkTEndian_SwapBE32(1 << 23); - static const SK_OT_ULONG ThaiMask = SkTEndian_SwapBE32(1 << 24); - static const SK_OT_ULONG LaoMask = SkTEndian_SwapBE32(1 << 25); - static const SK_OT_ULONG GeorgianMask = SkTEndian_SwapBE32(1 << 26); + static const SK_OT_ULONG DevanagariMask = SkOTSetULONGBit<15>::value; + static const SK_OT_ULONG BengaliMask = SkOTSetULONGBit<16>::value; + static const SK_OT_ULONG GurmukhiMask = SkOTSetULONGBit<17>::value; + static const SK_OT_ULONG GujaratiMask = SkOTSetULONGBit<18>::value; + static const SK_OT_ULONG OriyaMask = SkOTSetULONGBit<19>::value; + static const SK_OT_ULONG TamilMask = SkOTSetULONGBit<20>::value; + static const SK_OT_ULONG TeluguMask = SkOTSetULONGBit<21>::value; + static const SK_OT_ULONG KannadaMask = SkOTSetULONGBit<22>::value; + static const SK_OT_ULONG MalayalamMask = SkOTSetULONGBit<23>::value; + static const SK_OT_ULONG ThaiMask = SkOTSetULONGBit<24>::value; + static const SK_OT_ULONG LaoMask = SkOTSetULONGBit<25>::value; + static const SK_OT_ULONG GeorgianMask = SkOTSetULONGBit<26>::value; //Reserved - static const SK_OT_ULONG HangulJamoMask = SkTEndian_SwapBE32(1 << 28); - static const SK_OT_ULONG LatinExtendedAdditionalMask = SkTEndian_SwapBE32(1 << 29); - static const SK_OT_ULONG GreekExtendedMask = SkTEndian_SwapBE32(1 << 30); - static const SK_OT_ULONG GeneralPunctuationMask = SkTEndian_SwapBE32(1 << 31); + static const SK_OT_ULONG HangulJamoMask = SkOTSetULONGBit<28>::value; + static const SK_OT_ULONG LatinExtendedAdditionalMask = SkOTSetULONGBit<29>::value; + static const SK_OT_ULONG GreekExtendedMask = SkOTSetULONGBit<30>::value; + static const SK_OT_ULONG GeneralPunctuationMask = SkOTSetULONGBit<31>::value; }; struct l1 { - static const SK_OT_ULONG SuperscriptsAndSubscriptsMask = SkTEndian_SwapBE32(1 << (32 - 32)); - static const SK_OT_ULONG CurrencySymbolsMask = SkTEndian_SwapBE32(1 << (33 - 32)); - static const SK_OT_ULONG CombiningDiacriticalMarksForSymbolsMask = SkTEndian_SwapBE32(1 << (34 - 32)); - static const SK_OT_ULONG LetterlikeSymbolsMask = SkTEndian_SwapBE32(1 << (35 - 32)); - static const SK_OT_ULONG NumberFormsMask = SkTEndian_SwapBE32(1 << (36 - 32)); - static const SK_OT_ULONG ArrowsMask = SkTEndian_SwapBE32(1 << (37 - 32)); - static const SK_OT_ULONG MathematicalOperatorsMask = SkTEndian_SwapBE32(1 << (38 - 32)); - static const SK_OT_ULONG MiscellaneousTechnicalMask = SkTEndian_SwapBE32(1 << (39 - 32)); - static const SK_OT_ULONG ControlPicturesMask = SkTEndian_SwapBE32(1 << (40 - 32)); - static const SK_OT_ULONG OpticalCharacterRecognitionMask = SkTEndian_SwapBE32(1 << (41 - 32)); - static const SK_OT_ULONG EnclosedAlphanumericsMask = SkTEndian_SwapBE32(1 << (42 - 32)); - static const SK_OT_ULONG BoxDrawingMask = SkTEndian_SwapBE32(1 << (43 - 32)); - static const SK_OT_ULONG BlockElementsMask = SkTEndian_SwapBE32(1 << (44 - 32)); - static const SK_OT_ULONG GeometricShapesMask = SkTEndian_SwapBE32(1 << (45 - 32)); - static const SK_OT_ULONG MiscellaneousSymbolsMask = SkTEndian_SwapBE32(1 << (46 - 32)); - static const SK_OT_ULONG DingbatsMask = SkTEndian_SwapBE32(1 << (47 - 32)); - static const SK_OT_ULONG CJKSymbolsAndPunctuationMask = SkTEndian_SwapBE32(1 << (48 - 32)); - static const SK_OT_ULONG HiraganaMask = SkTEndian_SwapBE32(1 << (49 - 32)); - static const SK_OT_ULONG KatakanaMask = SkTEndian_SwapBE32(1 << (50 - 32)); - static const SK_OT_ULONG BopomofoMask = SkTEndian_SwapBE32(1 << (51 - 32)); - static const SK_OT_ULONG HangulCompatibilityJamoMask = SkTEndian_SwapBE32(1 << (52 - 32)); + static const SK_OT_ULONG SuperscriptsAndSubscriptsMask = SkOTSetULONGBit<32 - 32>::value; + static const SK_OT_ULONG CurrencySymbolsMask = SkOTSetULONGBit<33 - 32>::value; + static const SK_OT_ULONG CombiningDiacriticalMarksForSymbolsMask = SkOTSetULONGBit<34 - 32>::value; + static const SK_OT_ULONG LetterlikeSymbolsMask = SkOTSetULONGBit<35 - 32>::value; + static const SK_OT_ULONG NumberFormsMask = SkOTSetULONGBit<36 - 32>::value; + static const SK_OT_ULONG ArrowsMask = SkOTSetULONGBit<37 - 32>::value; + static const SK_OT_ULONG MathematicalOperatorsMask = SkOTSetULONGBit<38 - 32>::value; + static const SK_OT_ULONG MiscellaneousTechnicalMask = SkOTSetULONGBit<39 - 32>::value; + static const SK_OT_ULONG ControlPicturesMask = SkOTSetULONGBit<40 - 32>::value; + static const SK_OT_ULONG OpticalCharacterRecognitionMask = SkOTSetULONGBit<41 - 32>::value; + static const SK_OT_ULONG EnclosedAlphanumericsMask = SkOTSetULONGBit<42 - 32>::value; + static const SK_OT_ULONG BoxDrawingMask = SkOTSetULONGBit<43 - 32>::value; + static const SK_OT_ULONG BlockElementsMask = SkOTSetULONGBit<44 - 32>::value; + static const SK_OT_ULONG GeometricShapesMask = SkOTSetULONGBit<45 - 32>::value; + static const SK_OT_ULONG MiscellaneousSymbolsMask = SkOTSetULONGBit<46 - 32>::value; + static const SK_OT_ULONG DingbatsMask = SkOTSetULONGBit<47 - 32>::value; + static const SK_OT_ULONG CJKSymbolsAndPunctuationMask = SkOTSetULONGBit<48 - 32>::value; + static const SK_OT_ULONG HiraganaMask = SkOTSetULONGBit<49 - 32>::value; + static const SK_OT_ULONG KatakanaMask = SkOTSetULONGBit<50 - 32>::value; + static const SK_OT_ULONG BopomofoMask = SkOTSetULONGBit<51 - 32>::value; + static const SK_OT_ULONG HangulCompatibilityJamoMask = SkOTSetULONGBit<52 - 32>::value; //Reserved - static const SK_OT_ULONG EnclosedCJKLettersAndMonthsMask = SkTEndian_SwapBE32(1 << (54 - 32)); - static const SK_OT_ULONG CJKCompatibilityMask = SkTEndian_SwapBE32(1 << (55 - 32)); - static const SK_OT_ULONG HangulMask = SkTEndian_SwapBE32(1 << (56 - 32)); - static const SK_OT_ULONG NonPlane0Mask = SkTEndian_SwapBE32(1 << (57 - 32)); + static const SK_OT_ULONG EnclosedCJKLettersAndMonthsMask = SkOTSetULONGBit<54 - 32>::value; + static const SK_OT_ULONG CJKCompatibilityMask = SkOTSetULONGBit<55 - 32>::value; + static const SK_OT_ULONG HangulMask = SkOTSetULONGBit<56 - 32>::value; + static const SK_OT_ULONG NonPlane0Mask = SkOTSetULONGBit<57 - 32>::value; //Reserved - static const SK_OT_ULONG CJKUnifiedIdeographsMask = SkTEndian_SwapBE32(1 << (59 - 32)); - static const SK_OT_ULONG PrivateUseAreaMask = SkTEndian_SwapBE32(1 << (60 - 32)); - static const SK_OT_ULONG CJKCompatibilityIdeographsMask = SkTEndian_SwapBE32(1 << (61 - 32)); - static const SK_OT_ULONG AlphabeticPresentationFormsMask = SkTEndian_SwapBE32(1 << (62 - 32)); - static const SK_OT_ULONG ArabicPresentationFormsAMask = SkTEndian_SwapBE32(1 << (63 - 32)); + static const SK_OT_ULONG CJKUnifiedIdeographsMask = SkOTSetULONGBit<59 - 32>::value; + static const SK_OT_ULONG PrivateUseAreaMask = SkOTSetULONGBit<60 - 32>::value; + static const SK_OT_ULONG CJKCompatibilityIdeographsMask = SkOTSetULONGBit<61 - 32>::value; + static const SK_OT_ULONG AlphabeticPresentationFormsMask = SkOTSetULONGBit<62 - 32>::value; + static const SK_OT_ULONG ArabicPresentationFormsAMask = SkOTSetULONGBit<63 - 32>::value; }; struct l2 { - static const SK_OT_ULONG CombiningHalfMarksMask = SkTEndian_SwapBE32(1 << (64 - 64)); - static const SK_OT_ULONG CJKCompatibilityFormsMask = SkTEndian_SwapBE32(1 << (65 - 64)); - static const SK_OT_ULONG SmallFormVariantsMask = SkTEndian_SwapBE32(1 << (66 - 64)); - static const SK_OT_ULONG ArabicPresentationFormsBMask = SkTEndian_SwapBE32(1 << (67 - 64)); - static const SK_OT_ULONG HalfwidthAndFullwidthFormsMask = SkTEndian_SwapBE32(1 << (68 - 64)); - static const SK_OT_ULONG SpecialsMask = SkTEndian_SwapBE32(1 << (69 - 64)); - static const SK_OT_ULONG TibetanMask = SkTEndian_SwapBE32(1 << (70 - 64)); - static const SK_OT_ULONG SyriacMask = SkTEndian_SwapBE32(1 << (71 - 64)); - static const SK_OT_ULONG ThaanaMask = SkTEndian_SwapBE32(1 << (72 - 64)); - static const SK_OT_ULONG SinhalaMask = SkTEndian_SwapBE32(1 << (73 - 64)); - static const SK_OT_ULONG MyanmarMask = SkTEndian_SwapBE32(1 << (74 - 64)); - static const SK_OT_ULONG EthiopicMask = SkTEndian_SwapBE32(1 << (75 - 64)); - static const SK_OT_ULONG CherokeeMask = SkTEndian_SwapBE32(1 << (76 - 64)); - static const SK_OT_ULONG UnifiedCanadianSyllabicsMask = SkTEndian_SwapBE32(1 << (77 - 64)); - static const SK_OT_ULONG OghamMask = SkTEndian_SwapBE32(1 << (78 - 64)); - static const SK_OT_ULONG RunicMask = SkTEndian_SwapBE32(1 << (79 - 64)); - static const SK_OT_ULONG KhmerMask = SkTEndian_SwapBE32(1 << (80 - 64)); - static const SK_OT_ULONG MongolianMask = SkTEndian_SwapBE32(1 << (81 - 64)); - static const SK_OT_ULONG BrailleMask = SkTEndian_SwapBE32(1 << (82 - 64)); - static const SK_OT_ULONG YiMask = SkTEndian_SwapBE32(1 << (83 - 64)); - static const SK_OT_ULONG Tagalog_Hanunoo_Buhid_TagbanwaMask = SkTEndian_SwapBE32(1 << (84 - 64)); - static const SK_OT_ULONG OldItalicMask = SkTEndian_SwapBE32(1 << (85 - 64)); - static const SK_OT_ULONG GothicMask = SkTEndian_SwapBE32(1 << (86 - 64)); - static const SK_OT_ULONG DeseretMask = SkTEndian_SwapBE32(1 << (87 - 64)); - static const SK_OT_ULONG MusicalSymbolsMask = SkTEndian_SwapBE32(1 << (88 - 64)); - static const SK_OT_ULONG MathematicalAlphanumericSymbolsMask = SkTEndian_SwapBE32(1 << (89 - 64)); - static const SK_OT_ULONG PrivateUseMask = SkTEndian_SwapBE32(1 << (90 - 64)); - static const SK_OT_ULONG VariationSelectorsMask = SkTEndian_SwapBE32(1 << (91 - 64)); - static const SK_OT_ULONG TagsMask = SkTEndian_SwapBE32(1 << (92 - 64)); + static const SK_OT_ULONG CombiningHalfMarksMask = SkOTSetULONGBit<64 - 64>::value; + static const SK_OT_ULONG CJKCompatibilityFormsMask = SkOTSetULONGBit<65 - 64>::value; + static const SK_OT_ULONG SmallFormVariantsMask = SkOTSetULONGBit<66 - 64>::value; + static const SK_OT_ULONG ArabicPresentationFormsBMask = SkOTSetULONGBit<67 - 64>::value; + static const SK_OT_ULONG HalfwidthAndFullwidthFormsMask = SkOTSetULONGBit<68 - 64>::value; + static const SK_OT_ULONG SpecialsMask = SkOTSetULONGBit<69 - 64>::value; + static const SK_OT_ULONG TibetanMask = SkOTSetULONGBit<70 - 64>::value; + static const SK_OT_ULONG SyriacMask = SkOTSetULONGBit<71 - 64>::value; + static const SK_OT_ULONG ThaanaMask = SkOTSetULONGBit<72 - 64>::value; + static const SK_OT_ULONG SinhalaMask = SkOTSetULONGBit<73 - 64>::value; + static const SK_OT_ULONG MyanmarMask = SkOTSetULONGBit<74 - 64>::value; + static const SK_OT_ULONG EthiopicMask = SkOTSetULONGBit<75 - 64>::value; + static const SK_OT_ULONG CherokeeMask = SkOTSetULONGBit<76 - 64>::value; + static const SK_OT_ULONG UnifiedCanadianSyllabicsMask = SkOTSetULONGBit<77 - 64>::value; + static const SK_OT_ULONG OghamMask = SkOTSetULONGBit<78 - 64>::value; + static const SK_OT_ULONG RunicMask = SkOTSetULONGBit<79 - 64>::value; + static const SK_OT_ULONG KhmerMask = SkOTSetULONGBit<80 - 64>::value; + static const SK_OT_ULONG MongolianMask = SkOTSetULONGBit<81 - 64>::value; + static const SK_OT_ULONG BrailleMask = SkOTSetULONGBit<82 - 64>::value; + static const SK_OT_ULONG YiMask = SkOTSetULONGBit<83 - 64>::value; + static const SK_OT_ULONG Tagalog_Hanunoo_Buhid_TagbanwaMask = SkOTSetULONGBit<84 - 64>::value; + static const SK_OT_ULONG OldItalicMask = SkOTSetULONGBit<85 - 64>::value; + static const SK_OT_ULONG GothicMask = SkOTSetULONGBit<86 - 64>::value; + static const SK_OT_ULONG DeseretMask = SkOTSetULONGBit<87 - 64>::value; + static const SK_OT_ULONG MusicalSymbolsMask = SkOTSetULONGBit<88 - 64>::value; + static const SK_OT_ULONG MathematicalAlphanumericSymbolsMask = SkOTSetULONGBit<89 - 64>::value; + static const SK_OT_ULONG PrivateUseMask = SkOTSetULONGBit<90 - 64>::value; + static const SK_OT_ULONG VariationSelectorsMask = SkOTSetULONGBit<91 - 64>::value; + static const SK_OT_ULONG TagsMask = SkOTSetULONGBit<92 - 64>::value; }; SK_OT_ULONG value[4]; } raw; @@ -389,13 +389,13 @@ struct SkOTTableOS2_V3 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT ItalicMask = SkTEndian_SwapBE16(1 << 0); - static const SK_OT_USHORT UnderscoreMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT NegativeMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT OutlinedMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT StrikeoutMask = SkTEndian_SwapBE16(1 << 4); - static const SK_OT_USHORT BoldMask = SkTEndian_SwapBE16(1 << 5); - static const SK_OT_USHORT RegularMask = SkTEndian_SwapBE16(1 << 6); + static const SK_OT_USHORT ItalicMask = SkOTSetUSHORTBit<0>::value; + static const SK_OT_USHORT UnderscoreMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT NegativeMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT OutlinedMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT StrikeoutMask = SkOTSetUSHORTBit<4>::value; + static const SK_OT_USHORT BoldMask = SkOTSetUSHORTBit<5>::value; + static const SK_OT_USHORT RegularMask = SkOTSetUSHORTBit<6>::value; SK_OT_USHORT value; } raw; } fsSelection; @@ -494,42 +494,42 @@ struct SkOTTableOS2_V3 { } field; struct Raw { struct l0 { - static const SK_OT_ULONG Latin1_1252Mask = SkTEndian_SwapBE32(1 << 0); - static const SK_OT_ULONG Latin2EasternEurope_1250Mask = SkTEndian_SwapBE32(1 << 1); - static const SK_OT_ULONG Cyrillic_1251Mask = SkTEndian_SwapBE32(1 << 2); - static const SK_OT_ULONG Greek_1253Mask = SkTEndian_SwapBE32(1 << 3); - static const SK_OT_ULONG Turkish_1254Mask = SkTEndian_SwapBE32(1 << 4); - static const SK_OT_ULONG Hebrew_1255Mask = SkTEndian_SwapBE32(1 << 5); - static const SK_OT_ULONG Arabic_1256Mask = SkTEndian_SwapBE32(1 << 6); - static const SK_OT_ULONG WindowsBaltic_1257Mask = SkTEndian_SwapBE32(1 << 7); - static const SK_OT_ULONG Vietnamese_1258Mask = SkTEndian_SwapBE32(1 << 8); - static const SK_OT_ULONG Thai_874Mask = SkTEndian_SwapBE32(1 << 16); - static const SK_OT_ULONG JISJapan_932Mask = SkTEndian_SwapBE32(1 << 17); - static const SK_OT_ULONG ChineseSimplified_936Mask = SkTEndian_SwapBE32(1 << 18); - static const SK_OT_ULONG KoreanWansung_949Mask = SkTEndian_SwapBE32(1 << 19); - static const SK_OT_ULONG ChineseTraditional_950Mask = SkTEndian_SwapBE32(1 << 20); - static const SK_OT_ULONG KoreanJohab_1361Mask = SkTEndian_SwapBE32(1 << 21); - static const SK_OT_ULONG MacintoshCharacterSetMask = SkTEndian_SwapBE32(1 << 29); - static const SK_OT_ULONG OEMCharacterSetMask = SkTEndian_SwapBE32(1 << 30); - static const SK_OT_ULONG SymbolCharacterSetMask = SkTEndian_SwapBE32(1 << 31); + static const SK_OT_ULONG Latin1_1252Mask = SkOTSetULONGBit<0>::value; + static const SK_OT_ULONG Latin2EasternEurope_1250Mask = SkOTSetULONGBit<1>::value; + static const SK_OT_ULONG Cyrillic_1251Mask = SkOTSetULONGBit<2>::value; + static const SK_OT_ULONG Greek_1253Mask = SkOTSetULONGBit<3>::value; + static const SK_OT_ULONG Turkish_1254Mask = SkOTSetULONGBit<4>::value; + static const SK_OT_ULONG Hebrew_1255Mask = SkOTSetULONGBit<5>::value; + static const SK_OT_ULONG Arabic_1256Mask = SkOTSetULONGBit<6>::value; + static const SK_OT_ULONG WindowsBaltic_1257Mask = SkOTSetULONGBit<7>::value; + static const SK_OT_ULONG Vietnamese_1258Mask = SkOTSetULONGBit<8>::value; + static const SK_OT_ULONG Thai_874Mask = SkOTSetULONGBit<16>::value; + static const SK_OT_ULONG JISJapan_932Mask = SkOTSetULONGBit<17>::value; + static const SK_OT_ULONG ChineseSimplified_936Mask = SkOTSetULONGBit<18>::value; + static const SK_OT_ULONG KoreanWansung_949Mask = SkOTSetULONGBit<19>::value; + static const SK_OT_ULONG ChineseTraditional_950Mask = SkOTSetULONGBit<20>::value; + static const SK_OT_ULONG KoreanJohab_1361Mask = SkOTSetULONGBit<21>::value; + static const SK_OT_ULONG MacintoshCharacterSetMask = SkOTSetULONGBit<29>::value; + static const SK_OT_ULONG OEMCharacterSetMask = SkOTSetULONGBit<30>::value; + static const SK_OT_ULONG SymbolCharacterSetMask = SkOTSetULONGBit<31>::value; }; struct l1 { - static const SK_OT_ULONG IBMGreek_869Mask = SkTEndian_SwapBE32(1 << (48 - 32)); - static const SK_OT_ULONG MSDOSRussian_866Mask = SkTEndian_SwapBE32(1 << (49 - 32)); - static const SK_OT_ULONG MSDOSNordic_865Mask = SkTEndian_SwapBE32(1 << (50 - 32)); - static const SK_OT_ULONG Arabic_864Mask = SkTEndian_SwapBE32(1 << (51 - 32)); - static const SK_OT_ULONG MSDOSCanadianFrench_863Mask = SkTEndian_SwapBE32(1 << (52 - 32)); - static const SK_OT_ULONG Hebrew_862Mask = SkTEndian_SwapBE32(1 << (53 - 32)); - static const SK_OT_ULONG MSDOSIcelandic_861Mask = SkTEndian_SwapBE32(1 << (54 - 32)); - static const SK_OT_ULONG MSDOSPortuguese_860Mask = SkTEndian_SwapBE32(1 << (55 - 32)); - static const SK_OT_ULONG IBMTurkish_857Mask = SkTEndian_SwapBE32(1 << (56 - 32)); - static const SK_OT_ULONG IBMCyrillic_855Mask = SkTEndian_SwapBE32(1 << (57 - 32)); - static const SK_OT_ULONG Latin2_852Mask = SkTEndian_SwapBE32(1 << (58 - 32)); - static const SK_OT_ULONG MSDOSBaltic_775Mask = SkTEndian_SwapBE32(1 << (59 - 32)); - static const SK_OT_ULONG Greek_737Mask = SkTEndian_SwapBE32(1 << (60 - 32)); - static const SK_OT_ULONG Arabic_708Mask = SkTEndian_SwapBE32(1 << (61 - 32)); - static const SK_OT_ULONG WELatin1_850Mask = SkTEndian_SwapBE32(1 << (62 - 32)); - static const SK_OT_ULONG US_437Mask = SkTEndian_SwapBE32(1 << (63 - 32)); + static const SK_OT_ULONG IBMGreek_869Mask = SkOTSetULONGBit<48 - 32>::value; + static const SK_OT_ULONG MSDOSRussian_866Mask = SkOTSetULONGBit<49 - 32>::value; + static const SK_OT_ULONG MSDOSNordic_865Mask = SkOTSetULONGBit<50 - 32>::value; + static const SK_OT_ULONG Arabic_864Mask = SkOTSetULONGBit<51 - 32>::value; + static const SK_OT_ULONG MSDOSCanadianFrench_863Mask = SkOTSetULONGBit<52 - 32>::value; + static const SK_OT_ULONG Hebrew_862Mask = SkOTSetULONGBit<53 - 32>::value; + static const SK_OT_ULONG MSDOSIcelandic_861Mask = SkOTSetULONGBit<54 - 32>::value; + static const SK_OT_ULONG MSDOSPortuguese_860Mask = SkOTSetULONGBit<55 - 32>::value; + static const SK_OT_ULONG IBMTurkish_857Mask = SkOTSetULONGBit<56 - 32>::value; + static const SK_OT_ULONG IBMCyrillic_855Mask = SkOTSetULONGBit<57 - 32>::value; + static const SK_OT_ULONG Latin2_852Mask = SkOTSetULONGBit<58 - 32>::value; + static const SK_OT_ULONG MSDOSBaltic_775Mask = SkOTSetULONGBit<59 - 32>::value; + static const SK_OT_ULONG Greek_737Mask = SkOTSetULONGBit<60 - 32>::value; + static const SK_OT_ULONG Arabic_708Mask = SkOTSetULONGBit<61 - 32>::value; + static const SK_OT_ULONG WELatin1_850Mask = SkOTSetULONGBit<62 - 32>::value; + static const SK_OT_ULONG US_437Mask = SkOTSetULONGBit<63 - 32>::value; }; SK_OT_ULONG value[2]; } raw; diff --git a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V4.h b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V4.h index fc6ed5daadaa..fc64b2257bbf 100644 --- a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V4.h +++ b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_V4.h @@ -74,12 +74,12 @@ struct SkOTTableOS2_V4 { Reserved07) } field; struct Raw { - static const SK_OT_USHORT Installable = SkTEndian_SwapBE16(0); - static const SK_OT_USHORT RestrictedMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT PreviewPrintMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT EditableMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT NoSubsettingMask = SkTEndian_SwapBE16(1 << 8); - static const SK_OT_USHORT BitmapMask = SkTEndian_SwapBE16(1 << 9); + static const SK_OT_USHORT Installable = 0; + static const SK_OT_USHORT RestrictedMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT PreviewPrintMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT EditableMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT NoSubsettingMask = SkOTSetUSHORTBit<8>::value; + static const SK_OT_USHORT BitmapMask = SkOTSetUSHORTBit<9>::value; SK_OT_USHORT value; } raw; } fsType; @@ -263,135 +263,135 @@ struct SkOTTableOS2_V4 { } field; struct Raw { struct l0 { - static const SK_OT_ULONG BasicLatinMask = SkTEndian_SwapBE32(1 << 0); - static const SK_OT_ULONG Latin1SupplementMask = SkTEndian_SwapBE32(1 << 1); - static const SK_OT_ULONG LatinExtendedAMask = SkTEndian_SwapBE32(1 << 2); - static const SK_OT_ULONG LatinExtendedBMask = SkTEndian_SwapBE32(1 << 3); - static const SK_OT_ULONG IPAExtensionsMask = SkTEndian_SwapBE32(1 << 4); - static const SK_OT_ULONG SpacingModifierLettersMask = SkTEndian_SwapBE32(1 << 5); - static const SK_OT_ULONG CombiningDiacriticalMarksMask = SkTEndian_SwapBE32(1 << 6); - static const SK_OT_ULONG GreekAndCopticMask = SkTEndian_SwapBE32(1 << 7); - static const SK_OT_ULONG CopticMask = SkTEndian_SwapBE32(1 << 8); - static const SK_OT_ULONG CyrillicMask = SkTEndian_SwapBE32(1 << 9); - static const SK_OT_ULONG ArmenianMask = SkTEndian_SwapBE32(1 << 10); - static const SK_OT_ULONG HebrewMask = SkTEndian_SwapBE32(1 << 11); - static const SK_OT_ULONG VaiMask = SkTEndian_SwapBE32(1 << 12); - static const SK_OT_ULONG ArabicMask = SkTEndian_SwapBE32(1 << 13); - static const SK_OT_ULONG NKoMask = SkTEndian_SwapBE32(1 << 14); - static const SK_OT_ULONG DevanagariMask = SkTEndian_SwapBE32(1 << 15); - static const SK_OT_ULONG BengaliMask = SkTEndian_SwapBE32(1 << 16); - static const SK_OT_ULONG GurmukhiMask = SkTEndian_SwapBE32(1 << 17); - static const SK_OT_ULONG GujaratiMask = SkTEndian_SwapBE32(1 << 18); - static const SK_OT_ULONG OriyaMask = SkTEndian_SwapBE32(1 << 19); - static const SK_OT_ULONG TamilMask = SkTEndian_SwapBE32(1 << 20); - static const SK_OT_ULONG TeluguMask = SkTEndian_SwapBE32(1 << 21); - static const SK_OT_ULONG KannadaMask = SkTEndian_SwapBE32(1 << 22); - static const SK_OT_ULONG MalayalamMask = SkTEndian_SwapBE32(1 << 23); - static const SK_OT_ULONG ThaiMask = SkTEndian_SwapBE32(1 << 24); - static const SK_OT_ULONG LaoMask = SkTEndian_SwapBE32(1 << 25); - static const SK_OT_ULONG GeorgianMask = SkTEndian_SwapBE32(1 << 26); - static const SK_OT_ULONG BalineseMask = SkTEndian_SwapBE32(1 << 27); - static const SK_OT_ULONG HangulJamoMask = SkTEndian_SwapBE32(1 << 28); - static const SK_OT_ULONG LatinExtendedAdditionalMask = SkTEndian_SwapBE32(1 << 29); - static const SK_OT_ULONG GreekExtendedMask = SkTEndian_SwapBE32(1 << 30); - static const SK_OT_ULONG GeneralPunctuationMask = SkTEndian_SwapBE32(1 << 31); + static const SK_OT_ULONG BasicLatinMask = SkOTSetULONGBit<0>::value; + static const SK_OT_ULONG Latin1SupplementMask = SkOTSetULONGBit<1>::value; + static const SK_OT_ULONG LatinExtendedAMask = SkOTSetULONGBit<2>::value; + static const SK_OT_ULONG LatinExtendedBMask = SkOTSetULONGBit<3>::value; + static const SK_OT_ULONG IPAExtensionsMask = SkOTSetULONGBit<4>::value; + static const SK_OT_ULONG SpacingModifierLettersMask = SkOTSetULONGBit<5>::value; + static const SK_OT_ULONG CombiningDiacriticalMarksMask = SkOTSetULONGBit<6>::value; + static const SK_OT_ULONG GreekAndCopticMask = SkOTSetULONGBit<7>::value; + static const SK_OT_ULONG CopticMask = SkOTSetULONGBit<8>::value; + static const SK_OT_ULONG CyrillicMask = SkOTSetULONGBit<9>::value; + static const SK_OT_ULONG ArmenianMask = SkOTSetULONGBit<10>::value; + static const SK_OT_ULONG HebrewMask = SkOTSetULONGBit<11>::value; + static const SK_OT_ULONG VaiMask = SkOTSetULONGBit<12>::value; + static const SK_OT_ULONG ArabicMask = SkOTSetULONGBit<13>::value; + static const SK_OT_ULONG NKoMask = SkOTSetULONGBit<14>::value; + static const SK_OT_ULONG DevanagariMask = SkOTSetULONGBit<15>::value; + static const SK_OT_ULONG BengaliMask = SkOTSetULONGBit<16>::value; + static const SK_OT_ULONG GurmukhiMask = SkOTSetULONGBit<17>::value; + static const SK_OT_ULONG GujaratiMask = SkOTSetULONGBit<18>::value; + static const SK_OT_ULONG OriyaMask = SkOTSetULONGBit<19>::value; + static const SK_OT_ULONG TamilMask = SkOTSetULONGBit<20>::value; + static const SK_OT_ULONG TeluguMask = SkOTSetULONGBit<21>::value; + static const SK_OT_ULONG KannadaMask = SkOTSetULONGBit<22>::value; + static const SK_OT_ULONG MalayalamMask = SkOTSetULONGBit<23>::value; + static const SK_OT_ULONG ThaiMask = SkOTSetULONGBit<24>::value; + static const SK_OT_ULONG LaoMask = SkOTSetULONGBit<25>::value; + static const SK_OT_ULONG GeorgianMask = SkOTSetULONGBit<26>::value; + static const SK_OT_ULONG BalineseMask = SkOTSetULONGBit<27>::value; + static const SK_OT_ULONG HangulJamoMask = SkOTSetULONGBit<28>::value; + static const SK_OT_ULONG LatinExtendedAdditionalMask = SkOTSetULONGBit<29>::value; + static const SK_OT_ULONG GreekExtendedMask = SkOTSetULONGBit<30>::value; + static const SK_OT_ULONG GeneralPunctuationMask = SkOTSetULONGBit<31>::value; }; struct l1 { - static const SK_OT_ULONG SuperscriptsAndSubscriptsMask = SkTEndian_SwapBE32(1 << (32 - 32)); - static const SK_OT_ULONG CurrencySymbolsMask = SkTEndian_SwapBE32(1 << (33 - 32)); - static const SK_OT_ULONG CombiningDiacriticalMarksForSymbolsMask = SkTEndian_SwapBE32(1 << (34 - 32)); - static const SK_OT_ULONG LetterlikeSymbolsMask = SkTEndian_SwapBE32(1 << (35 - 32)); - static const SK_OT_ULONG NumberFormsMask = SkTEndian_SwapBE32(1 << (36 - 32)); - static const SK_OT_ULONG ArrowsMask = SkTEndian_SwapBE32(1 << (37 - 32)); - static const SK_OT_ULONG MathematicalOperatorsMask = SkTEndian_SwapBE32(1 << (38 - 32)); - static const SK_OT_ULONG MiscellaneousTechnicalMask = SkTEndian_SwapBE32(1 << (39 - 32)); - static const SK_OT_ULONG ControlPicturesMask = SkTEndian_SwapBE32(1 << (40 - 32)); - static const SK_OT_ULONG OpticalCharacterRecognitionMask = SkTEndian_SwapBE32(1 << (41 - 32)); - static const SK_OT_ULONG EnclosedAlphanumericsMask = SkTEndian_SwapBE32(1 << (42 - 32)); - static const SK_OT_ULONG BoxDrawingMask = SkTEndian_SwapBE32(1 << (43 - 32)); - static const SK_OT_ULONG BlockElementsMask = SkTEndian_SwapBE32(1 << (44 - 32)); - static const SK_OT_ULONG GeometricShapesMask = SkTEndian_SwapBE32(1 << (45 - 32)); - static const SK_OT_ULONG MiscellaneousSymbolsMask = SkTEndian_SwapBE32(1 << (46 - 32)); - static const SK_OT_ULONG DingbatsMask = SkTEndian_SwapBE32(1 << (47 - 32)); - static const SK_OT_ULONG CJKSymbolsAndPunctuationMask = SkTEndian_SwapBE32(1 << (48 - 32)); - static const SK_OT_ULONG HiraganaMask = SkTEndian_SwapBE32(1 << (49 - 32)); - static const SK_OT_ULONG KatakanaMask = SkTEndian_SwapBE32(1 << (50 - 32)); - static const SK_OT_ULONG BopomofoMask = SkTEndian_SwapBE32(1 << (51 - 32)); - static const SK_OT_ULONG HangulCompatibilityJamoMask = SkTEndian_SwapBE32(1 << (52 - 32)); - static const SK_OT_ULONG PhagsPaMask = SkTEndian_SwapBE32(1 << (53 - 32)); - static const SK_OT_ULONG EnclosedCJKLettersAndMonthsMask = SkTEndian_SwapBE32(1 << (54 - 32)); - static const SK_OT_ULONG CJKCompatibilityMask = SkTEndian_SwapBE32(1 << (55 - 32)); - static const SK_OT_ULONG HangulMask = SkTEndian_SwapBE32(1 << (56 - 32)); - static const SK_OT_ULONG NonPlane0Mask = SkTEndian_SwapBE32(1 << (57 - 32)); - static const SK_OT_ULONG PhoenicianMask = SkTEndian_SwapBE32(1 << (58 - 32)); - static const SK_OT_ULONG CJKUnifiedIdeographsMask = SkTEndian_SwapBE32(1 << (59 - 32)); - static const SK_OT_ULONG PrivateUseAreaMask = SkTEndian_SwapBE32(1 << (60 - 32)); - static const SK_OT_ULONG CJKCompatibilityIdeographsMask = SkTEndian_SwapBE32(1 << (61 - 32)); - static const SK_OT_ULONG AlphabeticPresentationFormsMask = SkTEndian_SwapBE32(1 << (62 - 32)); - static const SK_OT_ULONG ArabicPresentationFormsAMask = SkTEndian_SwapBE32(1 << (63 - 32)); + static const SK_OT_ULONG SuperscriptsAndSubscriptsMask = SkOTSetULONGBit<32 - 32>::value; + static const SK_OT_ULONG CurrencySymbolsMask = SkOTSetULONGBit<33 - 32>::value; + static const SK_OT_ULONG CombiningDiacriticalMarksForSymbolsMask = SkOTSetULONGBit<34 - 32>::value; + static const SK_OT_ULONG LetterlikeSymbolsMask = SkOTSetULONGBit<35 - 32>::value; + static const SK_OT_ULONG NumberFormsMask = SkOTSetULONGBit<36 - 32>::value; + static const SK_OT_ULONG ArrowsMask = SkOTSetULONGBit<37 - 32>::value; + static const SK_OT_ULONG MathematicalOperatorsMask = SkOTSetULONGBit<38 - 32>::value; + static const SK_OT_ULONG MiscellaneousTechnicalMask = SkOTSetULONGBit<39 - 32>::value; + static const SK_OT_ULONG ControlPicturesMask = SkOTSetULONGBit<40 - 32>::value; + static const SK_OT_ULONG OpticalCharacterRecognitionMask = SkOTSetULONGBit<41 - 32>::value; + static const SK_OT_ULONG EnclosedAlphanumericsMask = SkOTSetULONGBit<42 - 32>::value; + static const SK_OT_ULONG BoxDrawingMask = SkOTSetULONGBit<43 - 32>::value; + static const SK_OT_ULONG BlockElementsMask = SkOTSetULONGBit<44 - 32>::value; + static const SK_OT_ULONG GeometricShapesMask = SkOTSetULONGBit<45 - 32>::value; + static const SK_OT_ULONG MiscellaneousSymbolsMask = SkOTSetULONGBit<46 - 32>::value; + static const SK_OT_ULONG DingbatsMask = SkOTSetULONGBit<47 - 32>::value; + static const SK_OT_ULONG CJKSymbolsAndPunctuationMask = SkOTSetULONGBit<48 - 32>::value; + static const SK_OT_ULONG HiraganaMask = SkOTSetULONGBit<49 - 32>::value; + static const SK_OT_ULONG KatakanaMask = SkOTSetULONGBit<50 - 32>::value; + static const SK_OT_ULONG BopomofoMask = SkOTSetULONGBit<51 - 32>::value; + static const SK_OT_ULONG HangulCompatibilityJamoMask = SkOTSetULONGBit<52 - 32>::value; + static const SK_OT_ULONG PhagsPaMask = SkOTSetULONGBit<53 - 32>::value; + static const SK_OT_ULONG EnclosedCJKLettersAndMonthsMask = SkOTSetULONGBit<54 - 32>::value; + static const SK_OT_ULONG CJKCompatibilityMask = SkOTSetULONGBit<55 - 32>::value; + static const SK_OT_ULONG HangulMask = SkOTSetULONGBit<56 - 32>::value; + static const SK_OT_ULONG NonPlane0Mask = SkOTSetULONGBit<57 - 32>::value; + static const SK_OT_ULONG PhoenicianMask = SkOTSetULONGBit<58 - 32>::value; + static const SK_OT_ULONG CJKUnifiedIdeographsMask = SkOTSetULONGBit<59 - 32>::value; + static const SK_OT_ULONG PrivateUseAreaMask = SkOTSetULONGBit<60 - 32>::value; + static const SK_OT_ULONG CJKCompatibilityIdeographsMask = SkOTSetULONGBit<61 - 32>::value; + static const SK_OT_ULONG AlphabeticPresentationFormsMask = SkOTSetULONGBit<62 - 32>::value; + static const SK_OT_ULONG ArabicPresentationFormsAMask = SkOTSetULONGBit<63 - 32>::value; }; struct l2 { - static const SK_OT_ULONG CombiningHalfMarksMask = SkTEndian_SwapBE32(1 << (64 - 64)); - static const SK_OT_ULONG CJKCompatibilityFormsMask = SkTEndian_SwapBE32(1 << (65 - 64)); - static const SK_OT_ULONG SmallFormVariantsMask = SkTEndian_SwapBE32(1 << (66 - 64)); - static const SK_OT_ULONG ArabicPresentationFormsBMask = SkTEndian_SwapBE32(1 << (67 - 64)); - static const SK_OT_ULONG HalfwidthAndFullwidthFormsMask = SkTEndian_SwapBE32(1 << (68 - 64)); - static const SK_OT_ULONG SpecialsMask = SkTEndian_SwapBE32(1 << (69 - 64)); - static const SK_OT_ULONG TibetanMask = SkTEndian_SwapBE32(1 << (70 - 64)); - static const SK_OT_ULONG SyriacMask = SkTEndian_SwapBE32(1 << (71 - 64)); - static const SK_OT_ULONG ThaanaMask = SkTEndian_SwapBE32(1 << (72 - 64)); - static const SK_OT_ULONG SinhalaMask = SkTEndian_SwapBE32(1 << (73 - 64)); - static const SK_OT_ULONG MyanmarMask = SkTEndian_SwapBE32(1 << (74 - 64)); - static const SK_OT_ULONG EthiopicMask = SkTEndian_SwapBE32(1 << (75 - 64)); - static const SK_OT_ULONG CherokeeMask = SkTEndian_SwapBE32(1 << (76 - 64)); - static const SK_OT_ULONG UnifiedCanadianSyllabicsMask = SkTEndian_SwapBE32(1 << (77 - 64)); - static const SK_OT_ULONG OghamMask = SkTEndian_SwapBE32(1 << (78 - 64)); - static const SK_OT_ULONG RunicMask = SkTEndian_SwapBE32(1 << (79 - 64)); - static const SK_OT_ULONG KhmerMask = SkTEndian_SwapBE32(1 << (80 - 64)); - static const SK_OT_ULONG MongolianMask = SkTEndian_SwapBE32(1 << (81 - 64)); - static const SK_OT_ULONG BrailleMask = SkTEndian_SwapBE32(1 << (82 - 64)); - static const SK_OT_ULONG YiMask = SkTEndian_SwapBE32(1 << (83 - 64)); - static const SK_OT_ULONG Tagalog_Hanunoo_Buhid_TagbanwaMask = SkTEndian_SwapBE32(1 << (84 - 64)); - static const SK_OT_ULONG OldItalicMask = SkTEndian_SwapBE32(1 << (85 - 64)); - static const SK_OT_ULONG GothicMask = SkTEndian_SwapBE32(1 << (86 - 64)); - static const SK_OT_ULONG DeseretMask = SkTEndian_SwapBE32(1 << (87 - 64)); - static const SK_OT_ULONG MusicalSymbolsMask = SkTEndian_SwapBE32(1 << (88 - 64)); - static const SK_OT_ULONG MathematicalAlphanumericSymbolsMask = SkTEndian_SwapBE32(1 << (89 - 64)); - static const SK_OT_ULONG PrivateUseMask = SkTEndian_SwapBE32(1 << (90 - 64)); - static const SK_OT_ULONG VariationSelectorsMask = SkTEndian_SwapBE32(1 << (91 - 64)); - static const SK_OT_ULONG TagsMask = SkTEndian_SwapBE32(1 << (92 - 64)); - static const SK_OT_ULONG LimbuMask = SkTEndian_SwapBE32(1 << (93 - 64)); - static const SK_OT_ULONG TaiLeMask = SkTEndian_SwapBE32(1 << (94 - 64)); - static const SK_OT_ULONG NewTaiLueMask = SkTEndian_SwapBE32(1 << (95 - 64)); + static const SK_OT_ULONG CombiningHalfMarksMask = SkOTSetULONGBit<64 - 64>::value; + static const SK_OT_ULONG CJKCompatibilityFormsMask = SkOTSetULONGBit<65 - 64>::value; + static const SK_OT_ULONG SmallFormVariantsMask = SkOTSetULONGBit<66 - 64>::value; + static const SK_OT_ULONG ArabicPresentationFormsBMask = SkOTSetULONGBit<67 - 64>::value; + static const SK_OT_ULONG HalfwidthAndFullwidthFormsMask = SkOTSetULONGBit<68 - 64>::value; + static const SK_OT_ULONG SpecialsMask = SkOTSetULONGBit<69 - 64>::value; + static const SK_OT_ULONG TibetanMask = SkOTSetULONGBit<70 - 64>::value; + static const SK_OT_ULONG SyriacMask = SkOTSetULONGBit<71 - 64>::value; + static const SK_OT_ULONG ThaanaMask = SkOTSetULONGBit<72 - 64>::value; + static const SK_OT_ULONG SinhalaMask = SkOTSetULONGBit<73 - 64>::value; + static const SK_OT_ULONG MyanmarMask = SkOTSetULONGBit<74 - 64>::value; + static const SK_OT_ULONG EthiopicMask = SkOTSetULONGBit<75 - 64>::value; + static const SK_OT_ULONG CherokeeMask = SkOTSetULONGBit<76 - 64>::value; + static const SK_OT_ULONG UnifiedCanadianSyllabicsMask = SkOTSetULONGBit<77 - 64>::value; + static const SK_OT_ULONG OghamMask = SkOTSetULONGBit<78 - 64>::value; + static const SK_OT_ULONG RunicMask = SkOTSetULONGBit<79 - 64>::value; + static const SK_OT_ULONG KhmerMask = SkOTSetULONGBit<80 - 64>::value; + static const SK_OT_ULONG MongolianMask = SkOTSetULONGBit<81 - 64>::value; + static const SK_OT_ULONG BrailleMask = SkOTSetULONGBit<82 - 64>::value; + static const SK_OT_ULONG YiMask = SkOTSetULONGBit<83 - 64>::value; + static const SK_OT_ULONG Tagalog_Hanunoo_Buhid_TagbanwaMask = SkOTSetULONGBit<84 - 64>::value; + static const SK_OT_ULONG OldItalicMask = SkOTSetULONGBit<85 - 64>::value; + static const SK_OT_ULONG GothicMask = SkOTSetULONGBit<86 - 64>::value; + static const SK_OT_ULONG DeseretMask = SkOTSetULONGBit<87 - 64>::value; + static const SK_OT_ULONG MusicalSymbolsMask = SkOTSetULONGBit<88 - 64>::value; + static const SK_OT_ULONG MathematicalAlphanumericSymbolsMask = SkOTSetULONGBit<89 - 64>::value; + static const SK_OT_ULONG PrivateUseMask = SkOTSetULONGBit<90 - 64>::value; + static const SK_OT_ULONG VariationSelectorsMask = SkOTSetULONGBit<91 - 64>::value; + static const SK_OT_ULONG TagsMask = SkOTSetULONGBit<92 - 64>::value; + static const SK_OT_ULONG LimbuMask = SkOTSetULONGBit<93 - 64>::value; + static const SK_OT_ULONG TaiLeMask = SkOTSetULONGBit<94 - 64>::value; + static const SK_OT_ULONG NewTaiLueMask = SkOTSetULONGBit<95 - 64>::value; }; struct l3 { - static const SK_OT_ULONG BugineseMask = SkTEndian_SwapBE32(1 << (96 - 96)); - static const SK_OT_ULONG GlagoliticMask = SkTEndian_SwapBE32(1 << (97 - 96)); - static const SK_OT_ULONG TifinaghMask = SkTEndian_SwapBE32(1 << (98 - 96)); - static const SK_OT_ULONG YijingHexagramSymbolsMask = SkTEndian_SwapBE32(1 << (99 - 96)); - static const SK_OT_ULONG SylotiNagriMask = SkTEndian_SwapBE32(1 << (100 - 96)); - static const SK_OT_ULONG LinearB_AegeanNumbersMask = SkTEndian_SwapBE32(1 << (101 - 96)); - static const SK_OT_ULONG AncientGreekNumbersMask = SkTEndian_SwapBE32(1 << (102 - 96)); - static const SK_OT_ULONG UgariticMask = SkTEndian_SwapBE32(1 << (103 - 96)); - static const SK_OT_ULONG OldPersianMask = SkTEndian_SwapBE32(1 << (104 - 96)); - static const SK_OT_ULONG ShavianMask = SkTEndian_SwapBE32(1 << (105 - 96)); - static const SK_OT_ULONG OsmanyaMask = SkTEndian_SwapBE32(1 << (106 - 96)); - static const SK_OT_ULONG CypriotSyllabaryMask = SkTEndian_SwapBE32(1 << (107 - 96)); - static const SK_OT_ULONG KharoshthiMask = SkTEndian_SwapBE32(1 << (108 - 96)); - static const SK_OT_ULONG TaiXuanJingSymbolsMask = SkTEndian_SwapBE32(1 << (109 - 96)); - static const SK_OT_ULONG CuneiformMask = SkTEndian_SwapBE32(1 << (110 - 96)); - static const SK_OT_ULONG CountingRodNumeralsMask = SkTEndian_SwapBE32(1 << (111 - 96)); - static const SK_OT_ULONG SundaneseMask = SkTEndian_SwapBE32(1 << (112 - 96)); - static const SK_OT_ULONG LepchaMask = SkTEndian_SwapBE32(1 << (113 - 96)); - static const SK_OT_ULONG OlChikiMask = SkTEndian_SwapBE32(1 << (114 - 96)); - static const SK_OT_ULONG SaurashtraMask = SkTEndian_SwapBE32(1 << (115 - 96)); - static const SK_OT_ULONG KayahLiMask = SkTEndian_SwapBE32(1 << (116 - 96)); - static const SK_OT_ULONG RejangMask = SkTEndian_SwapBE32(1 << (117 - 96)); - static const SK_OT_ULONG ChamMask = SkTEndian_SwapBE32(1 << (118 - 96)); - static const SK_OT_ULONG AncientSymbolsMask = SkTEndian_SwapBE32(1 << (119 - 96)); - static const SK_OT_ULONG PhaistosDiscMask = SkTEndian_SwapBE32(1 << (120 - 96)); - static const SK_OT_ULONG Carian_Lycian_LydianMask = SkTEndian_SwapBE32(1 << (121 - 96)); - static const SK_OT_ULONG DominoTiles_MahjongTilesMask = SkTEndian_SwapBE32(1 << (122 - 96)); + static const SK_OT_ULONG BugineseMask = SkOTSetULONGBit<96 - 96>::value; + static const SK_OT_ULONG GlagoliticMask = SkOTSetULONGBit<97 - 96>::value; + static const SK_OT_ULONG TifinaghMask = SkOTSetULONGBit<98 - 96>::value; + static const SK_OT_ULONG YijingHexagramSymbolsMask = SkOTSetULONGBit<99 - 96>::value; + static const SK_OT_ULONG SylotiNagriMask = SkOTSetULONGBit<100 - 96>::value; + static const SK_OT_ULONG LinearB_AegeanNumbersMask = SkOTSetULONGBit<101 - 96>::value; + static const SK_OT_ULONG AncientGreekNumbersMask = SkOTSetULONGBit<102 - 96>::value; + static const SK_OT_ULONG UgariticMask = SkOTSetULONGBit<103 - 96>::value; + static const SK_OT_ULONG OldPersianMask = SkOTSetULONGBit<104 - 96>::value; + static const SK_OT_ULONG ShavianMask = SkOTSetULONGBit<105 - 96>::value; + static const SK_OT_ULONG OsmanyaMask = SkOTSetULONGBit<106 - 96>::value; + static const SK_OT_ULONG CypriotSyllabaryMask = SkOTSetULONGBit<107 - 96>::value; + static const SK_OT_ULONG KharoshthiMask = SkOTSetULONGBit<108 - 96>::value; + static const SK_OT_ULONG TaiXuanJingSymbolsMask = SkOTSetULONGBit<109 - 96>::value; + static const SK_OT_ULONG CuneiformMask = SkOTSetULONGBit<110 - 96>::value; + static const SK_OT_ULONG CountingRodNumeralsMask = SkOTSetULONGBit<111 - 96>::value; + static const SK_OT_ULONG SundaneseMask = SkOTSetULONGBit<112 - 96>::value; + static const SK_OT_ULONG LepchaMask = SkOTSetULONGBit<113 - 96>::value; + static const SK_OT_ULONG OlChikiMask = SkOTSetULONGBit<114 - 96>::value; + static const SK_OT_ULONG SaurashtraMask = SkOTSetULONGBit<115 - 96>::value; + static const SK_OT_ULONG KayahLiMask = SkOTSetULONGBit<116 - 96>::value; + static const SK_OT_ULONG RejangMask = SkOTSetULONGBit<117 - 96>::value; + static const SK_OT_ULONG ChamMask = SkOTSetULONGBit<118 - 96>::value; + static const SK_OT_ULONG AncientSymbolsMask = SkOTSetULONGBit<119 - 96>::value; + static const SK_OT_ULONG PhaistosDiscMask = SkOTSetULONGBit<120 - 96>::value; + static const SK_OT_ULONG Carian_Lycian_LydianMask = SkOTSetULONGBit<121 - 96>::value; + static const SK_OT_ULONG DominoTiles_MahjongTilesMask = SkOTSetULONGBit<122 - 96>::value; }; SK_OT_ULONG value[4]; } raw; @@ -421,16 +421,16 @@ struct SkOTTableOS2_V4 { UseTypoMetrics) } field; struct Raw { - static const SK_OT_USHORT ItalicMask = SkTEndian_SwapBE16(1 << 0); - static const SK_OT_USHORT UnderscoreMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT NegativeMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT OutlinedMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT StrikeoutMask = SkTEndian_SwapBE16(1 << 4); - static const SK_OT_USHORT BoldMask = SkTEndian_SwapBE16(1 << 5); - static const SK_OT_USHORT RegularMask = SkTEndian_SwapBE16(1 << 6); - static const SK_OT_USHORT UseTypoMetricsMask = SkTEndian_SwapBE16(1 << 7); - static const SK_OT_USHORT WWSMask = SkTEndian_SwapBE16(1 << 8); - static const SK_OT_USHORT ObliqueMask = SkTEndian_SwapBE16(1 << 9); + static const SK_OT_USHORT ItalicMask = SkOTSetUSHORTBit<0>::value; + static const SK_OT_USHORT UnderscoreMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT NegativeMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT OutlinedMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT StrikeoutMask = SkOTSetUSHORTBit<4>::value; + static const SK_OT_USHORT BoldMask = SkOTSetUSHORTBit<5>::value; + static const SK_OT_USHORT RegularMask = SkOTSetUSHORTBit<6>::value; + static const SK_OT_USHORT UseTypoMetricsMask = SkOTSetUSHORTBit<7>::value; + static const SK_OT_USHORT WWSMask = SkOTSetUSHORTBit<8>::value; + static const SK_OT_USHORT ObliqueMask = SkOTSetUSHORTBit<9>::value; SK_OT_USHORT value; } raw; } fsSelection; @@ -529,42 +529,42 @@ struct SkOTTableOS2_V4 { } field; struct Raw { struct l0 { - static const SK_OT_ULONG Latin1_1252Mask = SkTEndian_SwapBE32(1 << 0); - static const SK_OT_ULONG Latin2EasternEurope_1250Mask = SkTEndian_SwapBE32(1 << 1); - static const SK_OT_ULONG Cyrillic_1251Mask = SkTEndian_SwapBE32(1 << 2); - static const SK_OT_ULONG Greek_1253Mask = SkTEndian_SwapBE32(1 << 3); - static const SK_OT_ULONG Turkish_1254Mask = SkTEndian_SwapBE32(1 << 4); - static const SK_OT_ULONG Hebrew_1255Mask = SkTEndian_SwapBE32(1 << 5); - static const SK_OT_ULONG Arabic_1256Mask = SkTEndian_SwapBE32(1 << 6); - static const SK_OT_ULONG WindowsBaltic_1257Mask = SkTEndian_SwapBE32(1 << 7); - static const SK_OT_ULONG Vietnamese_1258Mask = SkTEndian_SwapBE32(1 << 8); - static const SK_OT_ULONG Thai_874Mask = SkTEndian_SwapBE32(1 << 16); - static const SK_OT_ULONG JISJapan_932Mask = SkTEndian_SwapBE32(1 << 17); - static const SK_OT_ULONG ChineseSimplified_936Mask = SkTEndian_SwapBE32(1 << 18); - static const SK_OT_ULONG KoreanWansung_949Mask = SkTEndian_SwapBE32(1 << 19); - static const SK_OT_ULONG ChineseTraditional_950Mask = SkTEndian_SwapBE32(1 << 20); - static const SK_OT_ULONG KoreanJohab_1361Mask = SkTEndian_SwapBE32(1 << 21); - static const SK_OT_ULONG MacintoshCharacterSetMask = SkTEndian_SwapBE32(1 << 29); - static const SK_OT_ULONG OEMCharacterSetMask = SkTEndian_SwapBE32(1 << 30); - static const SK_OT_ULONG SymbolCharacterSetMask = SkTEndian_SwapBE32(1 << 31); + static const SK_OT_ULONG Latin1_1252Mask = SkOTSetULONGBit<0>::value; + static const SK_OT_ULONG Latin2EasternEurope_1250Mask = SkOTSetULONGBit<1>::value; + static const SK_OT_ULONG Cyrillic_1251Mask = SkOTSetULONGBit<2>::value; + static const SK_OT_ULONG Greek_1253Mask = SkOTSetULONGBit<3>::value; + static const SK_OT_ULONG Turkish_1254Mask = SkOTSetULONGBit<4>::value; + static const SK_OT_ULONG Hebrew_1255Mask = SkOTSetULONGBit<5>::value; + static const SK_OT_ULONG Arabic_1256Mask = SkOTSetULONGBit<6>::value; + static const SK_OT_ULONG WindowsBaltic_1257Mask = SkOTSetULONGBit<7>::value; + static const SK_OT_ULONG Vietnamese_1258Mask = SkOTSetULONGBit<8>::value; + static const SK_OT_ULONG Thai_874Mask = SkOTSetULONGBit<16>::value; + static const SK_OT_ULONG JISJapan_932Mask = SkOTSetULONGBit<17>::value; + static const SK_OT_ULONG ChineseSimplified_936Mask = SkOTSetULONGBit<18>::value; + static const SK_OT_ULONG KoreanWansung_949Mask = SkOTSetULONGBit<19>::value; + static const SK_OT_ULONG ChineseTraditional_950Mask = SkOTSetULONGBit<20>::value; + static const SK_OT_ULONG KoreanJohab_1361Mask = SkOTSetULONGBit<21>::value; + static const SK_OT_ULONG MacintoshCharacterSetMask = SkOTSetULONGBit<29>::value; + static const SK_OT_ULONG OEMCharacterSetMask = SkOTSetULONGBit<30>::value; + static const SK_OT_ULONG SymbolCharacterSetMask = SkOTSetULONGBit<31>::value; }; struct l1 { - static const SK_OT_ULONG IBMGreek_869Mask = SkTEndian_SwapBE32(1 << (48 - 32)); - static const SK_OT_ULONG MSDOSRussian_866Mask = SkTEndian_SwapBE32(1 << (49 - 32)); - static const SK_OT_ULONG MSDOSNordic_865Mask = SkTEndian_SwapBE32(1 << (50 - 32)); - static const SK_OT_ULONG Arabic_864Mask = SkTEndian_SwapBE32(1 << (51 - 32)); - static const SK_OT_ULONG MSDOSCanadianFrench_863Mask = SkTEndian_SwapBE32(1 << (52 - 32)); - static const SK_OT_ULONG Hebrew_862Mask = SkTEndian_SwapBE32(1 << (53 - 32)); - static const SK_OT_ULONG MSDOSIcelandic_861Mask = SkTEndian_SwapBE32(1 << (54 - 32)); - static const SK_OT_ULONG MSDOSPortuguese_860Mask = SkTEndian_SwapBE32(1 << (55 - 32)); - static const SK_OT_ULONG IBMTurkish_857Mask = SkTEndian_SwapBE32(1 << (56 - 32)); - static const SK_OT_ULONG IBMCyrillic_855Mask = SkTEndian_SwapBE32(1 << (57 - 32)); - static const SK_OT_ULONG Latin2_852Mask = SkTEndian_SwapBE32(1 << (58 - 32)); - static const SK_OT_ULONG MSDOSBaltic_775Mask = SkTEndian_SwapBE32(1 << (59 - 32)); - static const SK_OT_ULONG Greek_737Mask = SkTEndian_SwapBE32(1 << (60 - 32)); - static const SK_OT_ULONG Arabic_708Mask = SkTEndian_SwapBE32(1 << (61 - 32)); - static const SK_OT_ULONG WELatin1_850Mask = SkTEndian_SwapBE32(1 << (62 - 32)); - static const SK_OT_ULONG US_437Mask = SkTEndian_SwapBE32(1 << (63 - 32)); + static const SK_OT_ULONG IBMGreek_869Mask = SkOTSetULONGBit<48 - 32>::value; + static const SK_OT_ULONG MSDOSRussian_866Mask = SkOTSetULONGBit<49 - 32>::value; + static const SK_OT_ULONG MSDOSNordic_865Mask = SkOTSetULONGBit<50 - 32>::value; + static const SK_OT_ULONG Arabic_864Mask = SkOTSetULONGBit<51 - 32>::value; + static const SK_OT_ULONG MSDOSCanadianFrench_863Mask = SkOTSetULONGBit<52 - 32>::value; + static const SK_OT_ULONG Hebrew_862Mask = SkOTSetULONGBit<53 - 32>::value; + static const SK_OT_ULONG MSDOSIcelandic_861Mask = SkOTSetULONGBit<54 - 32>::value; + static const SK_OT_ULONG MSDOSPortuguese_860Mask = SkOTSetULONGBit<55 - 32>::value; + static const SK_OT_ULONG IBMTurkish_857Mask = SkOTSetULONGBit<56 - 32>::value; + static const SK_OT_ULONG IBMCyrillic_855Mask = SkOTSetULONGBit<57 - 32>::value; + static const SK_OT_ULONG Latin2_852Mask = SkOTSetULONGBit<58 - 32>::value; + static const SK_OT_ULONG MSDOSBaltic_775Mask = SkOTSetULONGBit<59 - 32>::value; + static const SK_OT_ULONG Greek_737Mask = SkOTSetULONGBit<60 - 32>::value; + static const SK_OT_ULONG Arabic_708Mask = SkOTSetULONGBit<61 - 32>::value; + static const SK_OT_ULONG WELatin1_850Mask = SkOTSetULONGBit<62 - 32>::value; + static const SK_OT_ULONG US_437Mask = SkOTSetULONGBit<63 - 32>::value; }; SK_OT_ULONG value[2]; } raw; diff --git a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_VA.h b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_VA.h index 146e83b67e7f..bc45da20217c 100644 --- a/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_VA.h +++ b/gfx/skia/trunk/src/sfnt/SkOTTable_OS_2_VA.h @@ -76,10 +76,10 @@ struct SkOTTableOS2_VA { Reserved07) } field; struct Raw { - static const SK_OT_USHORT Installable = SkTEndian_SwapBE16(0); - static const SK_OT_USHORT RestrictedMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT PreviewPrintMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT EditableMask = SkTEndian_SwapBE16(1 << 3); + static const SK_OT_USHORT Installable = 0; + static const SK_OT_USHORT RestrictedMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT PreviewPrintMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT EditableMask = SkOTSetUSHORTBit<3>::value; SK_OT_USHORT value; } raw; } fsType; @@ -121,12 +121,12 @@ struct SkOTTableOS2_VA { Reserved07) } field; struct Raw { - static const SK_OT_USHORT ItalicMask = SkTEndian_SwapBE16(1 << 0); - static const SK_OT_USHORT UnderscoreMask = SkTEndian_SwapBE16(1 << 1); - static const SK_OT_USHORT NegativeMask = SkTEndian_SwapBE16(1 << 2); - static const SK_OT_USHORT OutlinedMask = SkTEndian_SwapBE16(1 << 3); - static const SK_OT_USHORT StrikeoutMask = SkTEndian_SwapBE16(1 << 4); - static const SK_OT_USHORT BoldMask = SkTEndian_SwapBE16(1 << 5); + static const SK_OT_USHORT ItalicMask = SkOTSetUSHORTBit<0>::value; + static const SK_OT_USHORT UnderscoreMask = SkOTSetUSHORTBit<1>::value; + static const SK_OT_USHORT NegativeMask = SkOTSetUSHORTBit<2>::value; + static const SK_OT_USHORT OutlinedMask = SkOTSetUSHORTBit<3>::value; + static const SK_OT_USHORT StrikeoutMask = SkOTSetUSHORTBit<4>::value; + static const SK_OT_USHORT BoldMask = SkOTSetUSHORTBit<5>::value; SK_OT_USHORT value; } raw; } fsSelection; diff --git a/gfx/skia/trunk/src/utils/SkBitSet.h b/gfx/skia/trunk/src/utils/SkBitSet.h old mode 100755 new mode 100644 diff --git a/gfx/skia/trunk/src/utils/SkBitmapHasher.cpp b/gfx/skia/trunk/src/utils/SkBitmapHasher.cpp index 9f0affdea7db..6c861cd04bc2 100644 --- a/gfx/skia/trunk/src/utils/SkBitmapHasher.cpp +++ b/gfx/skia/trunk/src/utils/SkBitmapHasher.cpp @@ -57,7 +57,7 @@ static inline uint64_t first_8_bytes_as_uint64(const uint8_t *bytearray) { // Hmm, that didn't work. Maybe if we create a new // kARGB_8888_Config version of the bitmap it will work better? SkBitmap copyBitmap; - if (!bitmap.copyTo(©Bitmap, SkBitmap::kARGB_8888_Config)) { + if (!bitmap.copyTo(©Bitmap, kPMColor_SkColorType)) { return false; } return ComputeDigestInternal(copyBitmap, result); diff --git a/gfx/skia/trunk/src/utils/SkCanvasStack.cpp b/gfx/skia/trunk/src/utils/SkCanvasStack.cpp index 8951149b421e..87e8f653e21b 100644 --- a/gfx/skia/trunk/src/utils/SkCanvasStack.cpp +++ b/gfx/skia/trunk/src/utils/SkCanvasStack.cpp @@ -65,7 +65,7 @@ void SkCanvasStack::clipToZOrderedBounds() { * canvas unlike all other matrix operations (i.e. translate, scale, etc) which * just pre-concatenate with the existing matrix. */ -void SkCanvasStack::setMatrix(const SkMatrix& matrix) { +void SkCanvasStack::didSetMatrix(const SkMatrix& matrix) { SkASSERT(fList.count() == fCanvasData.count()); for (int i = 0; i < fList.count(); ++i) { @@ -74,28 +74,25 @@ void SkCanvasStack::setMatrix(const SkMatrix& matrix) { SkIntToScalar(-fCanvasData[i].origin.y())); fList[i]->setMatrix(tempMatrix); } - this->SkCanvas::setMatrix(matrix); + this->SkCanvas::didSetMatrix(matrix); } -bool SkCanvasStack::clipRect(const SkRect& r, SkRegion::Op op, bool aa) { - bool result = this->INHERITED::clipRect(r, op, aa); +void SkCanvasStack::onClipRect(const SkRect& r, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + this->INHERITED::onClipRect(r, op, edgeStyle); this->clipToZOrderedBounds(); - return result; } -bool SkCanvasStack::clipRRect(const SkRRect& rr, SkRegion::Op op, bool aa) { - bool result = this->INHERITED::clipRRect(rr, op, aa); +void SkCanvasStack::onClipRRect(const SkRRect& rr, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + this->INHERITED::onClipRRect(rr, op, edgeStyle); this->clipToZOrderedBounds(); - return result; } -bool SkCanvasStack::clipPath(const SkPath& p, SkRegion::Op op, bool aa) { - bool result = this->INHERITED::clipPath(p, op, aa); +void SkCanvasStack::onClipPath(const SkPath& p, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + this->INHERITED::onClipPath(p, op, edgeStyle); this->clipToZOrderedBounds(); - return result; } -bool SkCanvasStack::clipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { +void SkCanvasStack::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { SkASSERT(fList.count() == fCanvasData.count()); for (int i = 0; i < fList.count(); ++i) { SkRegion tempRegion; @@ -104,5 +101,5 @@ bool SkCanvasStack::clipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { tempRegion.op(fCanvasData[i].requiredClip, SkRegion::kIntersect_Op); fList[i]->clipRegion(tempRegion, op); } - return this->SkCanvas::clipRegion(deviceRgn, op); + this->SkCanvas::onClipRegion(deviceRgn, op); } diff --git a/gfx/skia/trunk/src/utils/SkCanvasStack.h b/gfx/skia/trunk/src/utils/SkCanvasStack.h index 531111827038..028e52604864 100644 --- a/gfx/skia/trunk/src/utils/SkCanvasStack.h +++ b/gfx/skia/trunk/src/utils/SkCanvasStack.h @@ -29,12 +29,13 @@ public: virtual void addCanvas(SkCanvas*) SK_OVERRIDE { SkDEBUGFAIL("Invalid Op"); } virtual void removeCanvas(SkCanvas*) SK_OVERRIDE { SkDEBUGFAIL("Invalid Op"); } - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRRect(const SkRRect&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; - virtual bool clipRegion(const SkRegion& deviceRgn, - SkRegion::Op) SK_OVERRIDE; +protected: + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion&, SkRegion::Op) SK_OVERRIDE; private: void clipToZOrderedBounds(); diff --git a/gfx/skia/trunk/src/utils/SkCanvasStateUtils.cpp b/gfx/skia/trunk/src/utils/SkCanvasStateUtils.cpp index eb92c37b1935..c5b558a1fbb5 100644 --- a/gfx/skia/trunk/src/utils/SkCanvasStateUtils.cpp +++ b/gfx/skia/trunk/src/utils/SkCanvasStateUtils.cpp @@ -130,6 +130,10 @@ public: fFailed |= antialias; } + virtual void clipRRect(const SkRRect& rrect, SkRegion::Op op, bool antialias) SK_OVERRIDE { + fFailed |= antialias; + } + virtual void clipPath(const SkPath&, SkRegion::Op, bool antialias) SK_OVERRIDE { fFailed |= antialias; } @@ -190,7 +194,8 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) { SkAutoTDelete canvasState(SkNEW_ARGS(SkCanvasState, (canvas))); // decompose the total matrix and clip - setup_MC_state(&canvasState->mcState, canvas->getTotalMatrix(), canvas->getTotalClip()); + setup_MC_state(&canvasState->mcState, canvas->getTotalMatrix(), + canvas->internal_private_getTotalClip()); /* * decompose the layers @@ -217,11 +222,11 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) { layerState->width = bitmap.width(); layerState->height = bitmap.height(); - switch (bitmap.config()) { - case SkBitmap::kARGB_8888_Config: + switch (bitmap.colorType()) { + case kPMColor_SkColorType: layerState->raster.config = kARGB_8888_RasterConfig; break; - case SkBitmap::kRGB_565_Config: + case kRGB_565_SkColorType: layerState->raster.config = kRGB_565_RasterConfig; break; default: @@ -275,25 +280,24 @@ static SkCanvas* create_canvas_from_canvas_layer(const SkCanvasLayerState& layer SkASSERT(kRaster_CanvasBackend == layerState.type); SkBitmap bitmap; - SkBitmap::Config config = - layerState.raster.config == kARGB_8888_RasterConfig ? SkBitmap::kARGB_8888_Config : - layerState.raster.config == kRGB_565_RasterConfig ? SkBitmap::kRGB_565_Config : - SkBitmap::kNo_Config; + SkColorType colorType = + layerState.raster.config == kARGB_8888_RasterConfig ? kPMColor_SkColorType : + layerState.raster.config == kRGB_565_RasterConfig ? kRGB_565_SkColorType : + kUnknown_SkColorType; - if (config == SkBitmap::kNo_Config) { + if (colorType == kUnknown_SkColorType) { return NULL; } - bitmap.setConfig(config, layerState.width, layerState.height, - layerState.raster.rowBytes); - bitmap.setPixels(layerState.raster.pixels); + bitmap.installPixels(SkImageInfo::Make(layerState.width, layerState.height, + colorType, kPremul_SkAlphaType), + layerState.raster.pixels, layerState.raster.rowBytes, + NULL, NULL); SkASSERT(!bitmap.empty()); SkASSERT(!bitmap.isNull()); - // create a device & canvas - SkAutoTUnref device(SkNEW_ARGS(SkBitmapDevice, (bitmap))); - SkAutoTUnref canvas(SkNEW_ARGS(SkCanvas, (device.get()))); + SkAutoTUnref canvas(SkNEW_ARGS(SkCanvas, (bitmap))); // setup the matrix and clip setup_canvas_from_MC_state(layerState.mcState, canvas.get()); diff --git a/gfx/skia/trunk/src/utils/SkDeferredCanvas.cpp b/gfx/skia/trunk/src/utils/SkDeferredCanvas.cpp index efc65463b521..984fe05b2b60 100644 --- a/gfx/skia/trunk/src/utils/SkDeferredCanvas.cpp +++ b/gfx/skia/trunk/src/utils/SkDeferredCanvas.cpp @@ -30,8 +30,7 @@ enum PlaybackMode { kSilent_PlaybackMode, }; -namespace { -bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint, +static bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint, size_t bitmapSizeThreshold) { if (bitmap && ((bitmap->getTexture() && !bitmap->isImmutable()) || (bitmap->getSize() > bitmapSizeThreshold))) { @@ -54,7 +53,6 @@ bool shouldDrawImmediately(const SkBitmap* bitmap, const SkPaint* paint, } return false; } -} //----------------------------------------------------------------------------- // DeferredPipeController @@ -135,13 +133,12 @@ void DeferredPipeController::playback(bool silent) { } //----------------------------------------------------------------------------- -// DeferredDevice +// SkDeferredDevice //----------------------------------------------------------------------------- -// FIXME: Derive from SkBaseDevice. -class DeferredDevice : public SkBitmapDevice { +class SkDeferredDevice : public SkBaseDevice { public: - explicit DeferredDevice(SkSurface* surface); - ~DeferredDevice(); + explicit SkDeferredDevice(SkSurface* surface); + ~SkDeferredDevice(); void setNotificationClient(SkDeferredCanvas::NotificationClient* notificationClient); SkCanvas* recordingCanvas(); @@ -160,19 +157,20 @@ public: void setMaxRecordingStorage(size_t); void recordedDrawCommand(); - virtual uint32_t getDeviceCapabilities() SK_OVERRIDE; virtual int width() const SK_OVERRIDE; virtual int height() const SK_OVERRIDE; + virtual SkBitmap::Config config() const SK_OVERRIDE; + virtual bool isOpaque() const SK_OVERRIDE; + virtual SkImageInfo imageInfo() const SK_OVERRIDE; + virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE; - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) SK_OVERRIDE; + virtual SkBaseDevice* onCreateDevice(const SkImageInfo&, Usage) SK_OVERRIDE; +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG virtual void writePixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) SK_OVERRIDE; - +#endif virtual SkSurface* newSurface(const SkImageInfo&) SK_OVERRIDE; protected: @@ -180,6 +178,7 @@ protected: virtual bool onReadPixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) SK_OVERRIDE; + virtual bool onWritePixels(const SkImageInfo&, const void*, size_t, int x, int y) SK_OVERRIDE; // The following methods are no-ops on a deferred device virtual bool filterTextFlags(const SkPaint& paint, TextFlags*) SK_OVERRIDE { @@ -199,9 +198,11 @@ protected: virtual void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) SK_OVERRIDE {SkASSERT(0);} + virtual void drawOval(const SkDraw&, const SkRect&, const SkPaint&) SK_OVERRIDE + {SkASSERT(0);} virtual void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) SK_OVERRIDE - {SkASSERT(0);} + {SkASSERT(0);} virtual void drawPath(const SkDraw&, const SkPath& path, const SkPaint& paint, const SkMatrix* prePathMatrix = NULL, @@ -210,6 +211,10 @@ protected: virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap, const SkMatrix& matrix, const SkPaint& paint) SK_OVERRIDE {SkASSERT(0);} + virtual void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, + const SkRect&, const SkPaint&, + SkCanvas::DrawBitmapRectFlags) SK_OVERRIDE + {SkASSERT(0);} virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y, const SkPaint& paint) SK_OVERRIDE {SkASSERT(0);} @@ -234,8 +239,24 @@ protected: virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) SK_OVERRIDE {SkASSERT(0);} + + virtual void lockPixels() SK_OVERRIDE {} + virtual void unlockPixels() SK_OVERRIDE {} + + virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { + return false; + } + virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { + return false; + } + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, + const SkImageFilter::Context&, SkBitmap*, SkIPoint*) SK_OVERRIDE { + return false; + } + private: virtual void flush() SK_OVERRIDE; + virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE {} void beginRecording(); void init(); @@ -255,12 +276,7 @@ private: size_t fBitmapSizeThreshold; }; -DeferredDevice::DeferredDevice(SkSurface* surface) - : SkBitmapDevice(SkBitmap::kNo_Config, - surface->getCanvas()->getDevice()->width(), - surface->getCanvas()->getDevice()->height(), - surface->getCanvas()->getDevice()->isOpaque(), - surface->getCanvas()->getDevice()->getDeviceProperties()) { +SkDeferredDevice::SkDeferredDevice(SkSurface* surface) { fMaxRecordingStorageBytes = kDefaultMaxRecordingStorageBytes; fNotificationClient = NULL; fImmediateCanvas = NULL; @@ -269,13 +285,13 @@ DeferredDevice::DeferredDevice(SkSurface* surface) this->init(); } -void DeferredDevice::setSurface(SkSurface* surface) { +void SkDeferredDevice::setSurface(SkSurface* surface) { SkRefCnt_SafeAssign(fImmediateCanvas, surface->getCanvas()); SkRefCnt_SafeAssign(fSurface, surface); fPipeController.setPlaybackCanvas(fImmediateCanvas); } -void DeferredDevice::init() { +void SkDeferredDevice::init() { fRecordingCanvas = NULL; fFreshFrame = true; fCanDiscardCanvasContents = false; @@ -286,29 +302,29 @@ void DeferredDevice::init() { this->beginRecording(); } -DeferredDevice::~DeferredDevice() { +SkDeferredDevice::~SkDeferredDevice() { this->flushPendingCommands(kSilent_PlaybackMode); SkSafeUnref(fImmediateCanvas); SkSafeUnref(fSurface); } -void DeferredDevice::setMaxRecordingStorage(size_t maxStorage) { +void SkDeferredDevice::setMaxRecordingStorage(size_t maxStorage) { fMaxRecordingStorageBytes = maxStorage; this->recordingCanvas(); // Accessing the recording canvas applies the new limit. } -void DeferredDevice::beginRecording() { +void SkDeferredDevice::beginRecording() { SkASSERT(NULL == fRecordingCanvas); fRecordingCanvas = fPipeWriter.startRecording(&fPipeController, 0, immediateDevice()->width(), immediateDevice()->height()); } -void DeferredDevice::setNotificationClient( +void SkDeferredDevice::setNotificationClient( SkDeferredCanvas::NotificationClient* notificationClient) { fNotificationClient = notificationClient; } -void DeferredDevice::skipPendingCommands() { +void SkDeferredDevice::skipPendingCommands() { if (!fRecordingCanvas->isDrawingToLayer()) { fCanDiscardCanvasContents = true; if (fPipeController.hasPendingCommands()) { @@ -321,17 +337,17 @@ void DeferredDevice::skipPendingCommands() { } } -bool DeferredDevice::isFreshFrame() { +bool SkDeferredDevice::isFreshFrame() { bool ret = fFreshFrame; fFreshFrame = false; return ret; } -bool DeferredDevice::hasPendingCommands() { +bool SkDeferredDevice::hasPendingCommands() { return fPipeController.hasPendingCommands(); } -void DeferredDevice::aboutToDraw() +void SkDeferredDevice::aboutToDraw() { if (NULL != fNotificationClient) { fNotificationClient->prepareForDraw(); @@ -344,7 +360,7 @@ void DeferredDevice::aboutToDraw() } } -void DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) { +void SkDeferredDevice::flushPendingCommands(PlaybackMode playbackMode) { if (!fPipeController.hasPendingCommands()) { return; } @@ -359,31 +375,31 @@ void DeferredDevice::flushPendingCommands(PlaybackMode playbackMode) { fPreviousStorageAllocated = storageAllocatedForRecording(); } -void DeferredDevice::flush() { +void SkDeferredDevice::flush() { this->flushPendingCommands(kNormal_PlaybackMode); fImmediateCanvas->flush(); } -size_t DeferredDevice::freeMemoryIfPossible(size_t bytesToFree) { +size_t SkDeferredDevice::freeMemoryIfPossible(size_t bytesToFree) { size_t val = fPipeWriter.freeMemoryIfPossible(bytesToFree); fPreviousStorageAllocated = storageAllocatedForRecording(); return val; } -size_t DeferredDevice::getBitmapSizeThreshold() const { +size_t SkDeferredDevice::getBitmapSizeThreshold() const { return fBitmapSizeThreshold; } -void DeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) { +void SkDeferredDevice::setBitmapSizeThreshold(size_t sizeThreshold) { fBitmapSizeThreshold = sizeThreshold; } -size_t DeferredDevice::storageAllocatedForRecording() const { +size_t SkDeferredDevice::storageAllocatedForRecording() const { return (fPipeController.storageAllocatedForRecording() + fPipeWriter.storageAllocatedForRecording()); } -void DeferredDevice::recordedDrawCommand() { +void SkDeferredDevice::recordedDrawCommand() { size_t storageAllocated = this->storageAllocatedForRecording(); if (storageAllocated > fMaxRecordingStorageBytes) { @@ -406,33 +422,41 @@ void DeferredDevice::recordedDrawCommand() { } } -SkCanvas* DeferredDevice::recordingCanvas() { +SkCanvas* SkDeferredDevice::recordingCanvas() { return fRecordingCanvas; } -SkImage* DeferredDevice::newImageSnapshot() { +SkImage* SkDeferredDevice::newImageSnapshot() { this->flush(); return fSurface ? fSurface->newImageSnapshot() : NULL; } -uint32_t DeferredDevice::getDeviceCapabilities() { - return immediateDevice()->getDeviceCapabilities(); -} - -int DeferredDevice::width() const { +int SkDeferredDevice::width() const { return immediateDevice()->width(); } -int DeferredDevice::height() const { +int SkDeferredDevice::height() const { return immediateDevice()->height(); } -GrRenderTarget* DeferredDevice::accessRenderTarget() { +SkBitmap::Config SkDeferredDevice::config() const { + return immediateDevice()->config(); +} + +bool SkDeferredDevice::isOpaque() const { + return immediateDevice()->isOpaque(); +} + +SkImageInfo SkDeferredDevice::imageInfo() const { + return immediateDevice()->imageInfo(); +} + +GrRenderTarget* SkDeferredDevice::accessRenderTarget() { this->flushPendingCommands(kNormal_PlaybackMode); return immediateDevice()->accessRenderTarget(); } -void DeferredDevice::prepareForImmediatePixelWrite() { +void SkDeferredDevice::prepareForImmediatePixelWrite() { // The purpose of the following code is to make sure commands are flushed, that // aboutToDraw() is called and that notifyContentWillChange is called, without // calling anything redundantly. @@ -449,8 +473,9 @@ void DeferredDevice::prepareForImmediatePixelWrite() { fImmediateCanvas->flush(); } -void DeferredDevice::writePixels(const SkBitmap& bitmap, - int x, int y, SkCanvas::Config8888 config8888) { +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG +void SkDeferredDevice::writePixels(const SkBitmap& bitmap, int x, int y, + SkCanvas::Config8888 config8888) { if (x <= 0 && y <= 0 && (x + bitmap.width()) >= width() && (y + bitmap.height()) >= height()) { @@ -477,31 +502,46 @@ void DeferredDevice::writePixels(const SkBitmap& bitmap, } } +#endif -const SkBitmap& DeferredDevice::onAccessBitmap() { +bool SkDeferredDevice::onWritePixels(const SkImageInfo& info, const void* pixels, size_t rowBytes, + int x, int y) { + SkASSERT(x >= 0 && y >= 0); + SkASSERT(x + info.width() <= width()); + SkASSERT(y + info.height() <= height()); + + this->flushPendingCommands(kNormal_PlaybackMode); + + const SkImageInfo deviceInfo = this->imageInfo(); + if (info.width() == deviceInfo.width() && info.height() == deviceInfo.height()) { + this->skipPendingCommands(); + } + + this->prepareForImmediatePixelWrite(); + return immediateDevice()->onWritePixels(info, pixels, rowBytes, x, y); +} + +const SkBitmap& SkDeferredDevice::onAccessBitmap() { this->flushPendingCommands(kNormal_PlaybackMode); return immediateDevice()->accessBitmap(false); } -SkBaseDevice* DeferredDevice::onCreateCompatibleDevice( - SkBitmap::Config config, int width, int height, bool isOpaque, - Usage usage) { - +SkBaseDevice* SkDeferredDevice::onCreateDevice(const SkImageInfo& info, Usage usage) { // Save layer usage not supported, and not required by SkDeferredCanvas. SkASSERT(usage != kSaveLayer_Usage); // Create a compatible non-deferred device. // We do not create a deferred device because we know the new device // will not be used with a deferred canvas (there is no API for that). - // And connecting a DeferredDevice to non-deferred canvas can result + // And connecting a SkDeferredDevice to non-deferred canvas can result // in unpredictable behavior. - return immediateDevice()->createCompatibleDevice(config, width, height, isOpaque); + return immediateDevice()->createCompatibleDevice(info); } -SkSurface* DeferredDevice::newSurface(const SkImageInfo& info) { +SkSurface* SkDeferredDevice::newSurface(const SkImageInfo& info) { return this->immediateDevice()->newSurface(info); } -bool DeferredDevice::onReadPixels( +bool SkDeferredDevice::onReadPixels( const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { this->flushPendingCommands(kNormal_PlaybackMode); return fImmediateCanvas->readPixels(const_cast(&bitmap), @@ -527,7 +567,7 @@ public: private: void init(SkDeferredCanvas& canvas, const SkBitmap* bitmap, const SkPaint* paint) { - DeferredDevice* device = static_cast(canvas.getDevice()); + SkDeferredDevice* device = static_cast(canvas.getDevice()); if (canvas.isDeferredDrawing() && (NULL != device) && shouldDrawImmediately(bitmap, paint, device->getBitmapSizeThreshold())) { canvas.setDeferredDrawing(false); @@ -541,11 +581,11 @@ private: }; SkDeferredCanvas* SkDeferredCanvas::Create(SkSurface* surface) { - SkAutoTUnref deferredDevice(SkNEW_ARGS(DeferredDevice, (surface))); + SkAutoTUnref deferredDevice(SkNEW_ARGS(SkDeferredDevice, (surface))); return SkNEW_ARGS(SkDeferredCanvas, (deferredDevice)); } -SkDeferredCanvas::SkDeferredCanvas(DeferredDevice* device) : SkCanvas (device) { +SkDeferredCanvas::SkDeferredCanvas(SkDeferredDevice* device) : SkCanvas (device) { this->init(); } @@ -567,7 +607,7 @@ size_t SkDeferredCanvas::freeMemoryIfPossible(size_t bytesToFree) { } void SkDeferredCanvas::setBitmapSizeThreshold(size_t sizeThreshold) { - DeferredDevice* deferredDevice = this->getDeferredDevice(); + SkDeferredDevice* deferredDevice = this->getDeferredDevice(); SkASSERT(deferredDevice); deferredDevice->setBitmapSizeThreshold(sizeThreshold); } @@ -593,8 +633,8 @@ SkCanvas* SkDeferredCanvas::immediateCanvas() const { return this->getDeferredDevice()->immediateCanvas(); } -DeferredDevice* SkDeferredCanvas::getDeferredDevice() const { - return static_cast(this->getDevice()); +SkDeferredDevice* SkDeferredCanvas::getDeferredDevice() const { + return static_cast(this->getDevice()); } void SkDeferredCanvas::setDeferredDrawing(bool val) { @@ -630,7 +670,7 @@ SkDeferredCanvas::~SkDeferredCanvas() { } SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) { - DeferredDevice* deferredDevice = this->getDeferredDevice(); + SkDeferredDevice* deferredDevice = this->getDeferredDevice(); SkASSERT(NULL != deferredDevice); // By swapping the surface into the existing device, we preserve // all pending commands, which can help to seamlessly recover from @@ -642,7 +682,7 @@ SkSurface* SkDeferredCanvas::setSurface(SkSurface* surface) { SkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient( NotificationClient* notificationClient) { - DeferredDevice* deferredDevice = this->getDeferredDevice(); + SkDeferredDevice* deferredDevice = this->getDeferredDevice(); SkASSERT(deferredDevice); if (deferredDevice) { deferredDevice->setNotificationClient(notificationClient); @@ -651,7 +691,7 @@ SkDeferredCanvas::NotificationClient* SkDeferredCanvas::setNotificationClient( } SkImage* SkDeferredCanvas::newImageSnapshot() { - DeferredDevice* deferredDevice = this->getDeferredDevice(); + SkDeferredDevice* deferredDevice = this->getDeferredDevice(); SkASSERT(deferredDevice); return deferredDevice ? deferredDevice->newImageSnapshot() : NULL; } @@ -694,108 +734,95 @@ bool SkDeferredCanvas::isFullFrame(const SkRect* rect, SkIntToScalar(canvasSize.fWidth), SkIntToScalar(canvasSize.fHeight))); } -int SkDeferredCanvas::save(SaveFlags flags) { +void SkDeferredCanvas::willSave(SaveFlags flags) { this->drawingCanvas()->save(flags); - int val = this->INHERITED::save(flags); this->recordedDrawCommand(); - - return val; + this->INHERITED::willSave(flags); } -int SkDeferredCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { +SkCanvas::SaveLayerStrategy SkDeferredCanvas::willSaveLayer(const SkRect* bounds, + const SkPaint* paint, SaveFlags flags) { this->drawingCanvas()->saveLayer(bounds, paint, flags); - int count = this->INHERITED::save(flags); - this->clipRectBounds(bounds, flags, NULL); this->recordedDrawCommand(); - - return count; + this->INHERITED::willSaveLayer(bounds, paint, flags); + // No need for a full layer. + return kNoLayer_SaveLayerStrategy; } -void SkDeferredCanvas::restore() { +void SkDeferredCanvas::willRestore() { this->drawingCanvas()->restore(); - this->INHERITED::restore(); this->recordedDrawCommand(); + this->INHERITED::willRestore(); } bool SkDeferredCanvas::isDrawingToLayer() const { return this->drawingCanvas()->isDrawingToLayer(); } -bool SkDeferredCanvas::translate(SkScalar dx, SkScalar dy) { +void SkDeferredCanvas::didTranslate(SkScalar dx, SkScalar dy) { this->drawingCanvas()->translate(dx, dy); - bool val = this->INHERITED::translate(dx, dy); this->recordedDrawCommand(); - return val; + this->INHERITED::didTranslate(dx, dy); } -bool SkDeferredCanvas::scale(SkScalar sx, SkScalar sy) { +void SkDeferredCanvas::didScale(SkScalar sx, SkScalar sy) { this->drawingCanvas()->scale(sx, sy); - bool val = this->INHERITED::scale(sx, sy); this->recordedDrawCommand(); - return val; + this->INHERITED::didScale(sx, sy); } -bool SkDeferredCanvas::rotate(SkScalar degrees) { +void SkDeferredCanvas::didRotate(SkScalar degrees) { this->drawingCanvas()->rotate(degrees); - bool val = this->INHERITED::rotate(degrees); this->recordedDrawCommand(); - return val; + this->INHERITED::didRotate(degrees); } -bool SkDeferredCanvas::skew(SkScalar sx, SkScalar sy) { +void SkDeferredCanvas::didSkew(SkScalar sx, SkScalar sy) { this->drawingCanvas()->skew(sx, sy); - bool val = this->INHERITED::skew(sx, sy); this->recordedDrawCommand(); - return val; + this->INHERITED::didSkew(sx, sy); } -bool SkDeferredCanvas::concat(const SkMatrix& matrix) { +void SkDeferredCanvas::didConcat(const SkMatrix& matrix) { this->drawingCanvas()->concat(matrix); - bool val = this->INHERITED::concat(matrix); this->recordedDrawCommand(); - return val; + this->INHERITED::didConcat(matrix); } -void SkDeferredCanvas::setMatrix(const SkMatrix& matrix) { +void SkDeferredCanvas::didSetMatrix(const SkMatrix& matrix) { this->drawingCanvas()->setMatrix(matrix); - this->INHERITED::setMatrix(matrix); + this->recordedDrawCommand(); + this->INHERITED::didSetMatrix(matrix); +} + +void SkDeferredCanvas::onClipRect(const SkRect& rect, + SkRegion::Op op, + ClipEdgeStyle edgeStyle) { + this->drawingCanvas()->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); + this->INHERITED::onClipRect(rect, op, edgeStyle); this->recordedDrawCommand(); } -bool SkDeferredCanvas::clipRect(const SkRect& rect, - SkRegion::Op op, - bool doAntiAlias) { - this->drawingCanvas()->clipRect(rect, op, doAntiAlias); - bool val = this->INHERITED::clipRect(rect, op, doAntiAlias); +void SkDeferredCanvas::onClipRRect(const SkRRect& rrect, + SkRegion::Op op, + ClipEdgeStyle edgeStyle) { + this->drawingCanvas()->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); + this->INHERITED::onClipRRect(rrect, op, edgeStyle); this->recordedDrawCommand(); - return val; } -bool SkDeferredCanvas::clipRRect(const SkRRect& rrect, - SkRegion::Op op, - bool doAntiAlias) { - this->drawingCanvas()->clipRRect(rrect, op, doAntiAlias); - bool val = this->INHERITED::clipRRect(rrect, op, doAntiAlias); +void SkDeferredCanvas::onClipPath(const SkPath& path, + SkRegion::Op op, + ClipEdgeStyle edgeStyle) { + this->drawingCanvas()->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle); + this->INHERITED::onClipPath(path, op, edgeStyle); this->recordedDrawCommand(); - return val; } -bool SkDeferredCanvas::clipPath(const SkPath& path, - SkRegion::Op op, - bool doAntiAlias) { - this->drawingCanvas()->clipPath(path, op, doAntiAlias); - bool val = this->INHERITED::clipPath(path, op, doAntiAlias); - this->recordedDrawCommand(); - return val; -} - -bool SkDeferredCanvas::clipRegion(const SkRegion& deviceRgn, - SkRegion::Op op) { +void SkDeferredCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { this->drawingCanvas()->clipRegion(deviceRgn, op); - bool val = this->INHERITED::clipRegion(deviceRgn, op); + this->INHERITED::onClipRegion(deviceRgn, op); this->recordedDrawCommand(); - return val; } void SkDeferredCanvas::clear(SkColor color) { @@ -854,6 +881,13 @@ void SkDeferredCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { } } +void SkDeferredCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + AutoImmediateDrawIfNeeded autoDraw(*this, &paint); + this->drawingCanvas()->drawDRRect(outer, inner, paint); + this->recordedDrawCommand(); +} + void SkDeferredCanvas::drawPath(const SkPath& path, const SkPaint& paint) { AutoImmediateDrawIfNeeded autoDraw(*this, &paint); this->drawingCanvas()->drawPath(path, paint); diff --git a/gfx/skia/trunk/src/utils/SkDumpCanvas.cpp b/gfx/skia/trunk/src/utils/SkDumpCanvas.cpp index 5f3a572ab92e..7445940f4e44 100644 --- a/gfx/skia/trunk/src/utils/SkDumpCanvas.cpp +++ b/gfx/skia/trunk/src/utils/SkDumpCanvas.cpp @@ -192,13 +192,13 @@ void SkDumpCanvas::dump(Verb verb, const SkPaint* paint, /////////////////////////////////////////////////////////////////////////////// -int SkDumpCanvas::save(SaveFlags flags) { +void SkDumpCanvas::willSave(SaveFlags flags) { this->dump(kSave_Verb, NULL, "save(0x%X)", flags); - return this->INHERITED::save(flags); + this->INHERITED::willSave(flags); } -int SkDumpCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { +SkCanvas::SaveLayerStrategy SkDumpCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags) { SkString str; str.printf("saveLayer(0x%X)", flags); if (bounds) { @@ -214,89 +214,98 @@ int SkDumpCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, } } this->dump(kSave_Verb, paint, str.c_str()); - return this->INHERITED::saveLayer(bounds, paint, flags); + return this->INHERITED::willSaveLayer(bounds, paint, flags); } -void SkDumpCanvas::restore() { - this->INHERITED::restore(); +void SkDumpCanvas::willRestore() { this->dump(kRestore_Verb, NULL, "restore"); + this->INHERITED::willRestore(); } -bool SkDumpCanvas::translate(SkScalar dx, SkScalar dy) { +void SkDumpCanvas::didTranslate(SkScalar dx, SkScalar dy) { this->dump(kMatrix_Verb, NULL, "translate(%g %g)", SkScalarToFloat(dx), SkScalarToFloat(dy)); - return this->INHERITED::translate(dx, dy); + this->INHERITED::didTranslate(dx, dy); } -bool SkDumpCanvas::scale(SkScalar sx, SkScalar sy) { +void SkDumpCanvas::didScale(SkScalar sx, SkScalar sy) { this->dump(kMatrix_Verb, NULL, "scale(%g %g)", SkScalarToFloat(sx), SkScalarToFloat(sy)); - return this->INHERITED::scale(sx, sy); + this->INHERITED::didScale(sx, sy); } -bool SkDumpCanvas::rotate(SkScalar degrees) { +void SkDumpCanvas::didRotate(SkScalar degrees) { this->dump(kMatrix_Verb, NULL, "rotate(%g)", SkScalarToFloat(degrees)); - return this->INHERITED::rotate(degrees); + this->INHERITED::didRotate(degrees); } -bool SkDumpCanvas::skew(SkScalar sx, SkScalar sy) { +void SkDumpCanvas::didSkew(SkScalar sx, SkScalar sy) { this->dump(kMatrix_Verb, NULL, "skew(%g %g)", SkScalarToFloat(sx), SkScalarToFloat(sy)); - return this->INHERITED::skew(sx, sy); + this->INHERITED::didSkew(sx, sy); } -bool SkDumpCanvas::concat(const SkMatrix& matrix) { +void SkDumpCanvas::didConcat(const SkMatrix& matrix) { SkString str; matrix.toString(&str); this->dump(kMatrix_Verb, NULL, "concat(%s)", str.c_str()); - return this->INHERITED::concat(matrix); + this->INHERITED::didConcat(matrix); } -void SkDumpCanvas::setMatrix(const SkMatrix& matrix) { +void SkDumpCanvas::didSetMatrix(const SkMatrix& matrix) { SkString str; matrix.toString(&str); this->dump(kMatrix_Verb, NULL, "setMatrix(%s)", str.c_str()); - this->INHERITED::setMatrix(matrix); + this->INHERITED::didSetMatrix(matrix); } /////////////////////////////////////////////////////////////////////////////// -static const char* bool_to_aastring(bool doAA) { - return doAA ? "AA" : "BW"; +const char* SkDumpCanvas::EdgeStyleToAAString(ClipEdgeStyle edgeStyle) { + return kSoft_ClipEdgeStyle == edgeStyle ? "AA" : "BW"; } -bool SkDumpCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { +void SkDumpCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { SkString str; toString(rect, &str); this->dump(kClip_Verb, NULL, "clipRect(%s %s %s)", str.c_str(), toString(op), - bool_to_aastring(doAA)); - return this->INHERITED::clipRect(rect, op, doAA); + EdgeStyleToAAString(edgeStyle)); + this->INHERITED::onClipRect(rect, op, edgeStyle); } -bool SkDumpCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { +void SkDumpCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { SkString str; toString(rrect, &str); this->dump(kClip_Verb, NULL, "clipRRect(%s %s %s)", str.c_str(), toString(op), - bool_to_aastring(doAA)); - return this->INHERITED::clipRRect(rrect, op, doAA); + EdgeStyleToAAString(edgeStyle)); + this->INHERITED::onClipRRect(rrect, op, edgeStyle); } -bool SkDumpCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { +void SkDumpCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { SkString str; toString(path, &str); this->dump(kClip_Verb, NULL, "clipPath(%s %s %s)", str.c_str(), toString(op), - bool_to_aastring(doAA)); - return this->INHERITED::clipPath(path, op, doAA); + EdgeStyleToAAString(edgeStyle)); + this->INHERITED::onClipPath(path, op, edgeStyle); } -bool SkDumpCanvas::clipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { +void SkDumpCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { SkString str; toString(deviceRgn, &str); this->dump(kClip_Verb, NULL, "clipRegion(%s %s)", str.c_str(), toString(op)); - return this->INHERITED::clipRegion(deviceRgn, op); + this->INHERITED::onClipRegion(deviceRgn, op); } +void SkDumpCanvas::onPushCull(const SkRect& cullRect) { + SkString str; + toString(cullRect, &str); + this->dump(kCull_Verb, NULL, "pushCull(%s)", str.c_str()); +} + +void SkDumpCanvas::onPopCull() { + this->dump(kCull_Verb, NULL, "popCull()"); +} /////////////////////////////////////////////////////////////////////////////// void SkDumpCanvas::drawPaint(const SkPaint& paint) { @@ -324,7 +333,16 @@ void SkDumpCanvas::drawRect(const SkRect& rect, const SkPaint& paint) { void SkDumpCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { SkString str; toString(rrect, &str); - this->dump(kDrawRRect_Verb, &paint, "drawRRect(%s)", str.c_str()); + this->dump(kDrawDRRect_Verb, &paint, "drawRRect(%s)", str.c_str()); +} + +void SkDumpCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + SkString str0, str1; + toString(outer, &str0); + toString(inner, &str0); + this->dump(kDrawRRect_Verb, &paint, "drawDRRect(%s,%s)", + str0.c_str(), str1.c_str()); } void SkDumpCanvas::drawPath(const SkPath& path, const SkPaint& paint) { diff --git a/gfx/skia/trunk/src/utils/SkGatherPixelRefsAndRects.h b/gfx/skia/trunk/src/utils/SkGatherPixelRefsAndRects.h index 51595259399d..a6ff16daf370 100644 --- a/gfx/skia/trunk/src/utils/SkGatherPixelRefsAndRects.h +++ b/gfx/skia/trunk/src/utils/SkGatherPixelRefsAndRects.h @@ -28,25 +28,31 @@ public: fSize.set(width, height); fPRCont = prCont; SkSafeRef(fPRCont); - fEmptyBitmap.setConfig(SkBitmap::kNo_Config, width, height); + fEmptyBitmap.setConfig(SkImageInfo::Make(width, height, + kUnknown_SkColorType, + kIgnore_SkAlphaType)); } virtual ~SkGatherPixelRefsAndRectsDevice() { SkSafeUnref(fPRCont); } - virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; } - virtual int width() const SK_OVERRIDE { return fSize.width(); } virtual int height() const SK_OVERRIDE { return fSize.height(); } virtual bool isOpaque() const SK_OVERRIDE { return false; } virtual SkBitmap::Config config() const SK_OVERRIDE { return SkBitmap::kNo_Config; } + virtual SkImageInfo imageInfo() const SK_OVERRIDE { + return fEmptyBitmap.info(); + } + +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG virtual void writePixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) SK_OVERRIDE { NotSupported(); } +#endif virtual GrRenderTarget* accessRenderTarget() SK_OVERRIDE { return NULL; } protected: @@ -301,7 +307,7 @@ protected: virtual void unlockPixels() SK_OVERRIDE { NothingToDo(); } virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } - virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkMatrix&, + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { return false; } @@ -326,13 +332,11 @@ private: NotSupported(); } - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) SK_OVERRIDE { + virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE { // we expect to only get called via savelayer, in which case it is fine. SkASSERT(kSaveLayer_Usage == usage); - return SkNEW_ARGS(SkGatherPixelRefsAndRectsDevice, (width, height, fPRCont)); + return SkNEW_ARGS(SkGatherPixelRefsAndRectsDevice, + (info.width(), info.height(), fPRCont)); } virtual void flush() SK_OVERRIDE {} diff --git a/gfx/skia/trunk/src/utils/SkLua.cpp b/gfx/skia/trunk/src/utils/SkLua.cpp index 9bbdc6c6adb1..4b874589234f 100644 --- a/gfx/skia/trunk/src/utils/SkLua.cpp +++ b/gfx/skia/trunk/src/utils/SkLua.cpp @@ -6,6 +6,11 @@ */ #include "SkLua.h" + +#if SK_SUPPORT_GPU +#include "GrReducedClip.h" +#endif + #include "SkCanvas.h" #include "SkData.h" #include "SkDocument.h" @@ -234,6 +239,73 @@ void SkLua::pushCanvas(SkCanvas* canvas, const char key[]) { CHECK_SETFIELD(key); } +static const char* element_type(SkClipStack::Element::Type type) { + switch (type) { + case SkClipStack::Element::kEmpty_Type: + return "empty"; + case SkClipStack::Element::kRect_Type: + return "rect"; + case SkClipStack::Element::kRRect_Type: + return "rrect"; + case SkClipStack::Element::kPath_Type: + return "path"; + } + return "unknown"; +} + +static const char* region_op(SkRegion::Op op) { + switch (op) { + case SkRegion::kDifference_Op: + return "difference"; + case SkRegion::kIntersect_Op: + return "intersect"; + case SkRegion::kUnion_Op: + return "union"; + case SkRegion::kXOR_Op: + return "xor"; + case SkRegion::kReverseDifference_Op: + return "reverse-difference"; + case SkRegion::kReplace_Op: + return "replace"; + } + return "unknown"; +} + +void SkLua::pushClipStack(const SkClipStack& stack, const char* key) { + lua_newtable(fL); + SkClipStack::B2TIter iter(stack); + const SkClipStack::Element* element; + int i = 0; + while (NULL != (element = iter.next())) { + this->pushClipStackElement(*element); + lua_rawseti(fL, -2, ++i); + } + CHECK_SETFIELD(key); +} + +void SkLua::pushClipStackElement(const SkClipStack::Element& element, const char* key) { + lua_newtable(fL); + SkClipStack::Element::Type type = element.getType(); + this->pushString(element_type(type), "type"); + switch (type) { + case SkClipStack::Element::kEmpty_Type: + break; + case SkClipStack::Element::kRect_Type: + this->pushRect(element.getRect(), "rect"); + break; + case SkClipStack::Element::kRRect_Type: + this->pushRRect(element.getRRect(), "rrect"); + break; + case SkClipStack::Element::kPath_Type: + this->pushPath(element.getPath(), "path"); + break; + } + this->pushString(region_op(element.getOp()), "op"); + this->pushBool(element.isAA(), "aa"); + CHECK_SETFIELD(key); +} + + /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -377,6 +449,50 @@ static int lcanvas_getTotalMatrix(lua_State* L) { return 1; } +static int lcanvas_getClipStack(lua_State* L) { + SkLua(L).pushClipStack(*get_ref(L, 1)->getClipStack()); + return 1; +} + +int SkLua::lcanvas_getReducedClipStack(lua_State* L) { +#if SK_SUPPORT_GPU + const SkCanvas* canvas = get_ref(L, 1); + SkISize layerSize = canvas->getTopLayerSize(); + SkIPoint layerOrigin = canvas->getTopLayerOrigin(); + SkIRect queryBounds = SkIRect::MakeXYWH(layerOrigin.fX, layerOrigin.fY, + layerSize.fWidth, layerSize.fHeight); + + GrReducedClip::ElementList elements; + GrReducedClip::InitialState initialState; + int32_t genID; + SkIRect resultBounds; + + const SkClipStack& stack = *canvas->getClipStack(); + + GrReducedClip::ReduceClipStack(stack, + queryBounds, + &elements, + &genID, + &initialState, + &resultBounds, + NULL); + + GrReducedClip::ElementList::Iter iter(elements); + int i = 0; + lua_newtable(L); + while(NULL != iter.get()) { + SkLua(L).pushClipStackElement(*iter.get()); + iter.next(); + lua_rawseti(L, -2, ++i); + } + // Currently this only returns the element list to lua, not the initial state or result bounds. + // It could return these as additional items on the lua stack. + return 1; +#else + return 0; +#endif +} + static int lcanvas_save(lua_State* L) { lua_pushinteger(L, get_ref(L, 1)->save()); return 1; @@ -412,7 +528,7 @@ static int lcanvas_gc(lua_State* L) { return 0; } -static const struct luaL_Reg gSkCanvas_Methods[] = { +const struct luaL_Reg gSkCanvas_Methods[] = { { "drawColor", lcanvas_drawColor }, { "drawRect", lcanvas_drawRect }, { "drawOval", lcanvas_drawOval }, @@ -422,6 +538,10 @@ static const struct luaL_Reg gSkCanvas_Methods[] = { { "drawText", lcanvas_drawText }, { "getSaveCount", lcanvas_getSaveCount }, { "getTotalMatrix", lcanvas_getTotalMatrix }, + { "getClipStack", lcanvas_getClipStack }, +#if SK_SUPPORT_GPU + { "getReducedClipStack", SkLua::lcanvas_getReducedClipStack }, +#endif { "save", lcanvas_save }, { "restore", lcanvas_restore }, { "scale", lcanvas_scale }, @@ -908,6 +1028,73 @@ static int lpath_getBounds(lua_State* L) { return 1; } +static const char* fill_type_to_str(SkPath::FillType fill) { + switch (fill) { + case SkPath::kEvenOdd_FillType: + return "even-odd"; + case SkPath::kWinding_FillType: + return "winding"; + case SkPath::kInverseEvenOdd_FillType: + return "inverse-even-odd"; + case SkPath::kInverseWinding_FillType: + return "inverse-winding"; + } + return "unknown"; +} + +static int lpath_getFillType(lua_State* L) { + SkPath::FillType fill = get_obj(L, 1)->getFillType(); + SkLua(L).pushString(fill_type_to_str(fill)); + return 1; +} + +static SkString segment_masks_to_str(uint32_t segmentMasks) { + SkString result; + bool first = true; + if (SkPath::kLine_SegmentMask & segmentMasks) { + result.append("line"); + first = false; + SkDEBUGCODE(segmentMasks &= ~SkPath::kLine_SegmentMask;) + } + if (SkPath::kQuad_SegmentMask & segmentMasks) { + if (!first) { + result.append(" "); + } + result.append("quad"); + first = false; + SkDEBUGCODE(segmentMasks &= ~SkPath::kQuad_SegmentMask;) + } + if (SkPath::kConic_SegmentMask & segmentMasks) { + if (!first) { + result.append(" "); + } + result.append("conic"); + first = false; + SkDEBUGCODE(segmentMasks &= ~SkPath::kConic_SegmentMask;) + } + if (SkPath::kCubic_SegmentMask & segmentMasks) { + if (!first) { + result.append(" "); + } + result.append("cubic"); + SkDEBUGCODE(segmentMasks &= ~SkPath::kCubic_SegmentMask;) + } + SkASSERT(0 == segmentMasks); + return result; +} + +static int lpath_getSegementTypes(lua_State* L) { + uint32_t segMasks = get_obj(L, 1)->getSegmentMasks(); + SkLua(L).pushString(segment_masks_to_str(segMasks)); + return 1; +} + +static int lpath_isConvex(lua_State* L) { + bool isConvex = SkPath::kConvex_Convexity == get_obj(L, 1)->getConvexity(); + SkLua(L).pushBool(isConvex); + return 1; +} + static int lpath_isEmpty(lua_State* L) { lua_pushboolean(L, get_obj(L, 1)->isEmpty()); return 1; @@ -950,6 +1137,11 @@ static int lpath_isNestedRects(lua_State* L) { return ret_count; } +static int lpath_countPoints(lua_State* L) { + lua_pushinteger(L, get_obj(L, 1)->countPoints()); + return 1; +} + static int lpath_reset(lua_State* L) { get_obj(L, 1)->reset(); return 0; @@ -990,9 +1182,13 @@ static int lpath_gc(lua_State* L) { static const struct luaL_Reg gSkPath_Methods[] = { { "getBounds", lpath_getBounds }, + { "getFillType", lpath_getFillType }, + { "getSegmentTypes", lpath_getSegementTypes }, + { "isConvex", lpath_isConvex }, { "isEmpty", lpath_isEmpty }, { "isRect", lpath_isRect }, { "isNestedRects", lpath_isNestedRects }, + { "countPoints", lpath_countPoints }, { "reset", lpath_reset }, { "moveTo", lpath_moveTo }, { "lineTo", lpath_lineTo }, diff --git a/gfx/skia/trunk/src/utils/SkLuaCanvas.cpp b/gfx/skia/trunk/src/utils/SkLuaCanvas.cpp index 7f127403ae02..9289beed887a 100644 --- a/gfx/skia/trunk/src/utils/SkLuaCanvas.cpp +++ b/gfx/skia/trunk/src/utils/SkLuaCanvas.cpp @@ -81,13 +81,13 @@ SkLuaCanvas::SkLuaCanvas(int width, int height, lua_State* L, const char func[]) SkLuaCanvas::~SkLuaCanvas() {} -int SkLuaCanvas::save(SaveFlags flags) { +void SkLuaCanvas::willSave(SaveFlags flags) { AUTO_LUA("save"); - return this->INHERITED::save(flags); + this->INHERITED::willSave(flags); } -int SkLuaCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { +SkCanvas::SaveLayerStrategy SkLuaCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags) { AUTO_LUA("saveLayer"); if (bounds) { lua.pushRect(*bounds, "bounds"); @@ -95,74 +95,77 @@ int SkLuaCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, if (paint) { lua.pushPaint(*paint, "paint"); } - return this->INHERITED::save(flags); + + this->INHERITED::willSaveLayer(bounds, paint, flags); + // No need for a layer. + return kNoLayer_SaveLayerStrategy; } -void SkLuaCanvas::restore() { +void SkLuaCanvas::willRestore() { AUTO_LUA("restore"); - this->INHERITED::restore(); + this->INHERITED::willRestore(); } -bool SkLuaCanvas::translate(SkScalar dx, SkScalar dy) { +void SkLuaCanvas::didTranslate(SkScalar dx, SkScalar dy) { AUTO_LUA("translate"); lua.pushScalar(dx, "dx"); lua.pushScalar(dy, "dy"); - return this->INHERITED::translate(dx, dy); + this->INHERITED::didTranslate(dx, dy); } -bool SkLuaCanvas::scale(SkScalar sx, SkScalar sy) { +void SkLuaCanvas::didScale(SkScalar sx, SkScalar sy) { AUTO_LUA("scale"); lua.pushScalar(sx, "sx"); lua.pushScalar(sy, "sy"); - return this->INHERITED::scale(sx, sy); + this->INHERITED::didScale(sx, sy); } -bool SkLuaCanvas::rotate(SkScalar degrees) { +void SkLuaCanvas::didRotate(SkScalar degrees) { AUTO_LUA("rotate"); lua.pushScalar(degrees, "degrees"); - return this->INHERITED::rotate(degrees); + this->INHERITED::didRotate(degrees); } -bool SkLuaCanvas::skew(SkScalar kx, SkScalar ky) { +void SkLuaCanvas::didSkew(SkScalar kx, SkScalar ky) { AUTO_LUA("skew"); lua.pushScalar(kx, "kx"); lua.pushScalar(ky, "ky"); - return this->INHERITED::skew(kx, ky); + this->INHERITED::didSkew(kx, ky); } -bool SkLuaCanvas::concat(const SkMatrix& matrix) { +void SkLuaCanvas::didConcat(const SkMatrix& matrix) { AUTO_LUA("concat"); - return this->INHERITED::concat(matrix); + this->INHERITED::didConcat(matrix); } -void SkLuaCanvas::setMatrix(const SkMatrix& matrix) { - this->INHERITED::setMatrix(matrix); +void SkLuaCanvas::didSetMatrix(const SkMatrix& matrix) { + this->INHERITED::didSetMatrix(matrix); } -bool SkLuaCanvas::clipRect(const SkRect& r, SkRegion::Op op, bool doAA) { +void SkLuaCanvas::onClipRect(const SkRect& r, SkRegion::Op op, ClipEdgeStyle edgeStyle) { AUTO_LUA("clipRect"); lua.pushRect(r, "rect"); - lua.pushBool(doAA, "aa"); - return this->INHERITED::clipRect(r, op, doAA); + lua.pushBool(kSoft_ClipEdgeStyle == edgeStyle, "aa"); + this->INHERITED::onClipRect(r, op, edgeStyle); } -bool SkLuaCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { +void SkLuaCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { AUTO_LUA("clipRRect"); lua.pushRRect(rrect, "rrect"); - lua.pushBool(doAA, "aa"); - return this->INHERITED::clipRRect(rrect, op, doAA); + lua.pushBool(kSoft_ClipEdgeStyle == edgeStyle, "aa"); + this->INHERITED::onClipRRect(rrect, op, edgeStyle); } -bool SkLuaCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { +void SkLuaCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { AUTO_LUA("clipPath"); lua.pushPath(path, "path"); - lua.pushBool(doAA, "aa"); - return this->INHERITED::clipPath(path, op, doAA); + lua.pushBool(kSoft_ClipEdgeStyle == edgeStyle, "aa"); + this->INHERITED::onClipPath(path, op, edgeStyle); } -bool SkLuaCanvas::clipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { +void SkLuaCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { AUTO_LUA("clipRegion"); - return this->INHERITED::clipRegion(deviceRgn, op); + this->INHERITED::onClipRegion(deviceRgn, op); } void SkLuaCanvas::drawPaint(const SkPaint& paint) { @@ -194,6 +197,14 @@ void SkLuaCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { lua.pushPaint(paint, "paint"); } +void SkLuaCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + AUTO_LUA("drawDRRect"); + lua.pushRRect(outer, "outer"); + lua.pushRRect(inner, "inner"); + lua.pushPaint(paint, "paint"); +} + void SkLuaCanvas::drawPath(const SkPath& path, const SkPaint& paint) { AUTO_LUA("drawPath"); lua.pushPath(path, "path"); diff --git a/gfx/skia/trunk/src/utils/SkMD5.h b/gfx/skia/trunk/src/utils/SkMD5.h index 6b4fc53636d4..4f504782b6b8 100644 --- a/gfx/skia/trunk/src/utils/SkMD5.h +++ b/gfx/skia/trunk/src/utils/SkMD5.h @@ -25,10 +25,12 @@ public: * Note that this treats the buffer as a series of uint8_t values. */ virtual bool write(const void* buffer, size_t size) SK_OVERRIDE { - update(reinterpret_cast(buffer), size); + this->update(reinterpret_cast(buffer), size); return true; } + virtual size_t bytesWritten() const SK_OVERRIDE { return SkToSizeT(this->byteCount); } + /** Processes input, adding it to the digest. Calling this after finish is undefined. */ void update(const uint8_t* input, size_t length); diff --git a/gfx/skia/trunk/src/utils/SkNWayCanvas.cpp b/gfx/skia/trunk/src/utils/SkNWayCanvas.cpp index 831d7bf6cf12..b127f21e8a9b 100644 --- a/gfx/skia/trunk/src/utils/SkNWayCanvas.cpp +++ b/gfx/skia/trunk/src/utils/SkNWayCanvas.cpp @@ -57,109 +57,113 @@ private: SkCanvas* fCanvas; }; -int SkNWayCanvas::save(SaveFlags flags) { +void SkNWayCanvas::willSave(SaveFlags flags) { Iter iter(fList); while (iter.next()) { iter->save(flags); } - return this->INHERITED::save(flags); + + this->INHERITED::willSave(flags); } -int SkNWayCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { +SkCanvas::SaveLayerStrategy SkNWayCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags) { Iter iter(fList); while (iter.next()) { iter->saveLayer(bounds, paint, flags); } - return this->INHERITED::saveLayer(bounds, paint, flags); + + this->INHERITED::willSaveLayer(bounds, paint, flags); + // No need for a layer. + return kNoLayer_SaveLayerStrategy; } -void SkNWayCanvas::restore() { +void SkNWayCanvas::willRestore() { Iter iter(fList); while (iter.next()) { iter->restore(); } - this->INHERITED::restore(); + this->INHERITED::willRestore(); } -bool SkNWayCanvas::translate(SkScalar dx, SkScalar dy) { +void SkNWayCanvas::didTranslate(SkScalar dx, SkScalar dy) { Iter iter(fList); while (iter.next()) { iter->translate(dx, dy); } - return this->INHERITED::translate(dx, dy); + this->INHERITED::didTranslate(dx, dy); } -bool SkNWayCanvas::scale(SkScalar sx, SkScalar sy) { +void SkNWayCanvas::didScale(SkScalar sx, SkScalar sy) { Iter iter(fList); while (iter.next()) { iter->scale(sx, sy); } - return this->INHERITED::scale(sx, sy); + this->INHERITED::didScale(sx, sy); } -bool SkNWayCanvas::rotate(SkScalar degrees) { +void SkNWayCanvas::didRotate(SkScalar degrees) { Iter iter(fList); while (iter.next()) { iter->rotate(degrees); } - return this->INHERITED::rotate(degrees); + this->INHERITED::didRotate(degrees); } -bool SkNWayCanvas::skew(SkScalar sx, SkScalar sy) { +void SkNWayCanvas::didSkew(SkScalar sx, SkScalar sy) { Iter iter(fList); while (iter.next()) { iter->skew(sx, sy); } - return this->INHERITED::skew(sx, sy); + this->INHERITED::didSkew(sx, sy); } -bool SkNWayCanvas::concat(const SkMatrix& matrix) { +void SkNWayCanvas::didConcat(const SkMatrix& matrix) { Iter iter(fList); while (iter.next()) { iter->concat(matrix); } - return this->INHERITED::concat(matrix); + this->INHERITED::didConcat(matrix); } -void SkNWayCanvas::setMatrix(const SkMatrix& matrix) { +void SkNWayCanvas::didSetMatrix(const SkMatrix& matrix) { Iter iter(fList); while (iter.next()) { iter->setMatrix(matrix); } - this->INHERITED::setMatrix(matrix); + this->INHERITED::didSetMatrix(matrix); } -bool SkNWayCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { +void SkNWayCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { Iter iter(fList); while (iter.next()) { - iter->clipRect(rect, op, doAA); + iter->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); } - return this->INHERITED::clipRect(rect, op, doAA); + this->INHERITED::onClipRect(rect, op, edgeStyle); } -bool SkNWayCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { +void SkNWayCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { Iter iter(fList); while (iter.next()) { - iter->clipRRect(rrect, op, doAA); + iter->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); } - return this->INHERITED::clipRRect(rrect, op, doAA); + this->INHERITED::onClipRRect(rrect, op, edgeStyle); } -bool SkNWayCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { +void SkNWayCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { Iter iter(fList); while (iter.next()) { - iter->clipPath(path, op, doAA); + iter->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle); } - return this->INHERITED::clipPath(path, op, doAA); + this->INHERITED::onClipPath(path, op, edgeStyle); } -bool SkNWayCanvas::clipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { +void SkNWayCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { Iter iter(fList); while (iter.next()) { iter->clipRegion(deviceRgn, op); } - return this->INHERITED::clipRegion(deviceRgn, op); + this->INHERITED::onClipRegion(deviceRgn, op); } void SkNWayCanvas::clear(SkColor color) { @@ -205,6 +209,14 @@ void SkNWayCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { } } +void SkNWayCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + Iter iter(fList); + while (iter.next()) { + iter->drawDRRect(outer, inner, paint); + } +} + void SkNWayCanvas::drawPath(const SkPath& path, const SkPaint& paint) { Iter iter(fList); while (iter.next()) { diff --git a/gfx/skia/trunk/src/utils/SkNoSaveLayerCanvas.h b/gfx/skia/trunk/src/utils/SkNoSaveLayerCanvas.h deleted file mode 100644 index 58d28b40b13e..000000000000 --- a/gfx/skia/trunk/src/utils/SkNoSaveLayerCanvas.h +++ /dev/null @@ -1,60 +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 SkNoSaveLayerCanvas_DEFINED -#define SkNoSaveLayerCanvas_DEFINED - -#include "SkCanvas.h" -#include "SkRRect.h" - -// The NoSaveLayerCanvas is used to play back SkPictures when the saveLayer -// functionality isn't required (e.g., during analysis of the draw calls). -// It also simplifies the clipping calls to only use rectangles. -class SkNoSaveLayerCanvas : public SkCanvas { -public: - SkNoSaveLayerCanvas(SkBaseDevice* device) : INHERITED(device) {} - - // turn saveLayer() into save() for speed, should not affect correctness. - virtual int saveLayer(const SkRect* bounds, - const SkPaint* paint, - SaveFlags flags) SK_OVERRIDE { - - // Like SkPictureRecord, we don't want to create layers, but we do need - // to respect the save and (possibly) its rect-clip. - int count = this->INHERITED::save(flags); - if (NULL != bounds) { - this->INHERITED::clipRectBounds(bounds, flags, NULL); - } - return count; - } - - // disable aa for speed - virtual bool clipRect(const SkRect& rect, - SkRegion::Op op, - bool doAA) SK_OVERRIDE { - return this->INHERITED::clipRect(rect, op, false); - } - - // for speed, just respect the bounds, and disable AA. May give us a few - // false positives and negatives. - virtual bool clipPath(const SkPath& path, - SkRegion::Op op, - bool doAA) SK_OVERRIDE { - return this->updateClipConservativelyUsingBounds(path.getBounds(), op, - path.isInverseFillType()); - } - virtual bool clipRRect(const SkRRect& rrect, - SkRegion::Op op, - bool doAA) SK_OVERRIDE { - return this->updateClipConservativelyUsingBounds(rrect.getBounds(), op, false); - } - -private: - typedef SkCanvas INHERITED; -}; - -#endif // SkNoSaveLayerCanvas_DEFINED diff --git a/gfx/skia/trunk/src/utils/SkPictureUtils.cpp b/gfx/skia/trunk/src/utils/SkPictureUtils.cpp index 92d0487c54cc..23d7afd7a210 100644 --- a/gfx/skia/trunk/src/utils/SkPictureUtils.cpp +++ b/gfx/skia/trunk/src/utils/SkPictureUtils.cpp @@ -54,11 +54,10 @@ public: GatherPixelRefDevice(int width, int height, PixelRefSet* prset) { fSize.set(width, height); - fEmptyBitmap.setConfig(SkBitmap::kNo_Config, width, height); + fEmptyBitmap.setConfig(SkImageInfo::MakeUnknown(width, height)); fPRSet = prset; } - virtual uint32_t getDeviceCapabilities() SK_OVERRIDE { return 0; } virtual int width() const SK_OVERRIDE { return fSize.width(); } virtual int height() const SK_OVERRIDE { return fSize.height(); } virtual bool isOpaque() const SK_OVERRIDE { return false; } @@ -77,7 +76,7 @@ public: virtual void unlockPixels() SK_OVERRIDE { nothing_to_do(); } virtual bool allowImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } virtual bool canHandleImageFilter(const SkImageFilter*) SK_OVERRIDE { return false; } - virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkMatrix&, + virtual bool filterImage(const SkImageFilter*, const SkBitmap&, const SkImageFilter::Context&, SkBitmap* result, SkIPoint* offset) SK_OVERRIDE { return false; } @@ -85,10 +84,13 @@ public: virtual void clear(SkColor color) SK_OVERRIDE { nothing_to_do(); } + +#ifdef SK_SUPPORT_LEGACY_WRITEPIXELSCONFIG virtual void writePixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) SK_OVERRIDE { not_supported(); } +#endif virtual void drawPaint(const SkDraw&, const SkPaint& paint) SK_OVERRIDE { this->addBitmapFromPaint(paint); @@ -172,13 +174,10 @@ protected: virtual void replaceBitmapBackendForRasterSurface(const SkBitmap&) SK_OVERRIDE { not_supported(); } - virtual SkBaseDevice* onCreateCompatibleDevice(SkBitmap::Config config, - int width, int height, - bool isOpaque, - Usage usage) SK_OVERRIDE { + virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info, Usage usage) SK_OVERRIDE { // we expect to only get called via savelayer, in which case it is fine. SkASSERT(kSaveLayer_Usage == usage); - return SkNEW_ARGS(GatherPixelRefDevice, (width, height, fPRSet)); + return SkNEW_ARGS(GatherPixelRefDevice, (info.width(), info.height(), fPRSet)); } virtual void flush() SK_OVERRIDE {} diff --git a/gfx/skia/trunk/src/utils/SkProxyCanvas.cpp b/gfx/skia/trunk/src/utils/SkProxyCanvas.cpp index f530313b162d..037ddd0df685 100644 --- a/gfx/skia/trunk/src/utils/SkProxyCanvas.cpp +++ b/gfx/skia/trunk/src/utils/SkProxyCanvas.cpp @@ -21,57 +21,68 @@ void SkProxyCanvas::setProxy(SkCanvas* proxy) { ///////////////////////////////// Overrides /////////// -int SkProxyCanvas::save(SaveFlags flags) { - return fProxy->save(flags); +void SkProxyCanvas::willSave(SaveFlags flags) { + fProxy->save(flags); + this->INHERITED::willSave(flags); } -int SkProxyCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { - return fProxy->saveLayer(bounds, paint, flags); +SkCanvas::SaveLayerStrategy SkProxyCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags) { + fProxy->saveLayer(bounds, paint, flags); + this->INHERITED::willSaveLayer(bounds, paint, flags); + // No need for a layer. + return kNoLayer_SaveLayerStrategy; } -void SkProxyCanvas::restore() { +void SkProxyCanvas::willRestore() { fProxy->restore(); + this->INHERITED::willRestore(); } -bool SkProxyCanvas::translate(SkScalar dx, SkScalar dy) { - return fProxy->translate(dx, dy); +void SkProxyCanvas::didTranslate(SkScalar dx, SkScalar dy) { + fProxy->translate(dx, dy); + this->INHERITED::didTranslate(dx, dy); } -bool SkProxyCanvas::scale(SkScalar sx, SkScalar sy) { - return fProxy->scale(sx, sy); +void SkProxyCanvas::didScale(SkScalar sx, SkScalar sy) { + fProxy->scale(sx, sy); + this->INHERITED::didScale(sx, sy); } -bool SkProxyCanvas::rotate(SkScalar degrees) { - return fProxy->rotate(degrees); +void SkProxyCanvas::didRotate(SkScalar degrees) { + fProxy->rotate(degrees); + this->INHERITED::didRotate(degrees); } -bool SkProxyCanvas::skew(SkScalar sx, SkScalar sy) { - return fProxy->skew(sx, sy); +void SkProxyCanvas::didSkew(SkScalar sx, SkScalar sy) { + fProxy->skew(sx, sy); + this->INHERITED::didSkew(sx, sy); } -bool SkProxyCanvas::concat(const SkMatrix& matrix) { - return fProxy->concat(matrix); +void SkProxyCanvas::didConcat(const SkMatrix& matrix) { + fProxy->concat(matrix); + this->INHERITED::didConcat(matrix); } -void SkProxyCanvas::setMatrix(const SkMatrix& matrix) { +void SkProxyCanvas::didSetMatrix(const SkMatrix& matrix) { fProxy->setMatrix(matrix); + this->INHERITED::didSetMatrix(matrix); } -bool SkProxyCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { - return fProxy->clipRect(rect, op, doAA); +void SkProxyCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + fProxy->clipRect(rect, op, kSoft_ClipEdgeStyle == edgeStyle); } -bool SkProxyCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { - return fProxy->clipRRect(rrect, op, doAA); +void SkProxyCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + fProxy->clipRRect(rrect, op, kSoft_ClipEdgeStyle == edgeStyle); } -bool SkProxyCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { - return fProxy->clipPath(path, op, doAA); +void SkProxyCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + fProxy->clipPath(path, op, kSoft_ClipEdgeStyle == edgeStyle); } -bool SkProxyCanvas::clipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { - return fProxy->clipRegion(deviceRgn, op); +void SkProxyCanvas::onClipRegion(const SkRegion& deviceRgn, SkRegion::Op op) { + fProxy->clipRegion(deviceRgn, op); } void SkProxyCanvas::drawPaint(const SkPaint& paint) { @@ -95,6 +106,11 @@ void SkProxyCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { fProxy->drawRRect(rrect, paint); } +void SkProxyCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + fProxy->drawDRRect(outer, inner, paint); +} + void SkProxyCanvas::drawPath(const SkPath& path, const SkPaint& paint) { fProxy->drawPath(path, paint); } diff --git a/gfx/skia/trunk/src/utils/SkSHA1.h b/gfx/skia/trunk/src/utils/SkSHA1.h index cf2cb8c6796b..df8b9bf1b68c 100644 --- a/gfx/skia/trunk/src/utils/SkSHA1.h +++ b/gfx/skia/trunk/src/utils/SkSHA1.h @@ -29,6 +29,8 @@ public: return true; } + virtual size_t bytesWritten() const SK_OVERRIDE { return SkToSizeT(this->byteCount); } + /** Processes input, adding it to the digest. Calling this after finish is undefined. */ void update(const uint8_t* input, size_t length); diff --git a/gfx/skia/trunk/src/utils/SkThreadPool.cpp b/gfx/skia/trunk/src/utils/SkThreadPool.cpp deleted file mode 100644 index 125a5d9b6ad7..000000000000 --- a/gfx/skia/trunk/src/utils/SkThreadPool.cpp +++ /dev/null @@ -1,127 +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. - */ - -#include "SkRunnable.h" -#include "SkThreadPool.h" -#include "SkThreadUtils.h" -#include "SkTypes.h" - -#if defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID) -#include -#endif - -// Returns the number of cores on this machine. -static int num_cores() { -#if defined(SK_BUILD_FOR_WIN32) - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - return sysinfo.dwNumberOfProcessors; -#elif defined(SK_BUILD_FOR_UNIX) || defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_ANDROID) - return sysconf(_SC_NPROCESSORS_ONLN); -#else - return 1; -#endif -} - -SkThreadPool::SkThreadPool(int count) -: fState(kRunning_State), fBusyThreads(0) { - if (count < 0) count = num_cores(); - // Create count threads, all running SkThreadPool::Loop. - for (int i = 0; i < count; i++) { - SkThread* thread = SkNEW_ARGS(SkThread, (&SkThreadPool::Loop, this)); - *fThreads.append() = thread; - thread->start(); - } -} - -SkThreadPool::~SkThreadPool() { - if (kRunning_State == fState) { - this->wait(); - } -} - -void SkThreadPool::wait() { - fReady.lock(); - fState = kWaiting_State; - fReady.broadcast(); - fReady.unlock(); - - // Wait for all threads to stop. - for (int i = 0; i < fThreads.count(); i++) { - fThreads[i]->join(); - SkDELETE(fThreads[i]); - } - SkASSERT(fQueue.isEmpty()); -} - -/*static*/ void SkThreadPool::Loop(void* arg) { - // The SkThreadPool passes itself as arg to each thread as they're created. - SkThreadPool* pool = static_cast(arg); - - while (true) { - // We have to be holding the lock to read the queue and to call wait. - pool->fReady.lock(); - while(pool->fQueue.isEmpty()) { - // Does the client want to stop and are all the threads ready to stop? - // If so, we move into the halting state, and whack all the threads so they notice. - if (kWaiting_State == pool->fState && pool->fBusyThreads == 0) { - pool->fState = kHalting_State; - pool->fReady.broadcast(); - } - // Any time we find ourselves in the halting state, it's quitting time. - if (kHalting_State == pool->fState) { - pool->fReady.unlock(); - return; - } - // wait yields the lock while waiting, but will have it again when awoken. - pool->fReady.wait(); - } - // We've got the lock back here, no matter if we ran wait or not. - - // The queue is not empty, so we have something to run. Claim it. - LinkedRunnable* r = pool->fQueue.tail(); - - pool->fQueue.remove(r); - - // Having claimed our SkRunnable, we now give up the lock while we run it. - // Otherwise, we'd only ever do work on one thread at a time, which rather - // defeats the point of this code. - pool->fBusyThreads++; - pool->fReady.unlock(); - - // OK, now really do the work. - r->fRunnable->run(); - SkDELETE(r); - - // Let everyone know we're not busy. - pool->fReady.lock(); - pool->fBusyThreads--; - pool->fReady.unlock(); - } - - SkASSERT(false); // Unreachable. The only exit happens when pool->fState is kHalting_State. -} - -void SkThreadPool::add(SkRunnable* r) { - if (NULL == r) { - return; - } - - // If we don't have any threads, obligingly just run the thing now. - if (fThreads.isEmpty()) { - return r->run(); - } - - // We have some threads. Queue it up! - fReady.lock(); - SkASSERT(fState != kHalting_State); // Shouldn't be able to add work when we're halting. - LinkedRunnable* linkedRunnable = SkNEW(LinkedRunnable); - linkedRunnable->fRunnable = r; - fQueue.addToHead(linkedRunnable); - fReady.signal(); - fReady.unlock(); -} diff --git a/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.cpp b/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.cpp index 32a657095462..88bee505d80c 100644 --- a/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.cpp +++ b/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.cpp @@ -19,6 +19,7 @@ SkDebugCanvas::SkDebugCanvas(int width, int height) , fWidth(width) , fHeight(height) , fFilter(false) + , fMegaVizMode(false) , fIndex(0) , fOverdrawViz(false) , fOverdrawFilter(NULL) @@ -43,7 +44,8 @@ SkDebugCanvas::SkDebugCanvas(int width, int height) large.roundOut(&largeIRect); SkASSERT(!largeIRect.isEmpty()); #endif - INHERITED::clipRect(large, SkRegion::kReplace_Op, false); + // call the base class' version to avoid adding a draw command + this->INHERITED::onClipRect(large, SkRegion::kReplace_Op, kHard_ClipEdgeStyle); } SkDebugCanvas::~SkDebugCanvas() { @@ -118,7 +120,7 @@ static SkPMColor OverdrawXferModeProc(SkPMColor src, SkPMColor dst) { class SkOverdrawFilter : public SkDrawFilter { public: SkOverdrawFilter() { - fXferMode = new SkProcXfermode(OverdrawXferModeProc); + fXferMode = SkProcXfermode::Create(OverdrawXferModeProc); } virtual ~SkOverdrawFilter() { @@ -160,6 +162,71 @@ private: typedef SkDrawFilter INHERITED; }; +class SkDebugClipVisitor : public SkCanvas::ClipVisitor { +public: + SkDebugClipVisitor(SkCanvas* canvas) : fCanvas(canvas) {} + + virtual void clipRect(const SkRect& r, SkRegion::Op, bool doAA) SK_OVERRIDE { + SkPaint p; + p.setColor(SK_ColorRED); + p.setStyle(SkPaint::kStroke_Style); + p.setAntiAlias(doAA); + fCanvas->drawRect(r, p); + } + virtual void clipRRect(const SkRRect& rr, SkRegion::Op, bool doAA) SK_OVERRIDE { + SkPaint p; + p.setColor(SK_ColorGREEN); + p.setStyle(SkPaint::kStroke_Style); + p.setAntiAlias(doAA); + fCanvas->drawRRect(rr, p); + } + virtual void clipPath(const SkPath& path, SkRegion::Op, bool doAA) SK_OVERRIDE { + SkPaint p; + p.setColor(SK_ColorBLUE); + p.setStyle(SkPaint::kStroke_Style); + p.setAntiAlias(doAA); + fCanvas->drawPath(path, p); + } + +protected: + SkCanvas* fCanvas; + +private: + typedef SkCanvas::ClipVisitor INHERITED; +}; + +// set up the saveLayer commands so that the active ones +// return true in their 'active' method +void SkDebugCanvas::markActiveCommands(int index) { + fActiveLayers.rewind(); + fActiveCulls.rewind(); + + for (int i = 0; i < fCommandVector.count(); ++i) { + fCommandVector[i]->setActive(false); + } + + for (int i = 0; i < index; ++i) { + SkDrawCommand::Action result = fCommandVector[i]->action(); + if (SkDrawCommand::kPushLayer_Action == result) { + fActiveLayers.push(fCommandVector[i]); + } else if (SkDrawCommand::kPopLayer_Action == result) { + fActiveLayers.pop(); + } else if (SkDrawCommand::kPushCull_Action == result) { + fActiveCulls.push(fCommandVector[i]); + } else if (SkDrawCommand::kPopCull_Action == result) { + fActiveCulls.pop(); + } + } + + for (int i = 0; i < fActiveLayers.count(); ++i) { + fActiveLayers[i]->setActive(true); + } + + for (int i = 0; i < fActiveCulls.count(); ++i) { + fActiveCulls[i]->setActive(true); + } +} + void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) { SkASSERT(!fCommandVector.isEmpty()); SkASSERT(index < fCommandVector.count()); @@ -170,7 +237,7 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) { // and restores. // The visibility filter also requires a full re-draw - otherwise we can // end up drawing the filter repeatedly. - if (fIndex < index && !fFilter) { + if (fIndex < index && !fFilter && !fMegaVizMode) { i = fIndex + 1; } else { for (int j = 0; j < fOutstandingSaveCount; j++) { @@ -209,6 +276,10 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) { canvas->setDrawFilter(NULL); } + if (fMegaVizMode) { + this->markActiveCommands(index); + } + for (; i <= index; i++) { if (i == index && fFilter) { SkPaint p; @@ -225,12 +296,41 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) { } if (fCommandVector[i]->isVisible()) { - fCommandVector[i]->execute(canvas); + if (fMegaVizMode && fCommandVector[i]->active()) { + // "active" commands execute their visualization behaviors: + // All active saveLayers get replaced with saves so all draws go to the + // visible canvas. + // All active culls draw their cull box + fCommandVector[i]->vizExecute(canvas); + } else { + fCommandVector[i]->execute(canvas); + } + fCommandVector[i]->trackSaveState(&fOutstandingSaveCount); } } + + if (fMegaVizMode) { + SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight)); + r.outset(SK_Scalar1, SK_Scalar1); + + canvas->save(); + // nuke the CTM + canvas->setMatrix(SkMatrix::I()); + // turn off clipping + canvas->clipRect(r, SkRegion::kReplace_Op); + + // visualize existing clips + SkDebugClipVisitor visitor(canvas); + + canvas->replayClips(&visitor); + + canvas->restore(); + } fMatrix = canvas->getTotalMatrix(); - fClip = canvas->getTotalClip().getBounds(); + if (!canvas->getClipDeviceBounds(&fClip)) { + fClip.setEmpty(); + } fIndex = index; } @@ -280,10 +380,6 @@ SkTArray* SkDebugCanvas::getDrawCommandsAsStrings() const { return commandString; } -void SkDebugCanvas::toggleFilter(bool toggle) { - fFilter = toggle; -} - void SkDebugCanvas::overrideTexFiltering(bool overrideTexFiltering, SkPaint::FilterLevel level) { if (NULL == fTexOverrideFilter) { fTexOverrideFilter = new SkTexOverrideFilter; @@ -297,29 +393,25 @@ void SkDebugCanvas::clear(SkColor color) { addDrawCommand(new SkClearCommand(color)); } -bool SkDebugCanvas::clipPath(const SkPath& path, SkRegion::Op op, bool doAA) { - addDrawCommand(new SkClipPathCommand(path, op, doAA)); - return true; +void SkDebugCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + this->addDrawCommand(new SkClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle)); } -bool SkDebugCanvas::clipRect(const SkRect& rect, SkRegion::Op op, bool doAA) { - addDrawCommand(new SkClipRectCommand(rect, op, doAA)); - return true; +void SkDebugCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + this->addDrawCommand(new SkClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle)); } -bool SkDebugCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op, bool doAA) { - addDrawCommand(new SkClipRRectCommand(rrect, op, doAA)); - return true; +void SkDebugCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) { + this->addDrawCommand(new SkClipRRectCommand(rrect, op, kSoft_ClipEdgeStyle == edgeStyle)); } -bool SkDebugCanvas::clipRegion(const SkRegion& region, SkRegion::Op op) { - addDrawCommand(new SkClipRegionCommand(region, op)); - return true; +void SkDebugCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op) { + this->addDrawCommand(new SkClipRegionCommand(region, op)); } -bool SkDebugCanvas::concat(const SkMatrix& matrix) { +void SkDebugCanvas::didConcat(const SkMatrix& matrix) { addDrawCommand(new SkConcatCommand(matrix)); - return true; + this->INHERITED::didConcat(matrix); } void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left, @@ -401,6 +493,11 @@ void SkDebugCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) { addDrawCommand(new SkDrawRRectCommand(rrect, paint)); } +void SkDebugCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint) { + this->addDrawCommand(new SkDrawDRRectCommand(outer, inner, paint)); +} + void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top, const SkPaint* paint = NULL) { addDrawCommand(new SkDrawSpriteCommand(bitmap, left, top, paint)); @@ -425,43 +522,55 @@ void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount, texs, colors, NULL, indices, indexCount, paint)); } -void SkDebugCanvas::restore() { - addDrawCommand(new SkRestoreCommand()); +void SkDebugCanvas::onPushCull(const SkRect& cullRect) { + this->addDrawCommand(new SkPushCullCommand(cullRect)); } -bool SkDebugCanvas::rotate(SkScalar degrees) { +void SkDebugCanvas::onPopCull() { + this->addDrawCommand(new SkPopCullCommand()); +} + +void SkDebugCanvas::willRestore() { + this->addDrawCommand(new SkRestoreCommand()); + this->INHERITED::willRestore(); +} + +void SkDebugCanvas::didRotate(SkScalar degrees) { addDrawCommand(new SkRotateCommand(degrees)); - return true; + this->INHERITED::didRotate(degrees); } -int SkDebugCanvas::save(SaveFlags flags) { - addDrawCommand(new SkSaveCommand(flags)); - return true; +void SkDebugCanvas::willSave(SaveFlags flags) { + this->addDrawCommand(new SkSaveCommand(flags)); + this->INHERITED::willSave(flags); } -int SkDebugCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint, - SaveFlags flags) { - addDrawCommand(new SkSaveLayerCommand(bounds, paint, flags)); - return true; +SkCanvas::SaveLayerStrategy SkDebugCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint, + SaveFlags flags) { + this->addDrawCommand(new SkSaveLayerCommand(bounds, paint, flags)); + this->INHERITED::willSaveLayer(bounds, paint, flags); + // No need for a full layer. + return kNoLayer_SaveLayerStrategy; } -bool SkDebugCanvas::scale(SkScalar sx, SkScalar sy) { +void SkDebugCanvas::didScale(SkScalar sx, SkScalar sy) { addDrawCommand(new SkScaleCommand(sx, sy)); - return true; + this->INHERITED::didScale(sx, sy); } -void SkDebugCanvas::setMatrix(const SkMatrix& matrix) { +void SkDebugCanvas::didSetMatrix(const SkMatrix& matrix) { addDrawCommand(new SkSetMatrixCommand(matrix)); + this->INHERITED::didSetMatrix(matrix); } -bool SkDebugCanvas::skew(SkScalar sx, SkScalar sy) { +void SkDebugCanvas::didSkew(SkScalar sx, SkScalar sy) { addDrawCommand(new SkSkewCommand(sx, sy)); - return true; + this->INHERITED::didSkew(sx, sy); } -bool SkDebugCanvas::translate(SkScalar dx, SkScalar dy) { +void SkDebugCanvas::didTranslate(SkScalar dx, SkScalar dy) { addDrawCommand(new SkTranslateCommand(dx, dy)); - return true; + this->INHERITED::didTranslate(dx, dy); } void SkDebugCanvas::toggleCommand(int index, bool toggle) { diff --git a/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.h b/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.h index 262619e7f19f..1191a7611039 100644 --- a/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.h +++ b/gfx/skia/trunk/src/utils/debugger/SkDebugCanvas.h @@ -23,7 +23,9 @@ public: SkDebugCanvas(int width, int height); virtual ~SkDebugCanvas(); - void toggleFilter(bool toggle); + void toggleFilter(bool toggle) { fFilter = toggle; } + + void setMegaVizMode(bool megaVizMode) { fMegaVizMode = megaVizMode; } /** * Enable or disable overdraw visualization @@ -143,18 +145,6 @@ public: virtual void clear(SkColor) SK_OVERRIDE; - virtual bool clipPath(const SkPath&, SkRegion::Op, bool) SK_OVERRIDE; - - virtual bool clipRect(const SkRect&, SkRegion::Op, bool) SK_OVERRIDE; - - virtual bool clipRRect(const SkRRect& rrect, - SkRegion::Op op = SkRegion::kIntersect_Op, - bool doAntiAlias = false) SK_OVERRIDE; - - virtual bool clipRegion(const SkRegion& region, SkRegion::Op op) SK_OVERRIDE; - - virtual bool concat(const SkMatrix& matrix) SK_OVERRIDE; - virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) SK_OVERRIDE; @@ -214,30 +204,60 @@ public: const uint16_t indices[], int indexCount, const SkPaint&) SK_OVERRIDE; - virtual void restore() SK_OVERRIDE; - - virtual bool rotate(SkScalar degrees) SK_OVERRIDE; - - virtual int save(SaveFlags) SK_OVERRIDE; - - virtual int saveLayer(const SkRect* bounds, const SkPaint*, SaveFlags) SK_OVERRIDE; - - virtual bool scale(SkScalar sx, SkScalar sy) SK_OVERRIDE; - - virtual void setMatrix(const SkMatrix& matrix) SK_OVERRIDE; - - virtual bool skew(SkScalar sx, SkScalar sy) SK_OVERRIDE; - - virtual bool translate(SkScalar dx, SkScalar dy) SK_OVERRIDE; - static const int kVizImageHeight = 256; static const int kVizImageWidth = 256; + virtual bool isClipEmpty() const SK_OVERRIDE { return false; } + virtual bool isClipRect() const SK_OVERRIDE { return true; } +#ifdef SK_SUPPORT_LEGACY_GETCLIPTYPE + virtual ClipType getClipType() const SK_OVERRIDE { + return kRect_ClipType; + } +#endif + virtual bool getClipBounds(SkRect* bounds) const SK_OVERRIDE { + if (NULL != bounds) { + bounds->setXYWH(0, 0, + SkIntToScalar(this->imageInfo().fWidth), + SkIntToScalar(this->imageInfo().fHeight)); + } + return true; + } + virtual bool getClipDeviceBounds(SkIRect* bounds) const SK_OVERRIDE { + if (NULL != bounds) { + bounds->setLargest(); + } + return true; + } + +protected: + virtual void willSave(SaveFlags) SK_OVERRIDE; + virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE; + virtual void willRestore() SK_OVERRIDE; + + virtual void didTranslate(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didScale(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didRotate(SkScalar) SK_OVERRIDE; + virtual void didSkew(SkScalar, SkScalar) SK_OVERRIDE; + virtual void didConcat(const SkMatrix&) SK_OVERRIDE; + virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE; + + virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE; + virtual void onPushCull(const SkRect& cullRect) SK_OVERRIDE; + virtual void onPopCull() SK_OVERRIDE; + + virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE; + virtual void onClipRegion(const SkRegion& region, SkRegion::Op) SK_OVERRIDE; + + void markActiveCommands(int index); + private: SkTDArray fCommandVector; int fWidth; int fHeight; bool fFilter; + bool fMegaVizMode; int fIndex; SkMatrix fUserMatrix; SkMatrix fMatrix; @@ -257,6 +277,18 @@ private: */ int fOutstandingSaveCount; + /** + The active saveLayer commands at a given point in the renderering. + Only used when "mega" visualization is enabled. + */ + SkTDArray fActiveLayers; + + /** + The active cull commands at a given point in the rendering. + Only used when "mega" visualization is enabled. + */ + SkTDArray fActiveCulls; + /** Adds the command to the classes vector of commands. @param command The draw command for execution diff --git a/gfx/skia/trunk/src/utils/debugger/SkDrawCommand.cpp b/gfx/skia/trunk/src/utils/debugger/SkDrawCommand.cpp index db041cdce6c2..7e6b22b7c718 100644 --- a/gfx/skia/trunk/src/utils/debugger/SkDrawCommand.cpp +++ b/gfx/skia/trunk/src/utils/debugger/SkDrawCommand.cpp @@ -64,6 +64,9 @@ const char* SkDrawCommand::GetCommandString(DrawType type) { case BEGIN_COMMENT_GROUP: return "BeginCommentGroup"; case COMMENT: return "Comment"; case END_COMMENT_GROUP: return "EndCommentGroup"; + case DRAW_DRRECT: return "Draw DRRect"; + case PUSH_CULL: return "PushCull"; + case POP_CULL: return "PopCull"; default: SkDebugf("DrawType error 0x%08x\n", type); SkASSERT(0); @@ -170,6 +173,22 @@ void render_rrect(SkCanvas* canvas, const SkRRect& rrect) { canvas->restore(); } +void render_drrect(SkCanvas* canvas, const SkRRect& outer, const SkRRect& inner) { + canvas->clear(0xFFFFFFFF); + canvas->save(); + + const SkRect& bounds = outer.getBounds(); + + xlate_and_scale_to_bounds(canvas, bounds); + + SkPaint p; + p.setColor(SK_ColorBLACK); + p.setStyle(SkPaint::kStroke_Style); + + canvas->drawDRRect(outer, inner, p); + canvas->restore(); +} + }; @@ -634,6 +653,28 @@ bool SkDrawRRectCommand::render(SkCanvas* canvas) const { return true; } +SkDrawDRRectCommand::SkDrawDRRectCommand(const SkRRect& outer, + const SkRRect& inner, + const SkPaint& paint) { + fOuter = outer; + fInner = inner; + fPaint = paint; + fDrawType = DRAW_DRRECT; + + fInfo.push(SkObjectParser::RRectToString(outer)); + fInfo.push(SkObjectParser::RRectToString(inner)); + fInfo.push(SkObjectParser::PaintToString(paint)); +} + +void SkDrawDRRectCommand::execute(SkCanvas* canvas) { + canvas->drawDRRect(fOuter, fInner, fPaint); +} + +bool SkDrawDRRectCommand::render(SkCanvas* canvas) const { + render_drrect(canvas, fOuter, fInner); + return true; +} + SkDrawSpriteCommand::SkDrawSpriteCommand(const SkBitmap& bitmap, int left, int top, const SkPaint* paint) { fBitmap = bitmap; @@ -844,6 +885,10 @@ void SkSaveLayerCommand::execute(SkCanvas* canvas) { fFlags); } +void SkSaveLayerCommand::vizExecute(SkCanvas* canvas) { + canvas->save(); +} + void SkSaveLayerCommand::trackSaveState(int* state) { (*state)++; } @@ -897,3 +942,30 @@ SkTranslateCommand::SkTranslateCommand(SkScalar dx, SkScalar dy) { void SkTranslateCommand::execute(SkCanvas* canvas) { canvas->translate(fDx, fDy); } + +SkPushCullCommand::SkPushCullCommand(const SkRect& cullRect) + : fCullRect(cullRect) { + fDrawType = PUSH_CULL; + fInfo.push(SkObjectParser::RectToString(cullRect)); +} + +void SkPushCullCommand::execute(SkCanvas* canvas) { + canvas->pushCull(fCullRect); +} + +void SkPushCullCommand::vizExecute(SkCanvas* canvas) { + canvas->pushCull(fCullRect); + + SkPaint p; + p.setColor(SK_ColorCYAN); + p.setStyle(SkPaint::kStroke_Style); + canvas->drawRect(fCullRect, p); +} + +SkPopCullCommand::SkPopCullCommand() { + fDrawType = POP_CULL; +} + +void SkPopCullCommand::execute(SkCanvas* canvas) { + canvas->popCull(); +} diff --git a/gfx/skia/trunk/src/utils/debugger/SkDrawCommand.h b/gfx/skia/trunk/src/utils/debugger/SkDrawCommand.h index b78dc9c3c4df..3c40393fe7ae 100644 --- a/gfx/skia/trunk/src/utils/debugger/SkDrawCommand.h +++ b/gfx/skia/trunk/src/utils/debugger/SkDrawCommand.h @@ -36,10 +36,34 @@ public: } SkTDArray* Info() {return &fInfo; }; - virtual void execute(SkCanvas* canvas)=0; + virtual void execute(SkCanvas* canvas) = 0; + virtual void vizExecute(SkCanvas* canvas) { }; /** Does nothing by default, but used by save() and restore()-type - subclassse to track unresolved save() calls. */ + subclasses to track unresolved save() calls. */ virtual void trackSaveState(int* state) { }; + + // The next "active" system is only used by save, saveLayer, restore, + // pushCull and popCull. It is used in two ways: + // To determine which saveLayers are currently active (at a + // given point in the rendering). + // save just return a kPushLayer action but don't track active state + // restore just return a kPopLayer action + // saveLayers return kPushLayer but also track the active state + // To determine which culls are currently active (at a given point) + // in the rendering). + // pushCull returns a kPushCull action + // popCull returns a kPopCull action + enum Action { + kNone_Action, + kPopLayer_Action, + kPushLayer_Action, + kPopCull_Action, + kPushCull_Action + }; + virtual Action action() const { return kNone_Action; } + virtual void setActive(bool active) {} + virtual bool active() const { return false; } + DrawType getType() { return fDrawType; }; virtual bool render(SkCanvas* canvas) const { return false; } @@ -59,6 +83,7 @@ public: SkRestoreCommand(); virtual void execute(SkCanvas* canvas) SK_OVERRIDE; virtual void trackSaveState(int* state) SK_OVERRIDE; + virtual Action action() const SK_OVERRIDE { return kPopLayer_Action; } private: typedef SkDrawCommand INHERITED; @@ -429,6 +454,20 @@ private: typedef SkDrawCommand INHERITED; }; +class SkDrawDRRectCommand : public SkDrawCommand { +public: + SkDrawDRRectCommand(const SkRRect& outer, const SkRRect& inner, + const SkPaint& paint); + virtual void execute(SkCanvas* canvas) SK_OVERRIDE; + virtual bool render(SkCanvas* canvas) const SK_OVERRIDE; +private: + SkRRect fOuter; + SkRRect fInner; + SkPaint fPaint; + + typedef SkDrawCommand INHERITED; +}; + class SkDrawSpriteCommand : public SkDrawCommand { public: SkDrawSpriteCommand(const SkBitmap& bitmap, int left, int top, const SkPaint* paint); @@ -482,6 +521,7 @@ public: SkSaveCommand(SkCanvas::SaveFlags flags); virtual void execute(SkCanvas* canvas) SK_OVERRIDE; virtual void trackSaveState(int* state) SK_OVERRIDE; + virtual Action action() const SK_OVERRIDE { return kPushLayer_Action; } private: SkCanvas::SaveFlags fFlags; @@ -493,7 +533,11 @@ public: SkSaveLayerCommand(const SkRect* bounds, const SkPaint* paint, SkCanvas::SaveFlags flags); virtual void execute(SkCanvas* canvas) SK_OVERRIDE; + virtual void vizExecute(SkCanvas* canvas) SK_OVERRIDE; virtual void trackSaveState(int* state) SK_OVERRIDE; + virtual Action action() const SK_OVERRIDE{ return kPushLayer_Action; } + virtual void setActive(bool active) SK_OVERRIDE { fActive = active; } + virtual bool active() const SK_OVERRIDE { return fActive; } const SkPaint* paint() const { return fPaintPtr; } @@ -503,6 +547,8 @@ private: SkPaint* fPaintPtr; SkCanvas::SaveFlags fFlags; + bool fActive; + typedef SkDrawCommand INHERITED; }; @@ -557,4 +603,28 @@ private: typedef SkDrawCommand INHERITED; }; +class SkPushCullCommand : public SkDrawCommand { +public: + SkPushCullCommand(const SkRect&); + virtual void execute(SkCanvas*) SK_OVERRIDE; + virtual void vizExecute(SkCanvas* canvas) SK_OVERRIDE; + virtual Action action() const { return kPushCull_Action; } + virtual void setActive(bool active) { fActive = active; } + virtual bool active() const { return fActive; } +private: + SkRect fCullRect; + bool fActive; + + typedef SkDrawCommand INHERITED; +}; + +class SkPopCullCommand : public SkDrawCommand { +public: + SkPopCullCommand(); + virtual void execute(SkCanvas* canvas) SK_OVERRIDE; + virtual Action action() const { return kPopCull_Action; } +private: + typedef SkDrawCommand INHERITED; +}; + #endif diff --git a/gfx/skia/trunk/src/utils/debugger/SkObjectParser.cpp b/gfx/skia/trunk/src/utils/debugger/SkObjectParser.cpp index ebbd40018e79..028300c5a58a 100644 --- a/gfx/skia/trunk/src/utils/debugger/SkObjectParser.cpp +++ b/gfx/skia/trunk/src/utils/debugger/SkObjectParser.cpp @@ -94,7 +94,7 @@ SkString* SkObjectParser::IRectToString(const SkIRect& rect) { SkString* SkObjectParser::MatrixToString(const SkMatrix& matrix) { SkString* str = new SkString("SkMatrix: "); -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING matrix.toString(str); #endif return str; @@ -102,7 +102,7 @@ SkString* SkObjectParser::MatrixToString(const SkMatrix& matrix) { SkString* SkObjectParser::PaintToString(const SkPaint& paint) { SkString* str = new SkString; -#ifdef SK_DEVELOPER +#ifndef SK_IGNORE_TO_STRING paint.toString(str); #endif return str; diff --git a/gfx/skia/trunk/src/utils/mac/SkCreateCGImageRef.cpp b/gfx/skia/trunk/src/utils/mac/SkCreateCGImageRef.cpp index 1b52ba31a695..7687c3c7e4a0 100644 --- a/gfx/skia/trunk/src/utils/mac/SkCreateCGImageRef.cpp +++ b/gfx/skia/trunk/src/utils/mac/SkCreateCGImageRef.cpp @@ -22,13 +22,19 @@ static bool getBitmapInfo(const SkBitmap& bm, *upscaleTo32 = false; } - switch (bm.config()) { - case SkBitmap::kRGB_565_Config: + switch (bm.colorType()) { + case kRGB_565_SkColorType: +#if 0 + // doesn't see quite right. Are they thinking 1555? + *bitsPerComponent = 5; + *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone; + break; +#endif if (upscaleTo32) { *upscaleTo32 = true; } // fall through - case SkBitmap::kARGB_8888_Config: + case kPMColor_SkColorType: *bitsPerComponent = 8; #if SK_PMCOLOR_BYTE_ORDER(R,G,B,A) *info = kCGBitmapByteOrder32Big; @@ -60,14 +66,7 @@ This will probably not work. } #endif break; -#if 0 - case SkBitmap::kRGB_565_Config: - // doesn't see quite right. Are they thinking 1555? - *bitsPerComponent = 5; - *info = kCGBitmapByteOrder16Little | kCGImageAlphaNone; - break; -#endif - case SkBitmap::kARGB_4444_Config: + case kARGB_4444_SkColorType: *bitsPerComponent = 4; *info = kCGBitmapByteOrder16Little; if (bm.isOpaque()) { @@ -95,7 +94,7 @@ static SkBitmap* prepareForImageRef(const SkBitmap& bm, copy = new SkBitmap; // here we make a ceep copy of the pixels, since CG won't take our // 565 directly - bm.copyTo(copy, SkBitmap::kARGB_8888_Config); + bm.copyTo(copy, kPMColor_SkColorType); } else { copy = new SkBitmap(bm); } diff --git a/gfx/skia/trunk/src/views/SkWidgets.cpp b/gfx/skia/trunk/src/views/SkWidgets.cpp index e4547ec0e608..cde2b427389f 100644 --- a/gfx/skia/trunk/src/views/SkWidgets.cpp +++ b/gfx/skia/trunk/src/views/SkWidgets.cpp @@ -234,6 +234,7 @@ static const char* computeAnimatorState(int enabled, int focused, SkButtonWidget return "enabled"; } +#include "SkBlurMask.h" #include "SkBlurMaskFilter.h" #include "SkEmbossMaskFilter.h" @@ -255,7 +256,8 @@ static void create_emboss(SkPaint* paint, SkScalar radius, bool focus, bool pres if (focus) light.fDirection[2] += SK_Scalar1/4; - paint->setMaskFilter(new SkEmbossMaskFilter(light, radius))->unref(); + SkScalar sigma = SkBlurMask::ConvertRadiusToSigma(radius); + paint->setMaskFilter(new SkEmbossMaskFilter(sigma, light))->unref(); } void SkPushButtonWidget::onDraw(SkCanvas* canvas) @@ -507,7 +509,7 @@ bool SkBitmapView::getBitmap(SkBitmap* bitmap) const { if (bitmap) *bitmap = fBitmap; - return fBitmap.getConfig() != SkBitmap::kNo_Config; + return fBitmap.colorType() != kUnknown_SkColorType; } void SkBitmapView::setBitmap(const SkBitmap* bitmap, bool viewOwnsPixels) @@ -534,7 +536,7 @@ bool SkBitmapView::loadBitmapFromFile(const char path[]) void SkBitmapView::onDraw(SkCanvas* canvas) { - if (fBitmap.getConfig() != SkBitmap::kNo_Config && + if (fBitmap.colorType() != kUnknown_SkColorType && fBitmap.width() && fBitmap.height()) { SkAutoCanvasRestore restore(canvas, true); diff --git a/gfx/skia/trunk/src/views/SkWindow.cpp b/gfx/skia/trunk/src/views/SkWindow.cpp index 5451fca075ac..cca291a4e9e1 100644 --- a/gfx/skia/trunk/src/views/SkWindow.cpp +++ b/gfx/skia/trunk/src/views/SkWindow.cpp @@ -51,9 +51,9 @@ SkWindow::SkWindow() : fFocusView(NULL) { fWaitingOnInval = false; #ifdef SK_BUILD_FOR_WINCE - fConfig = SkBitmap::kRGB_565_Config; + fColorType = kRGB_565_SkColorType; #else - fConfig = SkBitmap::kARGB_8888_Config; + fColorType = kPMColor_SkColorType; #endif fMatrix.reset(); @@ -87,18 +87,18 @@ void SkWindow::postConcat(const SkMatrix& matrix) { this->setMatrix(m); } -void SkWindow::setConfig(SkBitmap::Config config) { - this->resize(fBitmap.width(), fBitmap.height(), config); +void SkWindow::setColorType(SkColorType ct) { + this->resize(fBitmap.width(), fBitmap.height(), ct); } -void SkWindow::resize(int width, int height, SkBitmap::Config config) { - if (config == SkBitmap::kNo_Config) - config = fConfig; +void SkWindow::resize(int width, int height, SkColorType ct) { + if (ct == kUnknown_SkColorType) + ct = fColorType; - if (width != fBitmap.width() || height != fBitmap.height() || config != fConfig) { - fConfig = config; - fBitmap.setConfig(config, width, height, 0, kOpaque_SkAlphaType); - fBitmap.allocPixels(); + if (width != fBitmap.width() || height != fBitmap.height() || ct != fColorType) { + fColorType = ct; + fBitmap.allocPixels(SkImageInfo::Make(width, height, + ct, kPremul_SkAlphaType)); this->setSize(SkIntToScalar(width), SkIntToScalar(height)); this->inval(NULL); diff --git a/gfx/skia/trunk/src/views/mac/SkNSView.mm b/gfx/skia/trunk/src/views/mac/SkNSView.mm index 209aecad792d..1014ffe04dca 100644 --- a/gfx/skia/trunk/src/views/mac/SkNSView.mm +++ b/gfx/skia/trunk/src/views/mac/SkNSView.mm @@ -57,7 +57,7 @@ SK_COMPILE_ASSERT(SK_SUPPORT_GPU, not_implemented_for_non_gpu_build); size = [self convertSizeToBacking:self.frame.size]; #endif fWind->resize((int) size.width, (int) size.height, - SkBitmap::kARGB_8888_Config); + kPMColor_SkColorType); } } From d72760e960aa3154f4da6dc2f7d716a914da57fc Mon Sep 17 00:00:00 2001 From: George Wright Date: Thu, 20 Mar 2014 14:06:36 -0400 Subject: [PATCH 017/101] [PATCH 2/6] Bug 985217 - Enable three legacy APIs in the new Skia r=snorp --- gfx/skia/trunk/include/config/SkUserConfig.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gfx/skia/trunk/include/config/SkUserConfig.h b/gfx/skia/trunk/include/config/SkUserConfig.h index d71adbe3b7c0..8259008416b6 100644 --- a/gfx/skia/trunk/include/config/SkUserConfig.h +++ b/gfx/skia/trunk/include/config/SkUserConfig.h @@ -204,3 +204,7 @@ #endif #define SK_ALLOW_STATIC_GLOBAL_INITIALIZERS 0 + +#define SK_SUPPORT_LEGACY_LAYERRASTERIZER_API 1 +#define SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG 1 +#define SK_SUPPORT_LEGACY_GETTOTALCLIP 1 From e7aad604925010efc42a2316e3b5f1f859a1b97a Mon Sep 17 00:00:00 2001 From: George Wright Date: Thu, 20 Mar 2014 14:07:36 -0400 Subject: [PATCH 018/101] [PATCH 3/6] Bug 985217 - Minor changes to gfx/2d for API changes in Skia r=snorp --- gfx/2d/DrawTargetSkia.cpp | 10 +++++----- gfx/2d/HelpersSkia.h | 25 ++++++++++++++++++++++--- gfx/2d/Scale.cpp | 2 +- gfx/2d/SourceSurfaceSkia.cpp | 4 ++-- 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/gfx/2d/DrawTargetSkia.cpp b/gfx/2d/DrawTargetSkia.cpp index 150fabdffe1e..70297a4b7afb 100644 --- a/gfx/2d/DrawTargetSkia.cpp +++ b/gfx/2d/DrawTargetSkia.cpp @@ -218,7 +218,7 @@ SetPaintPattern(SkPaint& aPaint, const Pattern& aPattern, TempBitmap& aTmpBitmap shader->setLocalMatrix(mat); SkSafeUnref(aPaint.setShader(shader)); if (pat.mFilter == Filter::POINT) { - aPaint.setFilterBitmap(false); + aPaint.setFilterLevel(SkPaint::kNone_FilterLevel); } break; } @@ -273,7 +273,7 @@ struct AutoPaintSetup { mPaint.setAlpha(U8CPU(aOptions.mAlpha*255.0)); mAlpha = aOptions.mAlpha; } - mPaint.setFilterBitmap(true); + mPaint.setFilterLevel(SkPaint::kLow_FilterLevel); } // TODO: Maybe add an operator overload to access this easier? @@ -314,7 +314,7 @@ DrawTargetSkia::DrawSurface(SourceSurface *aSurface, AutoPaintSetup paint(mCanvas.get(), aOptions); if (aSurfOptions.mFilter == Filter::POINT) { - paint.mPaint.setFilterBitmap(false); + paint.mPaint.setFilterLevel(SkPaint::kNone_FilterLevel); } mCanvas->drawBitmapRectToRect(bitmap.mBitmap, &sourceRect, destRect, &paint.mPaint); @@ -351,8 +351,8 @@ DrawTargetSkia::DrawSurfaceWithShadow(SourceSurface *aSurface, SkPaint paint; - SkImageFilter* filter = new SkDropShadowImageFilter(aOffset.x, aOffset.y, - aSigma, ColorToSkColor(aColor, 1.0)); + SkImageFilter* filter = SkDropShadowImageFilter::Create(aOffset.x, aOffset.y, + aSigma, ColorToSkColor(aColor, 1.0)); paint.setImageFilter(filter); paint.setXfermodeMode(GfxOpToSkiaOp(aOperator)); diff --git a/gfx/2d/HelpersSkia.h b/gfx/2d/HelpersSkia.h index 00375ec909e8..0e42d2d45d9f 100644 --- a/gfx/2d/HelpersSkia.h +++ b/gfx/2d/HelpersSkia.h @@ -38,6 +38,25 @@ GfxFormatToSkiaConfig(SurfaceFormat format) } } +static inline SkColorType +GfxFormatToSkiaColorType(SurfaceFormat format) +{ + switch (format) + { + case SurfaceFormat::B8G8R8A8: + return kBGRA_8888_SkColorType; + case SurfaceFormat::B8G8R8X8: + // We probably need to do something here. + return kBGRA_8888_SkColorType; + case SurfaceFormat::R5G6B5: + return kRGB_565_SkColorType; + case SurfaceFormat::A8: + return kAlpha_8_SkColorType; + default: + return kRGBA_8888_SkColorType; + } +} + static inline SurfaceFormat SkiaConfigToGfxFormat(SkBitmap::Config config) { @@ -144,9 +163,9 @@ StrokeOptionsToPaint(SkPaint& aPaint, const StrokeOptions &aOptions) pattern[i] = SkFloatToScalar(aOptions.mDashPattern[i % aOptions.mDashLength]); } - SkDashPathEffect* dash = new SkDashPathEffect(&pattern.front(), - dashCount, - SkFloatToScalar(aOptions.mDashOffset)); + SkDashPathEffect* dash = SkDashPathEffect::Create(&pattern.front(), + dashCount, + SkFloatToScalar(aOptions.mDashOffset)); SkSafeUnref(aPaint.setPathEffect(dash)); } diff --git a/gfx/2d/Scale.cpp b/gfx/2d/Scale.cpp index 0b5a26fadba7..556c7759f1f5 100644 --- a/gfx/2d/Scale.cpp +++ b/gfx/2d/Scale.cpp @@ -33,7 +33,7 @@ bool Scale(uint8_t* srcData, int32_t srcWidth, int32_t srcHeight, int32_t srcStr // Rescaler is compatible with 32 bpp only. Convert to RGB32 if needed. if (config != SkBitmap::kARGB_8888_Config) { - imgSrc.copyTo(&imgSrc, SkBitmap::kARGB_8888_Config); + imgSrc.copyTo(&imgSrc, kRGBA_8888_SkColorType); } // This returns an SkBitmap backed by dstData; since it also wrote to dstData, diff --git a/gfx/2d/SourceSurfaceSkia.cpp b/gfx/2d/SourceSurfaceSkia.cpp index 1fb99a04c2cd..18c3151c107e 100644 --- a/gfx/2d/SourceSurfaceSkia.cpp +++ b/gfx/2d/SourceSurfaceSkia.cpp @@ -68,7 +68,7 @@ SourceSurfaceSkia::InitFromData(unsigned char* aData, temp.setConfig(GfxFormatToSkiaConfig(aFormat), aSize.width, aSize.height, aStride); temp.setPixels(aData); - if (!temp.copyTo(&mBitmap, GfxFormatToSkiaConfig(aFormat))) { + if (!temp.copyTo(&mBitmap, GfxFormatToSkiaColorType(aFormat))) { return false; } @@ -108,7 +108,7 @@ SourceSurfaceSkia::DrawTargetWillChange() mDrawTarget = nullptr; SkBitmap temp = mBitmap; mBitmap.reset(); - temp.copyTo(&mBitmap, temp.getConfig()); + temp.copyTo(&mBitmap, temp.colorType()); } } From 6d1d47784435c63b0cf5527631ba66f2198c4ad4 Mon Sep 17 00:00:00 2001 From: George Wright Date: Thu, 20 Mar 2014 14:08:19 -0400 Subject: [PATCH 019/101] [PATCH 4/6] Bug 985217 - Remove client side array functions as Skia no longer uses/wants them, and set the functions differently following refactoring in GrGLInterface r=snorp --- gfx/gl/SkiaGLGlue.cpp | 272 +++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 151 deletions(-) diff --git a/gfx/gl/SkiaGLGlue.cpp b/gfx/gl/SkiaGLGlue.cpp index 25467d50ec95..b187b1a4d826 100755 --- a/gfx/gl/SkiaGLGlue.cpp +++ b/gfx/gl/SkiaGLGlue.cpp @@ -726,21 +726,6 @@ GrGLvoid glGenVertexArrays_mozilla(GrGLsizei n, GrGLuint *arrays) { // Additional functions required for desktop GL < version 3.2 -GrGLvoid glClientActiveTexture_mozilla(GrGLenum texture) -{ - return sGLContext.get()->fClientActiveTexture(texture); -} - -GrGLvoid glDisableClientState_mozilla(GrGLenum capability) -{ - return sGLContext.get()->fDisableClientState(capability); -} - -GrGLvoid glEnableClientState_mozilla(GrGLenum capability) -{ - return sGLContext.get()->fEnableClientState(capability); -} - GrGLvoid glLoadMatrixf_mozilla(const GLfloat* matrix) { return sGLContext.get()->fLoadMatrixf(matrix); @@ -761,21 +746,11 @@ GrGLvoid glTexGeni_mozilla(GrGLenum coord, GrGLenum pname, GrGLint param) return sGLContext.get()->fTexGeni(coord, pname, param); } -GrGLvoid glTexGenf_mozilla(GrGLenum coord, GrGLenum pname, GrGLfloat param) -{ - return sGLContext.get()->fTexGenf(coord, pname, param); -} - GrGLvoid glTexGenfv_mozilla(GrGLenum coord, GrGLenum pname, const GrGLfloat* param) { return sGLContext.get()->fTexGenfv(coord, pname, param); } -GrGLvoid glVertexPointer_mozilla(GrGLint size, GrGLenum type, GrGLsizei stride, const GrGLvoid* pointer) -{ - return sGLContext.get()->fVertexPointer(size, type, stride, pointer); -} - } // extern "C" static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context) @@ -785,154 +760,149 @@ static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context) i->fCallbackData = 0; // must be later initialized to be a valid DrawTargetSkia* pointer // Core GL functions required by Ganesh - i->fActiveTexture = glActiveTexture_mozilla; - i->fAttachShader = glAttachShader_mozilla; - i->fBindAttribLocation = glBindAttribLocation_mozilla; - i->fBindBuffer = glBindBuffer_mozilla; - i->fBindFramebuffer = glBindFramebuffer_mozilla; - i->fBindRenderbuffer = glBindRenderbuffer_mozilla; - i->fBindTexture = glBindTexture_mozilla; - i->fBlendFunc = glBlendFunc_mozilla; - i->fBlendColor = glBlendColor_mozilla; - i->fBufferData = glBufferData_mozilla; - i->fBufferSubData = glBufferSubData_mozilla; - i->fCheckFramebufferStatus = glCheckFramebufferStatus_mozilla; - i->fClear = glClear_mozilla; - i->fClearColor = glClearColor_mozilla; - i->fClearStencil = glClearStencil_mozilla; - i->fColorMask = glColorMask_mozilla; - i->fCompileShader = glCompileShader_mozilla; - i->fCopyTexSubImage2D = glCopyTexSubImage2D_mozilla; - i->fCreateProgram = glCreateProgram_mozilla; - i->fCreateShader = glCreateShader_mozilla; - i->fCullFace = glCullFace_mozilla; - i->fDeleteBuffers = glDeleteBuffers_mozilla; - i->fDeleteFramebuffers = glDeleteFramebuffers_mozilla; - i->fDeleteProgram = glDeleteProgram_mozilla; - i->fDeleteRenderbuffers = glDeleteRenderbuffers_mozilla; - i->fDeleteShader = glDeleteShader_mozilla; - i->fDeleteTextures = glDeleteTextures_mozilla; - i->fDepthMask = glDepthMask_mozilla; - i->fDisable = glDisable_mozilla; - i->fDisableVertexAttribArray = glDisableVertexAttribArray_mozilla; - i->fDrawArrays = glDrawArrays_mozilla; - i->fDrawElements = glDrawElements_mozilla; - i->fEnable = glEnable_mozilla; - i->fEnableVertexAttribArray = glEnableVertexAttribArray_mozilla; - i->fFinish = glFinish_mozilla; - i->fFlush = glFlush_mozilla; - i->fFramebufferRenderbuffer = glFramebufferRenderbuffer_mozilla; - i->fFramebufferTexture2D = glFramebufferTexture2D_mozilla; - i->fFrontFace = glFrontFace_mozilla; - i->fGenBuffers = glGenBuffers_mozilla; - i->fGenFramebuffers = glGenFramebuffers_mozilla; - i->fGenRenderbuffers = glGenRenderbuffers_mozilla; - i->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv_mozilla; - i->fGenTextures = glGenTextures_mozilla; - i->fGenerateMipmap = glGenerateMipmap_mozilla; - i->fGetBufferParameteriv = glGetBufferParameteriv_mozilla; - i->fGetError = glGetError_mozilla; - i->fGetIntegerv = glGetIntegerv_mozilla; - i->fGetProgramInfoLog = glGetProgramInfoLog_mozilla; - i->fGetProgramiv = glGetProgramiv_mozilla; - i->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv_mozilla; - i->fGetShaderInfoLog = glGetShaderInfoLog_mozilla; - i->fGetShaderiv = glGetShaderiv_mozilla; - i->fGetString = glGetString_mozilla; - i->fGetUniformLocation = glGetUniformLocation_mozilla; - i->fLineWidth = glLineWidth_mozilla; - i->fLinkProgram = glLinkProgram_mozilla; - i->fPixelStorei = glPixelStorei_mozilla; - i->fReadPixels = glReadPixels_mozilla; - i->fRenderbufferStorage = glRenderbufferStorage_mozilla; - i->fScissor = glScissor_mozilla; - i->fShaderSource = glShaderSource_mozilla; - i->fStencilFunc = glStencilFunc_mozilla; - i->fStencilMask = glStencilMask_mozilla; - i->fStencilOp = glStencilOp_mozilla; - i->fTexImage2D = glTexImage2D_mozilla; - i->fTexParameteri = glTexParameteri_mozilla; - i->fTexParameteriv = glTexParameteriv_mozilla; - i->fTexSubImage2D = glTexSubImage2D_mozilla; - i->fUniform1f = glUniform1f_mozilla; - i->fUniform1i = glUniform1i_mozilla; - i->fUniform1fv = glUniform1fv_mozilla; - i->fUniform1iv = glUniform1iv_mozilla; - i->fUniform2f = glUniform2f_mozilla; - i->fUniform2i = glUniform2i_mozilla; - i->fUniform2fv = glUniform2fv_mozilla; - i->fUniform2iv = glUniform2iv_mozilla; - i->fUniform3f = glUniform3f_mozilla; - i->fUniform3i = glUniform3i_mozilla; - i->fUniform3fv = glUniform3fv_mozilla; - i->fUniform3iv = glUniform3iv_mozilla; - i->fUniform4f = glUniform4f_mozilla; - i->fUniform4i = glUniform4i_mozilla; - i->fUniform4fv = glUniform4fv_mozilla; - i->fUniform4iv = glUniform4iv_mozilla; - i->fUniformMatrix2fv = glUniformMatrix2fv_mozilla; - i->fUniformMatrix3fv = glUniformMatrix3fv_mozilla; - i->fUniformMatrix4fv = glUniformMatrix4fv_mozilla; - i->fUseProgram = glUseProgram_mozilla; - i->fVertexAttrib4fv = glVertexAttrib4fv_mozilla; - i->fVertexAttribPointer = glVertexAttribPointer_mozilla; - i->fViewport = glViewport_mozilla; + i->fFunctions.fActiveTexture = glActiveTexture_mozilla; + i->fFunctions.fAttachShader = glAttachShader_mozilla; + i->fFunctions.fBindAttribLocation = glBindAttribLocation_mozilla; + i->fFunctions.fBindBuffer = glBindBuffer_mozilla; + i->fFunctions.fBindFramebuffer = glBindFramebuffer_mozilla; + i->fFunctions.fBindRenderbuffer = glBindRenderbuffer_mozilla; + i->fFunctions.fBindTexture = glBindTexture_mozilla; + i->fFunctions.fBlendFunc = glBlendFunc_mozilla; + i->fFunctions.fBlendColor = glBlendColor_mozilla; + i->fFunctions.fBufferData = glBufferData_mozilla; + i->fFunctions.fBufferSubData = glBufferSubData_mozilla; + i->fFunctions.fCheckFramebufferStatus = glCheckFramebufferStatus_mozilla; + i->fFunctions.fClear = glClear_mozilla; + i->fFunctions.fClearColor = glClearColor_mozilla; + i->fFunctions.fClearStencil = glClearStencil_mozilla; + i->fFunctions.fColorMask = glColorMask_mozilla; + i->fFunctions.fCompileShader = glCompileShader_mozilla; + i->fFunctions.fCopyTexSubImage2D = glCopyTexSubImage2D_mozilla; + i->fFunctions.fCreateProgram = glCreateProgram_mozilla; + i->fFunctions.fCreateShader = glCreateShader_mozilla; + i->fFunctions.fCullFace = glCullFace_mozilla; + i->fFunctions.fDeleteBuffers = glDeleteBuffers_mozilla; + i->fFunctions.fDeleteFramebuffers = glDeleteFramebuffers_mozilla; + i->fFunctions.fDeleteProgram = glDeleteProgram_mozilla; + i->fFunctions.fDeleteRenderbuffers = glDeleteRenderbuffers_mozilla; + i->fFunctions.fDeleteShader = glDeleteShader_mozilla; + i->fFunctions.fDeleteTextures = glDeleteTextures_mozilla; + i->fFunctions.fDepthMask = glDepthMask_mozilla; + i->fFunctions.fDisable = glDisable_mozilla; + i->fFunctions.fDisableVertexAttribArray = glDisableVertexAttribArray_mozilla; + i->fFunctions.fDrawArrays = glDrawArrays_mozilla; + i->fFunctions.fDrawElements = glDrawElements_mozilla; + i->fFunctions.fEnable = glEnable_mozilla; + i->fFunctions.fEnableVertexAttribArray = glEnableVertexAttribArray_mozilla; + i->fFunctions.fFinish = glFinish_mozilla; + i->fFunctions.fFlush = glFlush_mozilla; + i->fFunctions.fFramebufferRenderbuffer = glFramebufferRenderbuffer_mozilla; + i->fFunctions.fFramebufferTexture2D = glFramebufferTexture2D_mozilla; + i->fFunctions.fFrontFace = glFrontFace_mozilla; + i->fFunctions.fGenBuffers = glGenBuffers_mozilla; + i->fFunctions.fGenFramebuffers = glGenFramebuffers_mozilla; + i->fFunctions.fGenRenderbuffers = glGenRenderbuffers_mozilla; + i->fFunctions.fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv_mozilla; + i->fFunctions.fGenTextures = glGenTextures_mozilla; + i->fFunctions.fGenerateMipmap = glGenerateMipmap_mozilla; + i->fFunctions.fGetBufferParameteriv = glGetBufferParameteriv_mozilla; + i->fFunctions.fGetError = glGetError_mozilla; + i->fFunctions.fGetIntegerv = glGetIntegerv_mozilla; + i->fFunctions.fGetProgramInfoLog = glGetProgramInfoLog_mozilla; + i->fFunctions.fGetProgramiv = glGetProgramiv_mozilla; + i->fFunctions.fGetRenderbufferParameteriv = glGetRenderbufferParameteriv_mozilla; + i->fFunctions.fGetShaderInfoLog = glGetShaderInfoLog_mozilla; + i->fFunctions.fGetShaderiv = glGetShaderiv_mozilla; + i->fFunctions.fGetString = glGetString_mozilla; + i->fFunctions.fGetUniformLocation = glGetUniformLocation_mozilla; + i->fFunctions.fLineWidth = glLineWidth_mozilla; + i->fFunctions.fLinkProgram = glLinkProgram_mozilla; + i->fFunctions.fPixelStorei = glPixelStorei_mozilla; + i->fFunctions.fReadPixels = glReadPixels_mozilla; + i->fFunctions.fRenderbufferStorage = glRenderbufferStorage_mozilla; + i->fFunctions.fScissor = glScissor_mozilla; + i->fFunctions.fShaderSource = glShaderSource_mozilla; + i->fFunctions.fStencilFunc = glStencilFunc_mozilla; + i->fFunctions.fStencilMask = glStencilMask_mozilla; + i->fFunctions.fStencilOp = glStencilOp_mozilla; + i->fFunctions.fTexImage2D = glTexImage2D_mozilla; + i->fFunctions.fTexParameteri = glTexParameteri_mozilla; + i->fFunctions.fTexParameteriv = glTexParameteriv_mozilla; + i->fFunctions.fTexSubImage2D = glTexSubImage2D_mozilla; + i->fFunctions.fUniform1f = glUniform1f_mozilla; + i->fFunctions.fUniform1i = glUniform1i_mozilla; + i->fFunctions.fUniform1fv = glUniform1fv_mozilla; + i->fFunctions.fUniform1iv = glUniform1iv_mozilla; + i->fFunctions.fUniform2f = glUniform2f_mozilla; + i->fFunctions.fUniform2i = glUniform2i_mozilla; + i->fFunctions.fUniform2fv = glUniform2fv_mozilla; + i->fFunctions.fUniform2iv = glUniform2iv_mozilla; + i->fFunctions.fUniform3f = glUniform3f_mozilla; + i->fFunctions.fUniform3i = glUniform3i_mozilla; + i->fFunctions.fUniform3fv = glUniform3fv_mozilla; + i->fFunctions.fUniform3iv = glUniform3iv_mozilla; + i->fFunctions.fUniform4f = glUniform4f_mozilla; + i->fFunctions.fUniform4i = glUniform4i_mozilla; + i->fFunctions.fUniform4fv = glUniform4fv_mozilla; + i->fFunctions.fUniform4iv = glUniform4iv_mozilla; + i->fFunctions.fUniformMatrix2fv = glUniformMatrix2fv_mozilla; + i->fFunctions.fUniformMatrix3fv = glUniformMatrix3fv_mozilla; + i->fFunctions.fUniformMatrix4fv = glUniformMatrix4fv_mozilla; + i->fFunctions.fUseProgram = glUseProgram_mozilla; + i->fFunctions.fVertexAttrib4fv = glVertexAttrib4fv_mozilla; + i->fFunctions.fVertexAttribPointer = glVertexAttribPointer_mozilla; + i->fFunctions.fViewport = glViewport_mozilla; // Required for either desktop OpenGL 2.0 or OpenGL ES 2.0 - i->fStencilFuncSeparate = glStencilFuncSeparate_mozilla; - i->fStencilMaskSeparate = glStencilMaskSeparate_mozilla; - i->fStencilOpSeparate = glStencilOpSeparate_mozilla; + i->fFunctions.fStencilFuncSeparate = glStencilFuncSeparate_mozilla; + i->fFunctions.fStencilMaskSeparate = glStencilMaskSeparate_mozilla; + i->fFunctions.fStencilOpSeparate = glStencilOpSeparate_mozilla; // GLContext supports glMapBuffer - i->fMapBuffer = glMapBuffer_mozilla; - i->fUnmapBuffer = glUnmapBuffer_mozilla; + i->fFunctions.fMapBuffer = glMapBuffer_mozilla; + i->fFunctions.fUnmapBuffer = glUnmapBuffer_mozilla; // GLContext supports glRenderbufferStorageMultisample/glBlitFramebuffer - i->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample_mozilla; - i->fBlitFramebuffer = glBlitFramebuffer_mozilla; + i->fFunctions.fRenderbufferStorageMultisample = glRenderbufferStorageMultisample_mozilla; + i->fFunctions.fBlitFramebuffer = glBlitFramebuffer_mozilla; // GLContext supports glCompressedTexImage2D - i->fCompressedTexImage2D = glCompressedTexImage2D_mozilla; + i->fFunctions.fCompressedTexImage2D = glCompressedTexImage2D_mozilla; // GL_OES_vertex_array_object - i->fBindVertexArray = glBindVertexArray_mozilla; - i->fDeleteVertexArrays = glDeleteVertexArrays_mozilla; - i->fGenVertexArrays = glGenVertexArrays_mozilla; + i->fFunctions.fBindVertexArray = glBindVertexArray_mozilla; + i->fFunctions.fDeleteVertexArrays = glDeleteVertexArrays_mozilla; + i->fFunctions.fGenVertexArrays = glGenVertexArrays_mozilla; // Desktop GL - i->fGetTexLevelParameteriv = glGetTexLevelParameteriv_mozilla; - i->fDrawBuffer = glDrawBuffer_mozilla; - i->fReadBuffer = glReadBuffer_mozilla; + i->fFunctions.fGetTexLevelParameteriv = glGetTexLevelParameteriv_mozilla; + i->fFunctions.fDrawBuffer = glDrawBuffer_mozilla; + i->fFunctions.fReadBuffer = glReadBuffer_mozilla; // Desktop OpenGL > 1.5 - i->fGenQueries = glGenQueries_mozilla; - i->fDeleteQueries = glDeleteQueries_mozilla; - i->fBeginQuery = glBeginQuery_mozilla; - i->fEndQuery = glEndQuery_mozilla; - i->fGetQueryiv = glGetQueryiv_mozilla; - i->fGetQueryObjectiv = glGetQueryObjectiv_mozilla; - i->fGetQueryObjectuiv = glGetQueryObjectuiv_mozilla; + i->fFunctions.fGenQueries = glGenQueries_mozilla; + i->fFunctions.fDeleteQueries = glDeleteQueries_mozilla; + i->fFunctions.fBeginQuery = glBeginQuery_mozilla; + i->fFunctions.fEndQuery = glEndQuery_mozilla; + i->fFunctions.fGetQueryiv = glGetQueryiv_mozilla; + i->fFunctions.fGetQueryObjectiv = glGetQueryObjectiv_mozilla; + i->fFunctions.fGetQueryObjectuiv = glGetQueryObjectuiv_mozilla; // Desktop OpenGL > 2.0 - i->fDrawBuffers = glDrawBuffers_mozilla; + i->fFunctions.fDrawBuffers = glDrawBuffers_mozilla; // Desktop OpenGL < 3.2 (which we pretend to be) - i->fClientActiveTexture = glClientActiveTexture_mozilla; - i->fDisableClientState = glDisableClientState_mozilla; - i->fEnableClientState = glEnableClientState_mozilla; - i->fLoadIdentity = glLoadIdentity_mozilla; - i->fLoadMatrixf = glLoadMatrixf_mozilla; - i->fMatrixMode = glMatrixMode_mozilla; - i->fTexGenf = glTexGenf_mozilla; - i->fTexGenfv = glTexGenfv_mozilla; - i->fTexGeni = glTexGeni_mozilla; - i->fVertexPointer = glVertexPointer_mozilla; + i->fFunctions.fLoadIdentity = glLoadIdentity_mozilla; + i->fFunctions.fLoadMatrixf = glLoadMatrixf_mozilla; + i->fFunctions.fMatrixMode = glMatrixMode_mozilla; + i->fFunctions.fTexGenfv = glTexGenfv_mozilla; + i->fFunctions.fTexGeni = glTexGeni_mozilla; // We support both desktop GL and GLES2 if (context->IsGLES2()) { - i->fBindingsExported = kES2_GrGLBinding; + i->fBindingsExported = kGLES_GrGLStandard; } else { - i->fBindingsExported = kDesktop_GrGLBinding; + i->fStandard = kGL_GrGLStandard; } return i; From 158e10b759f6e05989284aa17c73374077cc1f5b Mon Sep 17 00:00:00 2001 From: George Wright Date: Mon, 17 Mar 2014 13:17:49 -0400 Subject: [PATCH 020/101] [PATCH 5/6] Bug 985217 - Stub out CreateTypeface* for Mac r=snorp --- gfx/skia/trunk/src/ports/SkFontHost_mac.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gfx/skia/trunk/src/ports/SkFontHost_mac.cpp b/gfx/skia/trunk/src/ports/SkFontHost_mac.cpp index 26d30d726a27..7f4f41c22e34 100755 --- a/gfx/skia/trunk/src/ports/SkFontHost_mac.cpp +++ b/gfx/skia/trunk/src/ports/SkFontHost_mac.cpp @@ -2317,3 +2317,24 @@ SkFontMgr* SkFontMgr::Factory() { return SkNEW(SkFontMgr_Mac); } #endif + +SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace, + const char famillyName[], + SkTypeface::Style style) +{ + SkDEBUGFAIL("SkFontHost::FindTypeface unimplemented"); + return NULL; +} + +SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*) +{ + SkDEBUGFAIL("SkFontHost::CreateTypeface unimplemented"); + return NULL; +} + +SkTypeface* SkFontHost::CreateTypefaceFromFile(char const*) +{ + SkDEBUGFAIL("SkFontHost::CreateTypefaceFromFile unimplemented"); + return NULL; +} + From c447e9eb943f037b4b4135ed48b2a469ce9db627 Mon Sep 17 00:00:00 2001 From: George Wright Date: Tue, 18 Mar 2014 19:37:56 -0400 Subject: [PATCH 021/101] [PATCH 6/6] Bug 985217 - Ensure that our GLContext is current and working at GrGLInterface creation time as Skia now determines extensions at creation time r=snorp --- gfx/gl/SkiaGLGlue.cpp | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/gfx/gl/SkiaGLGlue.cpp b/gfx/gl/SkiaGLGlue.cpp index b187b1a4d826..c1ad6f700598 100755 --- a/gfx/gl/SkiaGLGlue.cpp +++ b/gfx/gl/SkiaGLGlue.cpp @@ -28,17 +28,23 @@ static mozilla::ThreadLocal sGLContext; extern "C" { -void EnsureGLContext(const GrGLInterface* i) +static void SetStaticGLContext(GLContext* context) { - const SkiaGLGlue* contextSkia = reinterpret_cast(i->fCallbackData); - GLContext* gl = contextSkia->GetGLContext(); - gl->MakeCurrent(); - if (!sGLContext.initialized()) { mozilla::DebugOnly success = sGLContext.init(); MOZ_ASSERT(success); } - sGLContext.set(gl); + + sGLContext.set(context); +} + +void EnsureGLContext(const GrGLInterface* i) +{ + const SkiaGLGlue* contextSkia = reinterpret_cast(i->fCallbackData); + MOZ_ASSERT(contextSkia); + GLContext* gl = contextSkia->GetGLContext(); + gl->MakeCurrent(); + SetStaticGLContext(gl); } // Core GL functions required by Ganesh @@ -755,10 +761,28 @@ GrGLvoid glTexGenfv_mozilla(GrGLenum coord, GrGLenum pname, const GrGLfloat* par static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context) { + SetStaticGLContext(context); + GrGLInterface* i = new GrGLInterface(); i->fCallback = EnsureGLContext; i->fCallbackData = 0; // must be later initialized to be a valid DrawTargetSkia* pointer + context->MakeCurrent(); + + // We support both desktop GL and GLES2 + if (context->IsGLES2()) { + i->fStandard = kGLES_GrGLStandard; + } else { + i->fStandard = kGL_GrGLStandard; + } + + GrGLExtensions extensions; + if (!extensions.init(i->fStandard, glGetString_mozilla, NULL, glGetIntegerv_mozilla)) { + return nullptr; + } + + i->fExtensions.swap(&extensions); + // Core GL functions required by Ganesh i->fFunctions.fActiveTexture = glActiveTexture_mozilla; i->fFunctions.fAttachShader = glAttachShader_mozilla; @@ -898,13 +922,6 @@ static GrGLInterface* CreateGrGLInterfaceFromGLContext(GLContext* context) i->fFunctions.fTexGenfv = glTexGenfv_mozilla; i->fFunctions.fTexGeni = glTexGeni_mozilla; - // We support both desktop GL and GLES2 - if (context->IsGLES2()) { - i->fBindingsExported = kGLES_GrGLStandard; - } else { - i->fStandard = kGL_GrGLStandard; - } - return i; } From aae6baffd3d2f52263b688b588e2c35cd867a5ec Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Thu, 20 Mar 2014 14:26:47 -0700 Subject: [PATCH 022/101] Bug 924260 -[e10s] Fix assertion on window close (r=felipe) --- toolkit/content/browser-child.js | 1 + 1 file changed, 1 insertion(+) diff --git a/toolkit/content/browser-child.js b/toolkit/content/browser-child.js index 879e05feb51a..073c9f329cf7 100644 --- a/toolkit/content/browser-child.js +++ b/toolkit/content/browser-child.js @@ -238,6 +238,7 @@ addEventListener("DOMWindowClose", function (aEvent) { if (!aEvent.isTrusted) return; sendAsyncMessage("DOMWindowClose"); + aEvent.preventDefault(); }, false); addEventListener("ImageContentLoaded", function (aEvent) { From bf528602436b320798da784ba06eb20446ed0417 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Thu, 20 Mar 2014 14:27:24 -0700 Subject: [PATCH 023/101] Bug 985731 - [e10s] Disable beacon tests (r=ted) --- dom/tests/mochitest/beacon/mochitest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/tests/mochitest/beacon/mochitest.ini b/dom/tests/mochitest/beacon/mochitest.ini index 6d418cbef825..0ab1ab5567ef 100644 --- a/dom/tests/mochitest/beacon/mochitest.ini +++ b/dom/tests/mochitest/beacon/mochitest.ini @@ -1,5 +1,5 @@ [DEFAULT] -skip-if = buildapp == 'b2g' +skip-if = buildapp == 'b2g' || e10s support-files = beacon-frame.html beacon-handler.sjs beacon-set-cookie.sjs From b1405bc489b868c820527269b05a0105c068413c Mon Sep 17 00:00:00 2001 From: David Keeler Date: Thu, 20 Mar 2014 14:29:21 -0700 Subject: [PATCH 024/101] bug 985201 - rename insanity::pkix to mozilla::pkix r=cviecco r=briansmith --HG-- rename : security/insanity/include/insanity/ScopedPtr.h => security/pkix/include/pkix/ScopedPtr.h rename : security/insanity/include/insanity/bind.h => security/pkix/include/pkix/bind.h rename : security/insanity/include/insanity/nullptr.h => security/pkix/include/pkix/nullptr.h rename : security/insanity/include/insanity/pkix.h => security/pkix/include/pkix/pkix.h rename : security/insanity/include/insanity/pkixtypes.h => security/pkix/include/pkix/pkixtypes.h rename : security/insanity/lib/pkixbind.cpp => security/pkix/lib/pkixbind.cpp rename : security/insanity/lib/pkixbuild.cpp => security/pkix/lib/pkixbuild.cpp rename : security/insanity/lib/pkixcheck.cpp => security/pkix/lib/pkixcheck.cpp rename : security/insanity/lib/pkixcheck.h => security/pkix/lib/pkixcheck.h rename : security/insanity/lib/pkixder.cpp => security/pkix/lib/pkixder.cpp rename : security/insanity/lib/pkixder.h => security/pkix/lib/pkixder.h rename : security/insanity/lib/pkixkey.cpp => security/pkix/lib/pkixkey.cpp rename : security/insanity/lib/pkixocsp.cpp => security/pkix/lib/pkixocsp.cpp rename : security/insanity/lib/pkixutil.h => security/pkix/lib/pkixutil.h rename : security/insanity/moz.build => security/pkix/moz.build rename : security/insanity/test/lib/moz.build => security/pkix/test/lib/moz.build rename : security/insanity/test/lib/pkixtestutil.cpp => security/pkix/test/lib/pkixtestutil.cpp rename : security/insanity/test/lib/pkixtestutil.h => security/pkix/test/lib/pkixtestutil.h --- security/apps/AppSignatureVerification.cpp | 14 +- security/apps/AppTrustDomain.cpp | 8 +- security/apps/AppTrustDomain.h | 12 +- security/apps/moz.build | 2 +- security/certverifier/CertVerifier.cpp | 30 ++-- security/certverifier/CertVerifier.h | 12 +- security/certverifier/ExtendedValidation.cpp | 2 +- .../certverifier/NSSCertDBTrustDomain.cpp | 12 +- security/certverifier/NSSCertDBTrustDomain.h | 12 +- security/certverifier/OCSPCache.cpp | 12 +- security/certverifier/OCSPCache.h | 2 +- security/certverifier/moz.build | 4 +- .../ssl/src/SSLServerCertVerification.cpp | 46 +++--- .../manager/ssl/src/TransportSecurityInfo.cpp | 4 +- security/manager/ssl/src/moz.build | 2 +- security/manager/ssl/src/nsCMS.cpp | 10 +- .../manager/ssl/src/nsCertOverrideService.cpp | 8 +- security/manager/ssl/src/nsCertPicker.cpp | 6 +- security/manager/ssl/src/nsCertTree.cpp | 6 +- security/manager/ssl/src/nsCrypto.cpp | 10 +- security/manager/ssl/src/nsNSSCallbacks.cpp | 4 +- security/manager/ssl/src/nsNSSCertCache.cpp | 2 +- security/manager/ssl/src/nsNSSCertificate.cpp | 6 +- security/manager/ssl/src/nsNSSCertificate.h | 10 +- .../manager/ssl/src/nsNSSCertificateDB.cpp | 48 +++--- security/manager/ssl/src/nsNSSComponent.cpp | 12 +- security/manager/ssl/src/nsNSSIOLayer.cpp | 6 +- security/manager/ssl/src/nsPKCS12Blob.cpp | 4 +- security/manager/ssl/src/nsRecentBadCerts.cpp | 4 +- security/manager/ssl/tests/gtest/moz.build | 2 +- .../ssl/tests/unit/test_cert_overrides.js | 54 +++---- .../ssl/tests/unit/test_cert_signatures.js | 12 +- .../manager/ssl/tests/unit/test_cert_trust.js | 142 +++++++++--------- .../ssl/tests/unit/test_certificate_usages.js | 42 +++--- .../manager/ssl/tests/unit/test_ev_certs.js | 32 ++-- .../manager/ssl/tests/unit/test_getchain.js | 4 +- ...st_intermediate_basic_usage_constraints.js | 20 +-- .../ssl/tests/unit/test_name_constraints.js | 6 +- .../ssl/tests/unit/test_ocsp_caching.js | 10 +- .../ssl/tests/unit/test_ocsp_required.js | 10 +- .../ssl/tests/unit/test_ocsp_stapling.js | 10 +- .../tests/unit/test_ocsp_stapling_expired.js | 6 +- .../test_ocsp_stapling_with_intermediate.js | 6 +- .../ssl/tests/unit/tlsserver/cmd/Makefile.in | 4 +- .../tests/unit/tlsserver/lib/OCSPCommon.cpp | 5 +- .../ssl/tests/unit/tlsserver/lib/moz.build | 4 +- .../include/pkix}/ScopedPtr.h | 38 ++--- .../insanity => pkix/include/pkix}/bind.h | 10 +- .../insanity => pkix/include/pkix}/nullptr.h | 6 +- .../insanity => pkix/include/pkix}/pkix.h | 10 +- .../include/pkix}/pkixtypes.h | 14 +- security/{insanity => pkix}/lib/pkixbind.cpp | 8 +- security/{insanity => pkix}/lib/pkixbuild.cpp | 8 +- security/{insanity => pkix}/lib/pkixcheck.cpp | 6 +- security/{insanity => pkix}/lib/pkixcheck.h | 10 +- security/{insanity => pkix}/lib/pkixder.cpp | 4 +- security/{insanity => pkix}/lib/pkixder.h | 12 +- security/{insanity => pkix}/lib/pkixkey.cpp | 6 +- security/{insanity => pkix}/lib/pkixocsp.cpp | 8 +- security/{insanity => pkix}/lib/pkixutil.h | 12 +- security/{insanity => pkix}/moz.build | 2 +- .../{insanity => pkix}/test/lib/moz.build | 0 .../test/lib/pkixtestutil.cpp | 4 +- .../test/lib/pkixtestutil.h | 14 +- toolkit/components/telemetry/Histograms.json | 8 +- 65 files changed, 430 insertions(+), 429 deletions(-) rename security/{insanity/include/insanity => pkix/include/pkix}/ScopedPtr.h (90%) rename security/{insanity/include/insanity => pkix/include/pkix}/bind.h (93%) rename security/{insanity/include/insanity => pkix/include/pkix}/nullptr.h (89%) rename security/{insanity/include/insanity => pkix/include/pkix}/pkix.h (97%) rename security/{insanity/include/insanity => pkix/include/pkix}/pkixtypes.h (94%) rename security/{insanity => pkix}/lib/pkixbind.cpp (89%) rename security/{insanity => pkix}/lib/pkixbuild.cpp (99%) rename security/{insanity => pkix}/lib/pkixcheck.cpp (99%) rename security/{insanity => pkix}/lib/pkixcheck.h (87%) rename security/{insanity => pkix}/lib/pkixder.cpp (95%) rename security/{insanity => pkix}/lib/pkixder.h (98%) rename security/{insanity => pkix}/lib/pkixkey.cpp (96%) rename security/{insanity => pkix}/lib/pkixocsp.cpp (99%) rename security/{insanity => pkix}/lib/pkixutil.h (95%) rename security/{insanity => pkix}/moz.build (95%) rename security/{insanity => pkix}/test/lib/moz.build (100%) rename security/{insanity => pkix}/test/lib/pkixtestutil.cpp (99%) rename security/{insanity => pkix}/test/lib/pkixtestutil.h (88%) diff --git a/security/apps/AppSignatureVerification.cpp b/security/apps/AppSignatureVerification.cpp index e1a8f6c52ada..e54c5177c325 100644 --- a/security/apps/AppSignatureVerification.cpp +++ b/security/apps/AppSignatureVerification.cpp @@ -10,7 +10,7 @@ #include "nsNSSCertificateDB.h" -#include "insanity/pkix.h" +#include "pkix/pkix.h" #include "mozilla/RefPtr.h" #include "CryptoTask.h" #include "AppTrustDomain.h" @@ -33,7 +33,7 @@ #include "plstr.h" #include "prlog.h" -using namespace insanity::pkix; +using namespace mozilla::pkix; using namespace mozilla; using namespace mozilla::psm; @@ -525,9 +525,9 @@ ParseMF(const char* filebuf, nsIZipReader * zip, nsresult VerifySignature(AppTrustedRoot trustedRoot, const SECItem& buffer, const SECItem& detachedDigest, - /*out*/ insanity::pkix::ScopedCERTCertList& builtChain) + /*out*/ mozilla::pkix::ScopedCERTCertList& builtChain) { - insanity::pkix::ScopedPtr + mozilla::pkix::ScopedPtr cmsMsg(NSS_CMSMessage_CreateFromDER(const_cast(&buffer), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr)); @@ -560,13 +560,13 @@ VerifySignature(AppTrustedRoot trustedRoot, // Parse the certificates into CERTCertificate objects held in memory, so that // AppTrustDomain will be able to find them during path building. - insanity::pkix::ScopedCERTCertList certs(CERT_NewCertList()); + mozilla::pkix::ScopedCERTCertList certs(CERT_NewCertList()); if (!certs) { return NS_ERROR_OUT_OF_MEMORY; } if (signedData->rawCerts) { for (size_t i = 0; signedData->rawCerts[i]; ++i) { - insanity::pkix::ScopedCERTCertificate + mozilla::pkix::ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), signedData->rawCerts[i], nullptr, false, true)); @@ -666,7 +666,7 @@ OpenSignedAppFile(AppTrustedRoot aTrustedRoot, nsIFile* aJarFile, } sigBuffer.type = siBuffer; - insanity::pkix::ScopedCERTCertList builtChain; + mozilla::pkix::ScopedCERTCertList builtChain; rv = VerifySignature(aTrustedRoot, sigBuffer, sfCalculatedDigest.get(), builtChain); if (NS_FAILED(rv)) { diff --git a/security/apps/AppTrustDomain.cpp b/security/apps/AppTrustDomain.cpp index 25b222727fb0..a72049b583be 100644 --- a/security/apps/AppTrustDomain.cpp +++ b/security/apps/AppTrustDomain.cpp @@ -10,7 +10,7 @@ #include "AppTrustDomain.h" #include "certdb.h" -#include "insanity/pkix.h" +#include "pkix/pkix.h" #include "mozilla/ArrayUtils.h" #include "nsIX509CertDB.h" #include "prerror.h" @@ -23,7 +23,7 @@ #include "marketplace-dev-reviewers.inc" #include "xpcshell.inc" -using namespace insanity::pkix; +using namespace mozilla::pkix; #ifdef PR_LOGGING extern PRLogModuleInfo* gPIPNSSLog; @@ -88,7 +88,7 @@ AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot) SECStatus AppTrustDomain::FindPotentialIssuers(const SECItem* encodedIssuerName, PRTime time, - /*out*/ insanity::pkix::ScopedCERTCertList& results) + /*out*/ mozilla::pkix::ScopedCERTCertList& results) { MOZ_ASSERT(mTrustedRoot); if (!mTrustedRoot) { @@ -168,7 +168,7 @@ SECStatus AppTrustDomain::VerifySignedData(const CERTSignedData* signedData, const CERTCertificate* cert) { - return ::insanity::pkix::VerifySignedData(signedData, cert, mPinArg); + return ::mozilla::pkix::VerifySignedData(signedData, cert, mPinArg); } SECStatus diff --git a/security/apps/AppTrustDomain.h b/security/apps/AppTrustDomain.h index 1e5d42996cfa..875c1db34105 100644 --- a/security/apps/AppTrustDomain.h +++ b/security/apps/AppTrustDomain.h @@ -7,37 +7,37 @@ #ifndef mozilla_psm_AppsTrustDomain_h #define mozilla_psm_AppsTrustDomain_h -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsDebug.h" #include "nsIX509CertDB.h" namespace mozilla { namespace psm { -class AppTrustDomain MOZ_FINAL : public insanity::pkix::TrustDomain +class AppTrustDomain MOZ_FINAL : public mozilla::pkix::TrustDomain { public: AppTrustDomain(void* pinArg); SECStatus SetTrustedRoot(AppTrustedRoot trustedRoot); - SECStatus GetCertTrust(insanity::pkix::EndEntityOrCA endEntityOrCA, + SECStatus GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA, SECOidTag policy, const CERTCertificate* candidateCert, /*out*/ TrustLevel* trustLevel) MOZ_OVERRIDE; SECStatus FindPotentialIssuers(const SECItem* encodedIssuerName, PRTime time, - /*out*/ insanity::pkix::ScopedCERTCertList& results) + /*out*/ mozilla::pkix::ScopedCERTCertList& results) MOZ_OVERRIDE; SECStatus VerifySignedData(const CERTSignedData* signedData, const CERTCertificate* cert) MOZ_OVERRIDE; - SECStatus CheckRevocation(insanity::pkix::EndEntityOrCA endEntityOrCA, + SECStatus CheckRevocation(mozilla::pkix::EndEntityOrCA endEntityOrCA, const CERTCertificate* cert, /*const*/ CERTCertificate* issuerCertToDup, PRTime time, /*optional*/ const SECItem* stapledOCSPresponse); private: void* mPinArg; // non-owning! - insanity::pkix::ScopedCERTCertificate mTrustedRoot; + mozilla::pkix::ScopedCERTCertificate mTrustedRoot; }; } } // namespace mozilla::psm diff --git a/security/apps/moz.build b/security/apps/moz.build index a8f821a0fd4f..9efda27c7174 100644 --- a/security/apps/moz.build +++ b/security/apps/moz.build @@ -16,8 +16,8 @@ FINAL_LIBRARY = 'xul' LOCAL_INCLUDES += [ '../certverifier', - '../insanity/include', '../manager/ssl/src', + '../pkix/include', ] DEFINES['NSS_ENABLE_ECC'] = 'True' diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp index d59a664b49c9..06a0d845af64 100644 --- a/security/certverifier/CertVerifier.cpp +++ b/security/certverifier/CertVerifier.cpp @@ -8,7 +8,7 @@ #include -#include "insanity/pkix.h" +#include "pkix/pkix.h" #include "ExtendedValidation.h" #include "NSSCertDBTrustDomain.h" #include "cert.h" @@ -17,9 +17,9 @@ #include "prerror.h" #include "sslerr.h" -// ScopedXXX in this file are insanity::pkix::ScopedXXX, not +// ScopedXXX in this file are mozilla::pkix::ScopedXXX, not // mozilla::ScopedXXX. -using namespace insanity::pkix; +using namespace mozilla::pkix; using namespace mozilla::psm; #ifdef PR_LOGGING @@ -65,7 +65,7 @@ InitCertVerifierLog() } #if 0 -// Once we migrate to insanity::pkix or change the overridable error +// Once we migrate to mozilla::pkix or change the overridable error // logic this will become unnecesary. static SECStatus insertErrorIntoVerifyLog(CERTCertificate* cert, const PRErrorCode err, @@ -223,17 +223,17 @@ BuildCertChainForOneKeyUsage(TrustDomain& trustDomain, CERTCertificate* cert, } SECStatus -CertVerifier::InsanityVerifyCert( +CertVerifier::MozillaPKIXVerifyCert( CERTCertificate* cert, const SECCertificateUsage usage, const PRTime time, void* pinArg, const Flags flags, /*optional*/ const SECItem* stapledOCSPResponse, - /*optional out*/ insanity::pkix::ScopedCERTCertList* validationChain, + /*optional out*/ mozilla::pkix::ScopedCERTCertList* validationChain, /*optional out*/ SECOidTag* evOidPolicy) { - PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("Top of InsanityVerifyCert\n")); + PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("Top of MozillaPKIXVerifyCert\n")); PR_ASSERT(cert); PR_ASSERT(usage == certificateUsageSSLServer || !(flags & FLAG_MUST_BE_EV)); @@ -267,7 +267,7 @@ CertVerifier::InsanityVerifyCert( // TODO(bug 915931): Pass in stapled OCSP response in all calls to // BuildCertChain. - insanity::pkix::ScopedCERTCertList builtChain; + mozilla::pkix::ScopedCERTCertList builtChain; switch (usage) { case certificateUsageSSLClient: { // XXX: We don't really have a trust bit for SSL client authentication so @@ -389,8 +389,8 @@ CertVerifier::InsanityVerifyCert( // by the implementation of window.crypto.importCertificates and in the // certificate viewer UI. Because we don't know what trust bit is // interesting, we just try them all. - insanity::pkix::EndEntityOrCA endEntityOrCA; - insanity::pkix::KeyUsages keyUsage; + mozilla::pkix::EndEntityOrCA endEntityOrCA; + mozilla::pkix::KeyUsages keyUsage; SECOidTag eku; if (usage == certificateUsageVerifyCA) { endEntityOrCA = MustBeCA; @@ -449,10 +449,10 @@ CertVerifier::VerifyCert(CERTCertificate* cert, /*optional out*/ SECOidTag* evOidPolicy, /*optional out*/ CERTVerifyLog* verifyLog) { - if (mImplementation == insanity) { - return InsanityVerifyCert(cert, usage, time, pinArg, flags, - stapledOCSPResponse, validationChain, - evOidPolicy); + if (mImplementation == mozillapkix) { + return MozillaPKIXVerifyCert(cert, usage, time, pinArg, flags, + stapledOCSPResponse, validationChain, + evOidPolicy); } if (!cert) @@ -799,7 +799,7 @@ CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert, /*optional*/ void* pinarg, const char* hostname, bool saveIntermediatesInPermanentDatabase, - /*optional out*/ insanity::pkix::ScopedCERTCertList* certChainOut, + /*optional out*/ mozilla::pkix::ScopedCERTCertList* certChainOut, /*optional out*/ SECOidTag* evOidPolicy) { PR_ASSERT(peerCert); diff --git a/security/certverifier/CertVerifier.h b/security/certverifier/CertVerifier.h index 2c970001e60a..09ed4b040ccb 100644 --- a/security/certverifier/CertVerifier.h +++ b/security/certverifier/CertVerifier.h @@ -7,7 +7,7 @@ #ifndef mozilla_psm__CertVerifier_h #define mozilla_psm__CertVerifier_h -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "OCSPCache.h" namespace mozilla { namespace psm { @@ -29,7 +29,7 @@ public: const PRTime time, void* pinArg, const Flags flags = 0, - /*optional out*/ insanity::pkix::ScopedCERTCertList* validationChain = nullptr, + /*optional out*/ mozilla::pkix::ScopedCERTCertList* validationChain = nullptr, /*optional out*/ SECOidTag* evOidPolicy = nullptr , /*optional out*/ CERTVerifyLog* verifyLog = nullptr); @@ -40,7 +40,7 @@ public: /*optional*/ void* pinarg, const char* hostname, bool saveIntermediatesInPermanentDatabase = false, - /*optional out*/ insanity::pkix::ScopedCERTCertList* certChainOut = nullptr, + /*optional out*/ mozilla::pkix::ScopedCERTCertList* certChainOut = nullptr, /*optional out*/ SECOidTag* evOidPolicy = nullptr); @@ -49,7 +49,7 @@ public: #ifndef NSS_NO_LIBPKIX libpkix = 1, #endif - insanity = 2 + mozillapkix = 2 }; enum missing_cert_download_config { missing_cert_download_off = 0, missing_cert_download_on }; @@ -80,13 +80,13 @@ public: const bool mOCSPGETEnabled; private: - SECStatus InsanityVerifyCert(CERTCertificate* cert, + SECStatus MozillaPKIXVerifyCert(CERTCertificate* cert, const SECCertificateUsage usage, const PRTime time, void* pinArg, const Flags flags, /*optional*/ const SECItem* stapledOCSPResponse, - /*optional out*/ insanity::pkix::ScopedCERTCertList* validationChain, + /*optional out*/ mozilla::pkix::ScopedCERTCertList* validationChain, /*optional out*/ SECOidTag* evOidPolicy); OCSPCache mOCSPCache; diff --git a/security/certverifier/ExtendedValidation.cpp b/security/certverifier/ExtendedValidation.cpp index 00812e1e3431..462a42876dd0 100644 --- a/security/certverifier/ExtendedValidation.cpp +++ b/security/certverifier/ExtendedValidation.cpp @@ -9,7 +9,7 @@ #include "cert.h" #include "certdb.h" #include "base64.h" -#include "insanity/nullptr.h" +#include "pkix/nullptr.h" #include "pk11pub.h" #include "secerr.h" #include "prerror.h" diff --git a/security/certverifier/NSSCertDBTrustDomain.cpp b/security/certverifier/NSSCertDBTrustDomain.cpp index e3fe420f401a..989216a55f28 100644 --- a/security/certverifier/NSSCertDBTrustDomain.cpp +++ b/security/certverifier/NSSCertDBTrustDomain.cpp @@ -10,7 +10,7 @@ #include "ExtendedValidation.h" #include "certdb.h" -#include "insanity/pkix.h" +#include "pkix/pkix.h" #include "mozilla/Telemetry.h" #include "nss.h" #include "ocsp.h" @@ -21,7 +21,7 @@ #include "secerr.h" #include "secmod.h" -using namespace insanity::pkix; +using namespace mozilla::pkix; #ifdef PR_LOGGING extern PRLogModuleInfo* gCertVerifierLog; @@ -53,7 +53,7 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType, SECStatus NSSCertDBTrustDomain::FindPotentialIssuers( const SECItem* encodedIssuerName, PRTime time, - /*out*/ insanity::pkix::ScopedCERTCertList& results) + /*out*/ mozilla::pkix::ScopedCERTCertList& results) { // TODO: normalize encodedIssuerName // TODO: NSS seems to be ambiguous between "no potential issuers found" and @@ -131,12 +131,12 @@ SECStatus NSSCertDBTrustDomain::VerifySignedData(const CERTSignedData* signedData, const CERTCertificate* cert) { - return ::insanity::pkix::VerifySignedData(signedData, cert, mPinArg); + return ::mozilla::pkix::VerifySignedData(signedData, cert, mPinArg); } SECStatus NSSCertDBTrustDomain::CheckRevocation( - insanity::pkix::EndEntityOrCA endEntityOrCA, + mozilla::pkix::EndEntityOrCA endEntityOrCA, const CERTCertificate* cert, /*const*/ CERTCertificate* issuerCert, PRTime time, @@ -146,7 +146,7 @@ NSSCertDBTrustDomain::CheckRevocation( // GetCertTrust. // TODO: need to verify that IsRevoked isn't called for trust anchors AND - // that that fact is documented in insanity. + // that that fact is documented in mozillapkix. PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("NSSCertDBTrustDomain: Top of CheckRevocation\n")); diff --git a/security/certverifier/NSSCertDBTrustDomain.h b/security/certverifier/NSSCertDBTrustDomain.h index 3a5c0ca79582..ea924119a86d 100644 --- a/security/certverifier/NSSCertDBTrustDomain.h +++ b/security/certverifier/NSSCertDBTrustDomain.h @@ -7,7 +7,7 @@ #ifndef mozilla_psm__NSSCertDBTrustDomain_h #define mozilla_psm__NSSCertDBTrustDomain_h -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "secmodt.h" #include "CertVerifier.h" @@ -43,9 +43,9 @@ SetClassicOCSPBehavior(CertVerifier::ocsp_download_config enabled, // Caller must free the result with PR_Free char* DefaultServerNicknameForCert(CERTCertificate* cert); -void SaveIntermediateCerts(const insanity::pkix::ScopedCERTCertList& certList); +void SaveIntermediateCerts(const mozilla::pkix::ScopedCERTCertList& certList); -class NSSCertDBTrustDomain : public insanity::pkix::TrustDomain +class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain { public: @@ -62,9 +62,9 @@ public: virtual SECStatus FindPotentialIssuers( const SECItem* encodedIssuerName, PRTime time, - /*out*/ insanity::pkix::ScopedCERTCertList& results); + /*out*/ mozilla::pkix::ScopedCERTCertList& results); - virtual SECStatus GetCertTrust(insanity::pkix::EndEntityOrCA endEntityOrCA, + virtual SECStatus GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA, SECOidTag policy, const CERTCertificate* candidateCert, /*out*/ TrustLevel* trustLevel); @@ -72,7 +72,7 @@ public: virtual SECStatus VerifySignedData(const CERTSignedData* signedData, const CERTCertificate* cert); - virtual SECStatus CheckRevocation(insanity::pkix::EndEntityOrCA endEntityOrCA, + virtual SECStatus CheckRevocation(mozilla::pkix::EndEntityOrCA endEntityOrCA, const CERTCertificate* cert, /*const*/ CERTCertificate* issuerCert, PRTime time, diff --git a/security/certverifier/OCSPCache.cpp b/security/certverifier/OCSPCache.cpp index f37794d2d9a0..b9ef6ef3a8e0 100644 --- a/security/certverifier/OCSPCache.cpp +++ b/security/certverifier/OCSPCache.cpp @@ -28,14 +28,14 @@ extern PRLogModuleInfo* gCertVerifierLog; namespace mozilla { namespace psm { void -Insanity_PK11_DestroyContext_true(PK11Context* context) +MozillaPKIX_PK11_DestroyContext_true(PK11Context* context) { PK11_DestroyContext(context, true); } -typedef insanity::pkix::ScopedPtr - ScopedPK11Context; +typedef mozilla::pkix::ScopedPtr + ScopedPK11Context; // Let derIssuer be the DER encoding of the issuer of aCert. // Let derPublicKey be the DER encoding of the public key of aIssuerCert. @@ -138,9 +138,9 @@ OCSPCache::LogWithCerts(const char* aMessage, const CERTCertificate* aCert, { #ifdef PR_LOGGING if (PR_LOG_TEST(gCertVerifierLog, PR_LOG_DEBUG)) { - insanity::pkix::ScopedPtr + mozilla::pkix::ScopedPtr cn(CERT_GetCommonName(&aCert->subject)); - insanity::pkix::ScopedPtr + mozilla::pkix::ScopedPtr cnIssuer(CERT_GetCommonName(&aIssuerCert->subject)); PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, (aMessage, cn.get(), cnIssuer.get())); } diff --git a/security/certverifier/OCSPCache.h b/security/certverifier/OCSPCache.h index 61db84c64a72..ae608b6fd69c 100644 --- a/security/certverifier/OCSPCache.h +++ b/security/certverifier/OCSPCache.h @@ -20,7 +20,7 @@ #include "certt.h" #include "hasht.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "mozilla/Mutex.h" #include "mozilla/Vector.h" #include "prerror.h" diff --git a/security/certverifier/moz.build b/security/certverifier/moz.build index dac05e5c3481..e755fb43c97d 100644 --- a/security/certverifier/moz.build +++ b/security/certverifier/moz.build @@ -16,11 +16,11 @@ if not CONFIG['NSS_NO_EV_CERTS']: ] LOCAL_INCLUDES += [ - '../insanity/include', + '../pkix/include', ] DIRS += [ - '../insanity', + '../pkix', ] FAIL_ON_WARNINGS = True diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index eecee1c7dc02..c42511b41d4d 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -96,7 +96,7 @@ #include -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "CertVerifier.h" #include "CryptoTask.h" #include "ExtendedValidation.h" @@ -314,13 +314,13 @@ MapCertErrorToProbeValue(PRErrorCode errorCode) } SECStatus -InsanityDetermineCertOverrideErrors(CERTCertificate* cert, - const char* hostName, PRTime now, - PRErrorCode defaultErrorCodeToReport, - /*out*/ uint32_t& collectedErrors, - /*out*/ PRErrorCode& errorCodeTrust, - /*out*/ PRErrorCode& errorCodeMismatch, - /*out*/ PRErrorCode& errorCodeExpired) +MozillaPKIXDetermineCertOverrideErrors(CERTCertificate* cert, + const char* hostName, PRTime now, + PRErrorCode defaultErrorCodeToReport, + /*out*/ uint32_t& collectedErrors, + /*out*/ PRErrorCode& errorCodeTrust, + /*out*/ PRErrorCode& errorCodeMismatch, + /*out*/ PRErrorCode& errorCodeExpired) { MOZ_ASSERT(cert); MOZ_ASSERT(hostName); @@ -329,7 +329,7 @@ InsanityDetermineCertOverrideErrors(CERTCertificate* cert, MOZ_ASSERT(errorCodeMismatch == 0); MOZ_ASSERT(errorCodeExpired == 0); - // Assumes the error prioritization described in insanity::pkix's + // Assumes the error prioritization described in mozilla::pkix's // BuildForward function. Also assumes that CERT_VerifyCertName was only // called if CertVerifier::VerifyCert succeeded. switch (defaultErrorCodeToReport) { @@ -707,14 +707,14 @@ CreateCertErrorRunnable(CertVerifier& certVerifier, errorCodeMismatch, errorCodeExpired); break; - case CertVerifier::insanity: - rv = InsanityDetermineCertOverrideErrors(cert, - infoObject->GetHostNameRaw(), - now, defaultErrorCodeToReport, - collected_errors, - errorCodeTrust, - errorCodeMismatch, - errorCodeExpired); + case CertVerifier::mozillapkix: + rv = MozillaPKIXDetermineCertOverrideErrors(cert, + infoObject->GetHostNameRaw(), + now, defaultErrorCodeToReport, + collected_errors, + errorCodeTrust, + errorCodeMismatch, + errorCodeExpired); break; default: @@ -809,7 +809,7 @@ private: const RefPtr mCertVerifier; const void* const mFdForLogging; const RefPtr mInfoObject; - const insanity::pkix::ScopedCERTCertificate mCert; + const mozilla::pkix::ScopedCERTCertificate mCert; const uint32_t mProviderFlags; const PRTime mTime; const TimeStamp mJobStartTime; @@ -909,7 +909,7 @@ AuthCertificate(CertVerifier& certVerifier, TransportSecurityInfo* infoObject, SECStatus rv; - // TODO: Remove this after we switch to insanity::pkix as the + // TODO: Remove this after we switch to mozilla::pkix as the // only option if (certVerifier.mImplementation == CertVerifier::classic) { if (stapledOCSPResponse) { @@ -965,7 +965,7 @@ AuthCertificate(CertVerifier& certVerifier, TransportSecurityInfo* infoObject, bool saveIntermediates = !(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE); - insanity::pkix::ScopedCERTCertList certList; + mozilla::pkix::ScopedCERTCertList certList; SECOidTag evOidPolicy; rv = certVerifier.VerifySSLServerCert(cert, stapledOCSPResponse, time, infoObject, @@ -1090,11 +1090,11 @@ SSLServerCertVerificationJob::Run() failureTelemetry = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_CLASSIC; break; - case CertVerifier::insanity: + case CertVerifier::mozillapkix: successTelemetry - = Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_INSANITY; + = Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_MOZILLAPKIX; failureTelemetry - = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_INSANITY; + = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_MOZILLAPKIX; break; #ifndef NSS_NO_LIBPKIX case CertVerifier::libpkix: diff --git a/security/manager/ssl/src/TransportSecurityInfo.cpp b/security/manager/ssl/src/TransportSecurityInfo.cpp index 70a2edf0b545..22089205c426 100644 --- a/security/manager/ssl/src/TransportSecurityInfo.cpp +++ b/security/manager/ssl/src/TransportSecurityInfo.cpp @@ -6,7 +6,7 @@ #include "TransportSecurityInfo.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsNSSComponent.h" #include "nsIWebProgressListener.h" #include "nsNSSCertificate.h" @@ -755,7 +755,7 @@ AppendErrorTextMismatch(const nsString &host, const char16_t *params[1]; nsresult rv; - insanity::pkix::ScopedCERTCertificate nssCert; + mozilla::pkix::ScopedCERTCertificate nssCert; nsCOMPtr cert2 = do_QueryInterface(ix509, &rv); if (cert2) diff --git a/security/manager/ssl/src/moz.build b/security/manager/ssl/src/moz.build index 044e72e656b9..fa4282b5911e 100644 --- a/security/manager/ssl/src/moz.build +++ b/security/manager/ssl/src/moz.build @@ -95,7 +95,7 @@ FINAL_LIBRARY = 'xul' LOCAL_INCLUDES += [ '../../../certverifier', - '../../../insanity/include', + '../../../pkix/include', ] if CONFIG['NSS_DISABLE_DBM']: diff --git a/security/manager/ssl/src/nsCMS.cpp b/security/manager/ssl/src/nsCMS.cpp index 038b06c003a0..7ce78034a043 100644 --- a/security/manager/ssl/src/nsCMS.cpp +++ b/security/manager/ssl/src/nsCMS.cpp @@ -6,7 +6,7 @@ #include "nsCMS.h" #include "CertVerifier.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsISupports.h" #include "nsNSSHelper.h" #include "nsNSSCertificate.h" @@ -515,7 +515,7 @@ NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts) if (!nssRecipientCert) return NS_ERROR_FAILURE; - insanity::pkix::ScopedCERTCertificate c(nssRecipientCert->GetCert()); + mozilla::pkix::ScopedCERTCertificate c(nssRecipientCert->GetCert()); recipientCerts.set(i, c.get()); } @@ -553,7 +553,7 @@ NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts) // Create and attach recipient information // for (i=0; i < recipientCertCount; i++) { - insanity::pkix::ScopedCERTCertificate rc(recipientCerts.get(i)); + mozilla::pkix::ScopedCERTCertificate rc(recipientCerts.get(i)); if ((recipientInfo = NSS_CMSRecipientInfo_Create(m_cmsMsg, rc.get())) == nullptr) { PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create recipient info\n")); goto loser; @@ -584,8 +584,8 @@ NS_IMETHODIMP nsCMSMessage::CreateSigned(nsIX509Cert* aSigningCert, nsIX509Cert* NSSCMSContentInfo *cinfo; NSSCMSSignedData *sigd; NSSCMSSignerInfo *signerinfo; - insanity::pkix::ScopedCERTCertificate scert; - insanity::pkix::ScopedCERTCertificate ecert; + mozilla::pkix::ScopedCERTCertificate scert; + mozilla::pkix::ScopedCERTCertificate ecert; nsCOMPtr aSigningCert2 = do_QueryInterface(aSigningCert); nsresult rv = NS_ERROR_FAILURE; diff --git a/security/manager/ssl/src/nsCertOverrideService.cpp b/security/manager/ssl/src/nsCertOverrideService.cpp index 513dc37f4e28..d3c1f1d5fdcf 100644 --- a/security/manager/ssl/src/nsCertOverrideService.cpp +++ b/security/manager/ssl/src/nsCertOverrideService.cpp @@ -6,7 +6,7 @@ #include "nsCertOverrideService.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsIX509Cert.h" #include "NSSCertDBTrustDomain.h" #include "nsNSSCertificate.h" @@ -394,7 +394,7 @@ GetCertFingerprintByOidTag(nsIX509Cert *aCert, if (!cert2) return NS_ERROR_FAILURE; - insanity::pkix::ScopedCERTCertificate nsscert(cert2->GetCert()); + mozilla::pkix::ScopedCERTCertificate nsscert(cert2->GetCert()); if (!nsscert) return NS_ERROR_FAILURE; @@ -432,7 +432,7 @@ GetCertFingerprintByDottedOidString(nsIX509Cert *aCert, if (!cert2) return NS_ERROR_FAILURE; - insanity::pkix::ScopedCERTCertificate nsscert(cert2->GetCert()); + mozilla::pkix::ScopedCERTCertificate nsscert(cert2->GetCert()); if (!nsscert) return NS_ERROR_FAILURE; @@ -455,7 +455,7 @@ nsCertOverrideService::RememberValidityOverride(const nsACString & aHostName, in if (!cert2) return NS_ERROR_FAILURE; - insanity::pkix::ScopedCERTCertificate nsscert(cert2->GetCert()); + mozilla::pkix::ScopedCERTCertificate nsscert(cert2->GetCert()); if (!nsscert) return NS_ERROR_FAILURE; diff --git a/security/manager/ssl/src/nsCertPicker.cpp b/security/manager/ssl/src/nsCertPicker.cpp index 1f6bd50e1de6..156416b7e967 100644 --- a/security/manager/ssl/src/nsCertPicker.cpp +++ b/security/manager/ssl/src/nsCertPicker.cpp @@ -4,7 +4,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsCertPicker.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsMemory.h" #include "nsCOMPtr.h" #include "nsXPIDLString.h" @@ -50,14 +50,14 @@ NS_IMETHODIMP nsCertPicker::PickByUsage(nsIInterfaceRequestor *ctx, { // Iterate over all certs. This assures that user is logged in to all hardware tokens. nsCOMPtr ctx = new PipUIContext(); - insanity::pkix::ScopedCERTCertList allcerts( + mozilla::pkix::ScopedCERTCertList allcerts( PK11_ListCerts(PK11CertListUnique, ctx)); } /* find all user certs that are valid and for SSL */ /* note that we are allowing expired certs in this list */ - insanity::pkix::ScopedCERTCertList certList( + mozilla::pkix::ScopedCERTCertList certList( CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), (SECCertUsage)certUsage, !allowDuplicateNicknames, diff --git a/security/manager/ssl/src/nsCertTree.cpp b/security/manager/ssl/src/nsCertTree.cpp index 1ba654d978d6..3d4d0a9a5c7c 100644 --- a/security/manager/ssl/src/nsCertTree.cpp +++ b/security/manager/ssl/src/nsCertTree.cpp @@ -4,7 +4,7 @@ #include "nsCertTree.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsNSSComponent.h" // for PIPNSS string bundle calls. #include "nsITreeColumns.h" #include "nsIX509Cert.h" @@ -638,7 +638,7 @@ nsCertTree::GetCertsByType(uint32_t aType, { nsNSSShutDownPreventionLock locker; nsCOMPtr cxt = new PipUIContext(); - insanity::pkix::ScopedCERTCertList certList( + mozilla::pkix::ScopedCERTCertList certList( PK11_ListCerts(PK11CertListUnique, cxt)); return GetCertsByTypeFromCertList(certList.get(), aType, aCertCmpFn, aCertCmpFnArg); @@ -809,7 +809,7 @@ nsCertTree::DeleteEntryObject(uint32_t index) // although there are still overrides stored, // so, we keep the cert, but remove the trust - insanity::pkix::ScopedCERTCertificate nsscert; + mozilla::pkix::ScopedCERTCertificate nsscert; nsCOMPtr cert2 = do_QueryInterface(cert); if (cert2) { diff --git a/security/manager/ssl/src/nsCrypto.cpp b/security/manager/ssl/src/nsCrypto.cpp index 43f186e71ab8..286cfdceab37 100644 --- a/security/manager/ssl/src/nsCrypto.cpp +++ b/security/manager/ssl/src/nsCrypto.cpp @@ -70,7 +70,7 @@ #include "certdb.h" #include "secmod.h" #include "ScopedNSSTypes.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "ssl.h" // For SSL_ClearSessionCache @@ -1042,7 +1042,7 @@ nsSetEscrowAuthority(CRMFCertRequest *certReq, nsKeyPairInfo *keyInfo, CRMF_CertRequestIsControlPresent(certReq, crmfPKIArchiveOptionsControl)){ return NS_ERROR_FAILURE; } - insanity::pkix::ScopedCERTCertificate cert(wrappingCert->GetCert()); + mozilla::pkix::ScopedCERTCertificate cert(wrappingCert->GetCert()); if (!cert) return NS_ERROR_FAILURE; @@ -1942,7 +1942,7 @@ nsCrypto::GenerateCRMFRequest(JSContext* aContext, aRv.Throw(NS_ERROR_FAILURE); return nullptr; } - insanity::pkix::ScopedCERTCertificate cert( + mozilla::pkix::ScopedCERTCertificate cert( CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &certDer, nullptr, false, true)); if (!cert) { @@ -2211,7 +2211,7 @@ nsCertAlreadyExists(SECItem *derCert) CERTCertDBHandle *handle = CERT_GetDefaultCertDB(); bool retVal = false; - insanity::pkix::ScopedCERTCertificate cert( + mozilla::pkix::ScopedCERTCertificate cert( CERT_FindCertByDERCert(handle, derCert)); if (cert) { if (cert->isperm && !cert->nickname && !cert->emailAddr) { @@ -2373,7 +2373,7 @@ nsCrypto::ImportUserCertificates(const nsAString& aNickname, //Import the root chain into the cert db. { - insanity::pkix::ScopedCERTCertList + mozilla::pkix::ScopedCERTCertList caPubs(CMMF_CertRepContentGetCAPubs(certRepContent)); if (caPubs) { int32_t numCAs = nsCertListCount(caPubs.get()); diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index f54d97e9a1e5..f3a1668b6a81 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsNSSCallbacks.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "mozilla/Telemetry.h" #include "mozilla/TimeStamp.h" #include "nsNSSComponent.h" @@ -1189,7 +1189,7 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { nsContentUtils::LogSimpleConsoleError(msg, "SSL"); } - insanity::pkix::ScopedCERTCertificate serverCert(SSL_PeerCertificate(fd)); + mozilla::pkix::ScopedCERTCertificate serverCert(SSL_PeerCertificate(fd)); /* Set the SSL Status information */ RefPtr status(infoObject->SSLStatus()); diff --git a/security/manager/ssl/src/nsNSSCertCache.cpp b/security/manager/ssl/src/nsNSSCertCache.cpp index 7b0837a51401..c4ec7b1599f8 100644 --- a/security/manager/ssl/src/nsNSSCertCache.cpp +++ b/security/manager/ssl/src/nsNSSCertCache.cpp @@ -46,7 +46,7 @@ nsNSSCertCache::CacheAllCerts() nsCOMPtr cxt = new PipUIContext(); - insanity::pkix::ScopedCERTCertList newList( + mozilla::pkix::ScopedCERTCertList newList( PK11_ListCerts(PK11CertListUnique, cxt)); if (newList) { diff --git a/security/manager/ssl/src/nsNSSCertificate.cpp b/security/manager/ssl/src/nsNSSCertificate.cpp index 526535099155..9026ed6c6fce 100644 --- a/security/manager/ssl/src/nsNSSCertificate.cpp +++ b/security/manager/ssl/src/nsNSSCertificate.cpp @@ -10,7 +10,7 @@ #include "prprf.h" #include "CertVerifier.h" #include "ExtendedValidation.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsNSSComponent.h" // for PIPNSS string bundle calls. #include "nsNSSCleaner.h" #include "nsCOMPtr.h" @@ -822,7 +822,7 @@ nsNSSCertificate::GetChain(nsIArray** _rvChain) nsresult rv; PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Getting chain for \"%s\"\n", mCert->nickname)); - ::insanity::pkix::ScopedCERTCertList nssChain; + ::mozilla::pkix::ScopedCERTCertList nssChain; RefPtr certVerifier(GetDefaultCertVerifier()); NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED); @@ -1542,7 +1542,7 @@ nsNSSCertificate::GetValidEVPolicyOid(nsACString& outDottedOid) NS_IMPL_ISUPPORTS1(nsNSSCertList, nsIX509CertList) -nsNSSCertList::nsNSSCertList(insanity::pkix::ScopedCERTCertList& certList, +nsNSSCertList::nsNSSCertList(mozilla::pkix::ScopedCERTCertList& certList, const nsNSSShutDownPreventionLock& proofOfLock) { if (certList) { diff --git a/security/manager/ssl/src/nsNSSCertificate.h b/security/manager/ssl/src/nsNSSCertificate.h index 8be39f8e56e9..63b49a2e4237 100644 --- a/security/manager/ssl/src/nsNSSCertificate.h +++ b/security/manager/ssl/src/nsNSSCertificate.h @@ -19,7 +19,7 @@ #include "nsISimpleEnumerator.h" #include "nsISerializable.h" #include "nsIClassInfo.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "certt.h" class nsAutoString; @@ -54,7 +54,7 @@ public: static nsNSSCertificate* ConstructFromDER(char* certDER, int derLen); private: - insanity::pkix::ScopedCERTCertificate mCert; + mozilla::pkix::ScopedCERTCertificate mCert; bool mPermDelete; uint32_t mCertType; nsresult CreateASN1Struct(nsIASN1Object** aRetVal); @@ -81,7 +81,7 @@ public: NS_DECL_NSIX509CERTLIST // certList is adopted - nsNSSCertList(insanity::pkix::ScopedCERTCertList& certList, + nsNSSCertList(mozilla::pkix::ScopedCERTCertList& certList, const nsNSSShutDownPreventionLock& proofOfLock); nsNSSCertList(); @@ -94,7 +94,7 @@ private: virtual void virtualDestroyNSSReference(); void destructorSafeDestroyNSSReference(); - insanity::pkix::ScopedCERTCertList mCertList; + mozilla::pkix::ScopedCERTCertList mCertList; nsNSSCertList(const nsNSSCertList&) MOZ_DELETE; void operator=(const nsNSSCertList&) MOZ_DELETE; @@ -114,7 +114,7 @@ private: virtual void virtualDestroyNSSReference(); void destructorSafeDestroyNSSReference(); - insanity::pkix::ScopedCERTCertList mCertList; + mozilla::pkix::ScopedCERTCertList mCertList; nsNSSCertListEnumerator(const nsNSSCertListEnumerator&) MOZ_DELETE; void operator=(const nsNSSCertListEnumerator&) MOZ_DELETE; diff --git a/security/manager/ssl/src/nsNSSCertificateDB.cpp b/security/manager/ssl/src/nsNSSCertificateDB.cpp index a4b412b7cf42..eaea2c5ec51b 100644 --- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -13,7 +13,7 @@ #include "CertVerifier.h" #include "ExtendedValidation.h" #include "NSSCertDBTrustDomain.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsNSSComponent.h" #include "mozilla/Base64.h" #include "nsCOMPtr.h" @@ -113,7 +113,7 @@ nsNSSCertificateDB::FindCertByNickname(nsISupports *aToken, if (isAlreadyShutDown()) { return NS_ERROR_NOT_AVAILABLE; } - insanity::pkix::ScopedCERTCertificate cert; + mozilla::pkix::ScopedCERTCertificate cert; char *asciiname = nullptr; NS_ConvertUTF16toUTF8 aUtf8Nickname(nickname); asciiname = const_cast(aUtf8Nickname.get()); @@ -159,7 +159,7 @@ nsNSSCertificateDB::FindCertByDBKey(const char *aDBkey, nsISupports *aToken, return NS_ERROR_INVALID_ARG; } - insanity::pkix::ScopedCERTCertificate cert; + mozilla::pkix::ScopedCERTCertificate cert; // someday maybe we can speed up the search using the moduleID and slotID // moduleID = NS_NSS_GET_LONG(keyItem.data); // slotID = NS_NSS_GET_LONG(&keyItem.data[NS_NSS_LONG]); @@ -203,7 +203,7 @@ nsNSSCertificateDB::FindCertNicknames(nsISupports *aToken, /* * obtain the cert list from NSS */ - insanity::pkix::ScopedCERTCertList certList; + mozilla::pkix::ScopedCERTCertList certList; certList = PK11_ListCerts(PK11CertListUnique, nullptr); if (!certList) goto cleanup; @@ -358,7 +358,7 @@ nsNSSCertificateDB::handleCACertDownload(nsIArray *x509Certs, return rv; PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Creating temp cert\n")); - insanity::pkix::ScopedCERTCertificate tmpCert; + mozilla::pkix::ScopedCERTCertificate tmpCert; CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); tmpCert = CERT_FindCertByDERCert(certdb, &der); if (!tmpCert) { @@ -415,7 +415,7 @@ nsNSSCertificateDB::handleCACertDownload(nsIArray *x509Certs, // Import additional delivered certificates that can be verified. // build a CertList for filtering - insanity::pkix::ScopedCERTCertList certList(CERT_NewCertList()); + mozilla::pkix::ScopedCERTCertList certList(CERT_NewCertList()); if (!certList) { return NS_ERROR_FAILURE; } @@ -511,7 +511,7 @@ nsNSSCertificateDB::ImportCertificates(uint8_t * data, uint32_t length, static SECStatus ImportCertsIntoPermanentStorage( - const insanity::pkix::ScopedCERTCertList& certChain, + const mozilla::pkix::ScopedCERTCertList& certChain, const SECCertUsage usage, const PRBool caOnly) { CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); @@ -561,7 +561,7 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length, nsresult nsrv = NS_OK; CERTCertDBHandle *certdb; CERTCertificate **certArray = nullptr; - insanity::pkix::ScopedCERTCertList certList; + mozilla::pkix::ScopedCERTCertList certList; CERTCertListNode *node; SECItem **rawArray; int numcerts; @@ -632,7 +632,7 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length, continue; } - insanity::pkix::ScopedCERTCertList certChain; + mozilla::pkix::ScopedCERTCertList certChain; SECStatus rv = certVerifier->VerifyCert(node->cert, nullptr, certificateUsageEmailRecipient, @@ -673,7 +673,7 @@ nsNSSCertificateDB::ImportServerCertificate(uint8_t * data, uint32_t length, SECStatus srv = SECFailure; nsresult nsrv = NS_OK; - insanity::pkix::ScopedCERTCertificate cert; + mozilla::pkix::ScopedCERTCertificate cert; SECItem **rawCerts = nullptr; int numcerts; int i; @@ -800,7 +800,7 @@ nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfac for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node,certList); node = CERT_LIST_NEXT(node)) { - insanity::pkix::ScopedCERTCertList certChain; + mozilla::pkix::ScopedCERTCertList certChain; SECStatus rv = certVerifier->VerifyCert(node->cert, nullptr, certificateUsageVerifyCA, PR_Now(), ctx, 0, &certChain); @@ -877,7 +877,7 @@ nsNSSCertificateDB::ImportUserCertificate(uint8_t *data, uint32_t length, nsIInt SECItem *CACerts; CERTDERCerts * collectArgs; PLArenaPool *arena; - insanity::pkix::ScopedCERTCertificate cert; + mozilla::pkix::ScopedCERTCertificate cert; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (!arena) { @@ -954,7 +954,7 @@ nsNSSCertificateDB::DeleteCertificate(nsIX509Cert *aCert) return NS_ERROR_NOT_AVAILABLE; } nsCOMPtr nssCert = do_QueryInterface(aCert); - insanity::pkix::ScopedCERTCertificate cert(nssCert->GetCert()); + mozilla::pkix::ScopedCERTCertificate cert(nssCert->GetCert()); if (!cert) return NS_ERROR_FAILURE; SECStatus srv = SECSuccess; @@ -1001,7 +1001,7 @@ nsNSSCertificateDB::SetCertTrust(nsIX509Cert *cert, if (!pipCert) { return rv; } - insanity::pkix::ScopedCERTCertificate nsscert(pipCert->GetCert()); + mozilla::pkix::ScopedCERTCertificate nsscert(pipCert->GetCert()); rv = attemptToLogInWithDefaultPassword(); if (NS_WARN_IF(rv != NS_OK)) { @@ -1054,7 +1054,7 @@ nsNSSCertificateDB::IsCertTrusted(nsIX509Cert *cert, } SECStatus srv; nsCOMPtr pipCert = do_QueryInterface(cert); - insanity::pkix::ScopedCERTCertificate nsscert(pipCert->GetCert()); + mozilla::pkix::ScopedCERTCertificate nsscert(pipCert->GetCert()); CERTCertTrust nsstrust; srv = CERT_GetCertTrust(nsscert.get(), &nsstrust); if (srv != SECSuccess) @@ -1302,7 +1302,7 @@ nsNSSCertificateDB::FindEmailEncryptionCert(const nsAString &aNickname, nsIX509C asciiname = const_cast(aUtf8Nickname.get()); /* Find a good cert in the user's database */ - insanity::pkix::ScopedCERTCertificate cert; + mozilla::pkix::ScopedCERTCertificate cert; cert = CERT_FindUserCertByUsage(CERT_GetDefaultCertDB(), asciiname, certUsageEmailRecipient, true, ctx); if (!cert) { @@ -1332,7 +1332,7 @@ nsNSSCertificateDB::FindEmailSigningCert(const nsAString &aNickname, nsIX509Cert return NS_ERROR_NOT_AVAILABLE; } - insanity::pkix::ScopedCERTCertificate cert; + mozilla::pkix::ScopedCERTCertificate cert; nsCOMPtr ctx = new PipUIContext(); char *asciiname = nullptr; NS_ConvertUTF16toUTF8 aUtf8Nickname(aNickname); @@ -1462,7 +1462,7 @@ nsNSSCertificateDB::ConstructX509(const char* certDER, secitem_cert.data = (unsigned char*)certDER; secitem_cert.len = lengthDER; - insanity::pkix::ScopedCERTCertificate cert; + mozilla::pkix::ScopedCERTCertificate cert; cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &secitem_cert, nullptr, false, true); @@ -1561,7 +1561,7 @@ nsNSSCertificateDB::get_default_nickname(CERTCertificate *cert, PR_smprintf_free(tmp); } - insanity::pkix::ScopedCERTCertificate dummycert; + mozilla::pkix::ScopedCERTCertificate dummycert; if (PK11_IsInternal(slot)) { /* look up the nickname to make sure it isn't in use already */ @@ -1622,7 +1622,7 @@ NS_IMETHODIMP nsNSSCertificateDB::AddCertFromBase64(const char *aBase64, const c PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("Creating temp cert\n")); CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); - insanity::pkix::ScopedCERTCertificate tmpCert(CERT_FindCertByDERCert(certdb, &der)); + mozilla::pkix::ScopedCERTCertificate tmpCert(CERT_FindCertByDERCert(certdb, &der)); if (!tmpCert) tmpCert = CERT_NewTempCertificate(certdb, &der, nullptr, false, true); @@ -1677,7 +1677,7 @@ nsNSSCertificateDB::SetCertTrustFromString(nsIX509Cert3* cert, if (srv != SECSuccess) { return MapSECStatus(SECFailure); } - insanity::pkix::ScopedCERTCertificate nssCert(cert->GetCert()); + mozilla::pkix::ScopedCERTCertificate nssCert(cert->GetCert()); nsresult rv = attemptToLogInWithDefaultPassword(); if (NS_WARN_IF(rv != NS_OK)) { @@ -1698,7 +1698,7 @@ nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval) nsCOMPtr ctx = new PipUIContext(); nsCOMPtr nssCertList; - insanity::pkix::ScopedCERTCertList certList( + mozilla::pkix::ScopedCERTCertList certList( PK11_ListCerts(PK11CertListUnique, ctx)); // nsNSSCertList 1) adopts certList, and 2) handles the nullptr case fine. @@ -1768,7 +1768,7 @@ nsNSSCertificateDB::VerifyCertNow(nsIX509Cert* aCert, RefPtr certVerifier(GetDefaultCertVerifier()); NS_ENSURE_TRUE(certVerifier, NS_ERROR_FAILURE); - insanity::pkix::ScopedCERTCertList resultChain; + mozilla::pkix::ScopedCERTCertList resultChain; SECOidTag evOidPolicy; SECStatus srv; @@ -1811,7 +1811,7 @@ nsNSSCertificateDB::ClearOCSPCache() RefPtr certVerifier(GetDefaultCertVerifier()); NS_ENSURE_TRUE(certVerifier, NS_ERROR_FAILURE); - if (certVerifier->mImplementation == CertVerifier::insanity) { + if (certVerifier->mImplementation == CertVerifier::mozillapkix) { certVerifier->ClearOCSPCache(); } else { SECStatus srv = CERT_ClearOCSPCache(); diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 7db1ac1414ae..5bdd8ab9eff8 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -971,9 +971,9 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting, CertVerifier::implementation_config certVerifierImplementation = CertVerifier::classic; - // The insanity::pkix pref overrides the libpkix pref - if (Preferences::GetBool("security.use_insanity_verification", false)) { - certVerifierImplementation = CertVerifier::insanity; + // The mozilla::pkix pref overrides the libpkix pref + if (Preferences::GetBool("security.use_mozillapkix_verification", false)) { + certVerifierImplementation = CertVerifier::mozillapkix; } else { #ifndef NSS_NO_LIBPKIX if (Preferences::GetBool("security.use_libpkix_verification", false)) { @@ -997,9 +997,9 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting, #endif odc, osc, ogc); - // insanity::pkix has its own OCSP cache, so disable the NSS cache + // mozilla::pkix has its own OCSP cache, so disable the NSS cache // if appropriate. - if (certVerifierImplementation == CertVerifier::insanity) { + if (certVerifierImplementation == CertVerifier::mozillapkix) { // Using -1 disables the cache. The other arguments are the default // values and aren't exposed by the API. CERT_OCSPCacheSettings(-1, 1*60*60L, 24*60*60L); @@ -1617,7 +1617,7 @@ nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic, || prefName.Equals("security.OCSP.require") || prefName.Equals("security.OCSP.GET.enabled") || prefName.Equals("security.ssl.enable_ocsp_stapling") - || prefName.Equals("security.use_insanity_verification") + || prefName.Equals("security.use_mozillapkix_verification") || prefName.Equals("security.use_libpkix_verification")) { MutexAutoLock lock(mutex); setValidationOptions(false, lock); diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index dd0104e80979..eb73317baeff 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -6,7 +6,7 @@ #include "nsNSSIOLayer.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsNSSComponent.h" #include "mozilla/Casting.h" #include "mozilla/DebugOnly.h" @@ -1870,9 +1870,9 @@ ClientAuthDataRunnable::RunOnTargetThread() { PLArenaPool* arena = nullptr; char** caNameStrings; - insanity::pkix::ScopedCERTCertificate cert; + mozilla::pkix::ScopedCERTCertificate cert; ScopedSECKEYPrivateKey privKey; - insanity::pkix::ScopedCERTCertList certList; + mozilla::pkix::ScopedCERTCertList certList; CERTCertListNode* node; ScopedCERTCertNicknames nicknames; char* extracted = nullptr; diff --git a/security/manager/ssl/src/nsPKCS12Blob.cpp b/security/manager/ssl/src/nsPKCS12Blob.cpp index 6898d8ac50aa..70e7a73b4dc2 100644 --- a/security/manager/ssl/src/nsPKCS12Blob.cpp +++ b/security/manager/ssl/src/nsPKCS12Blob.cpp @@ -5,7 +5,7 @@ #include "nsPKCS12Blob.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "prmem.h" #include "prprf.h" @@ -307,7 +307,7 @@ nsPKCS12Blob::ExportToFile(nsIFile *file, for (i=0; iGetCert()); + mozilla::pkix::ScopedCERTCertificate nssCert(cert->GetCert()); if (!nssCert) { rv = NS_ERROR_FAILURE; goto finish; diff --git a/security/manager/ssl/src/nsRecentBadCerts.cpp b/security/manager/ssl/src/nsRecentBadCerts.cpp index 741cf83bf2f0..e747600940c6 100644 --- a/security/manager/ssl/src/nsRecentBadCerts.cpp +++ b/security/manager/ssl/src/nsRecentBadCerts.cpp @@ -6,7 +6,7 @@ #include "nsRecentBadCerts.h" -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "nsIX509Cert.h" #include "nsIObserverService.h" #include "mozilla/RefPtr.h" @@ -72,7 +72,7 @@ nsRecentBadCerts::GetRecentBadCert(const nsAString & aHostNameWithPort, if (foundDER.len) { CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); - insanity::pkix::ScopedCERTCertificate nssCert( + mozilla::pkix::ScopedCERTCertificate nssCert( CERT_FindCertByDERCert(certdb, &foundDER)); if (!nssCert) nssCert = CERT_NewTempCertificate(certdb, &foundDER, diff --git a/security/manager/ssl/tests/gtest/moz.build b/security/manager/ssl/tests/gtest/moz.build index 1e77b651be96..68350145578a 100644 --- a/security/manager/ssl/tests/gtest/moz.build +++ b/security/manager/ssl/tests/gtest/moz.build @@ -15,7 +15,7 @@ SOURCES += [ LOCAL_INCLUDES += [ '../../../../certverifier', - '../../../../insanity/include', + '../../../../pkix/include', '/security/manager/ssl/src', ] diff --git a/security/manager/ssl/tests/unit/test_cert_overrides.js b/security/manager/ssl/tests/unit/test_cert_overrides.js index 43a839be7816..bae9fdc4f438 100644 --- a/security/manager/ssl/tests/unit/test_cert_overrides.js +++ b/security/manager/ssl/tests/unit/test_cert_overrides.js @@ -72,16 +72,16 @@ function run_test() { run_next_test(); } -function add_tests_in_mode(useInsanity) { +function add_tests_in_mode(useMozillaPKIX) { add_test(function () { - Services.prefs.setBoolPref("security.use_insanity_verification", - useInsanity); + Services.prefs.setBoolPref("security.use_mozillapkix_verification", + useMozillaPKIX); run_next_test(); }); - add_simple_tests(useInsanity); - add_combo_tests(useInsanity); - add_distrust_tests(useInsanity); + add_simple_tests(useMozillaPKIX); + add_combo_tests(useMozillaPKIX); + add_distrust_tests(useMozillaPKIX); add_test(function () { certOverrideService.clearValidityOverride("all:temporary-certificates", 0); @@ -89,23 +89,23 @@ function add_tests_in_mode(useInsanity) { }); } -function add_simple_tests(useInsanity) { +function add_simple_tests(useMozillaPKIX) { add_cert_override_test("expired.example.com", Ci.nsICertOverrideService.ERROR_TIME, getXPCOMStatusFromNSS(SEC_ERROR_EXPIRED_CERTIFICATE)); add_cert_override_test("selfsigned.example.com", Ci.nsICertOverrideService.ERROR_UNTRUSTED, getXPCOMStatusFromNSS( - useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_CA_CERT_INVALID)); + useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_CA_CERT_INVALID)); add_cert_override_test("unknownissuer.example.com", Ci.nsICertOverrideService.ERROR_UNTRUSTED, getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_ISSUER)); add_cert_override_test("expiredissuer.example.com", Ci.nsICertOverrideService.ERROR_UNTRUSTED, getXPCOMStatusFromNSS( - useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE)); + useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE)); add_cert_override_test("md5signature.example.com", Ci.nsICertOverrideService.ERROR_UNTRUSTED, getXPCOMStatusFromNSS( @@ -122,16 +122,16 @@ function add_simple_tests(useInsanity) { // (i.e. itself). As a result, to be able to override this, // SEC_ERROR_INADEQUATE_KEY_USAGE must be overridable (although, // confusingly, this isn't the main error reported). - // insanity::pkix just says this certificate's issuer is unknown. + // mozilla::pkix just says this certificate's issuer is unknown. add_cert_override_test("selfsigned-inadequateEKU.example.com", Ci.nsICertOverrideService.ERROR_UNTRUSTED, getXPCOMStatusFromNSS( - useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_CA_CERT_INVALID)); + useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_CA_CERT_INVALID)); // SEC_ERROR_INADEQUATE_KEY_USAGE is overridable in general for - // classic verification, but not for insanity::pkix verification. - if (useInsanity) { + // classic verification, but not for mozilla::pkix verification. + if (useMozillaPKIX) { add_connection_test("inadequatekeyusage.example.com", getXPCOMStatusFromNSS(SEC_ERROR_INADEQUATE_KEY_USAGE), null, @@ -149,9 +149,9 @@ function add_simple_tests(useInsanity) { } } -function add_combo_tests(useInsanity) { +function add_combo_tests(useMozillaPKIX) { // Note that "untrusted" here really is "unknown issuer" in the - // insanity::pkix case. + // mozilla::pkix case. add_cert_override_test("mismatch-expired.example.com", Ci.nsICertOverrideService.ERROR_MISMATCH | @@ -161,21 +161,21 @@ function add_combo_tests(useInsanity) { Ci.nsICertOverrideService.ERROR_MISMATCH | Ci.nsICertOverrideService.ERROR_UNTRUSTED, getXPCOMStatusFromNSS( - useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER)); + useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER)); add_cert_override_test("untrusted-expired.example.com", Ci.nsICertOverrideService.ERROR_UNTRUSTED | Ci.nsICertOverrideService.ERROR_TIME, getXPCOMStatusFromNSS( - useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER)); + useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER)); add_cert_override_test("mismatch-untrusted-expired.example.com", Ci.nsICertOverrideService.ERROR_MISMATCH | Ci.nsICertOverrideService.ERROR_UNTRUSTED | Ci.nsICertOverrideService.ERROR_TIME, getXPCOMStatusFromNSS( - useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER)); + useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER)); add_cert_override_test("md5signature-expired.example.com", Ci.nsICertOverrideService.ERROR_UNTRUSTED | @@ -184,7 +184,7 @@ function add_combo_tests(useInsanity) { SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)); } -function add_distrust_tests(useInsanity) { +function add_distrust_tests(useMozillaPKIX) { // Before we specifically distrust this certificate, it should be trusted. add_connection_test("untrusted.example.com", Cr.NS_OK); @@ -193,7 +193,7 @@ function add_distrust_tests(useInsanity) { add_distrust_override_test("tlsserver/default-ee.der", "untrusted.example.com", getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_CERT), - useInsanity + useMozillaPKIX ? getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_CERT) : Cr.NS_OK); @@ -202,7 +202,7 @@ function add_distrust_tests(useInsanity) { add_distrust_override_test("tlsserver/other-test-ca.der", "untrustedissuer.example.com", getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER), - useInsanity + useMozillaPKIX ? getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER) : Cr.NS_OK); } diff --git a/security/manager/ssl/tests/unit/test_cert_signatures.js b/security/manager/ssl/tests/unit/test_cert_signatures.js index 097140930820..0c104e6245e5 100644 --- a/security/manager/ssl/tests/unit/test_cert_signatures.js +++ b/security/manager/ssl/tests/unit/test_cert_signatures.js @@ -49,8 +49,8 @@ function run_test() { run_test_in_mode(false); } -function run_test_in_mode(useInsanity) { - Services.prefs.setBoolPref("security.use_insanity_verification", useInsanity); +function run_test_in_mode(useMozillaPKIX) { + Services.prefs.setBoolPref("security.use_mozillapkix_verification", useMozillaPKIX); clearOCSPCache(); clearSessionCache(); @@ -58,14 +58,14 @@ function run_test_in_mode(useInsanity) { check_ca("ca-p384"); check_ca("ca-dsa"); - // insanity::pkix does not allow CA certs to be validated for end-entity + // mozilla::pkix does not allow CA certs to be validated for end-entity // usages. - let int_usage = useInsanity + let int_usage = useMozillaPKIX ? 'SSL CA' : 'Client,Server,Sign,Encrypt,SSL CA,Status Responder'; - // insanity::pkix doesn't implement the Netscape Object Signer restriction. - const ee_usage = useInsanity + // mozilla::pkix doesn't implement the Netscape Object Signer restriction. + const ee_usage = useMozillaPKIX ? 'Client,Server,Sign,Encrypt,Object Signer' : 'Client,Server,Sign,Encrypt'; diff --git a/security/manager/ssl/tests/unit/test_cert_trust.js b/security/manager/ssl/tests/unit/test_cert_trust.js index 41c34a7e6caf..9a522f3b149d 100644 --- a/security/manager/ssl/tests/unit/test_cert_trust.js +++ b/security/manager/ssl/tests/unit/test_cert_trust.js @@ -39,20 +39,20 @@ function check_cert_err_generic(cert, expected_error, usage) { do_check_eq(error, expected_error); }; -function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useInsanity) { +function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKIX) { // On reset most usages are successful check_cert_err_generic(ee_cert, 0, certificateUsageSSLServer); check_cert_err_generic(ee_cert, 0, certificateUsageSSLClient); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageSSLCA); // expected no bc check_cert_err_generic(ee_cert, 0, certificateUsageEmailSigner); check_cert_err_generic(ee_cert, 0, certificateUsageEmailRecipient); - check_cert_err_generic(ee_cert, useInsanity ? 0 - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? 0 + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); // expected - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INVALID_ARGS, certificateUsageVerifyCA); // expected no bc check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); //expected @@ -64,18 +64,18 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useInsanity) certificateUsageSSLServer); check_cert_err_generic(ee_cert, SEC_ERROR_UNTRUSTED_ISSUER, certificateUsageSSLClient); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageSSLCA); check_cert_err_generic(ee_cert, SEC_ERROR_UNTRUSTED_ISSUER, certificateUsageEmailSigner); check_cert_err_generic(ee_cert, SEC_ERROR_UNTRUSTED_ISSUER, certificateUsageEmailRecipient); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_UNTRUSTED_ISSUER - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_UNTRUSTED_ISSUER + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INVALID_ARGS, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -84,34 +84,34 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useInsanity) // Trust set to T - trusted CA to issue client certs, where client cert is // usageSSLClient. setCertTrust(cert_to_modify_trust, 'T,T,T'); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER : 0, certificateUsageSSLServer); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER //XXX Bug 982340 - : 0 + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER //XXX Bug 982340 + : 0 : 0, certificateUsageSSLClient); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageSSLCA); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER : 0, certificateUsageEmailSigner); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER : 0, certificateUsageEmailRecipient); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_INADEQUATE_CERT_TYPE - : useInsanity ? 0 - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_INADEQUATE_CERT_TYPE + : useMozillaPKIX ? 0 + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INVALID_ARGS, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -121,43 +121,43 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useInsanity) setCertTrust(cert_to_modify_trust, 'p,C,C'); check_cert_err_generic(ee_cert, SEC_ERROR_UNTRUSTED_ISSUER, certificateUsageSSLServer); - check_cert_err_generic(ee_cert, useInsanity ? 0 //XXX Bug 982340 - : SEC_ERROR_UNTRUSTED_ISSUER, + check_cert_err_generic(ee_cert, useMozillaPKIX ? 0 //XXX Bug 982340 + : SEC_ERROR_UNTRUSTED_ISSUER, certificateUsageSSLClient); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageSSLCA); check_cert_err_generic(ee_cert, 0, certificateUsageEmailSigner); check_cert_err_generic(ee_cert, 0, certificateUsageEmailRecipient); - check_cert_err_generic(ee_cert, useInsanity ? 0 - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? 0 + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INVALID_ARGS, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); // Inherited trust SSL setCertTrust(cert_to_modify_trust, ',C,C'); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER : 0, certificateUsageSSLServer); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? 0 // XXX Bug 982340 - : SEC_ERROR_UNTRUSTED_ISSUER + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? 0 // XXX Bug 982340 + : SEC_ERROR_UNTRUSTED_ISSUER : 0, certificateUsageSSLClient); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageSSLCA); check_cert_err_generic(ee_cert, 0, certificateUsageEmailSigner); check_cert_err_generic(ee_cert, 0, certificateUsageEmailRecipient); - check_cert_err_generic(ee_cert, useInsanity ? 0 - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? 0 + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INVALID_ARGS, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -166,21 +166,21 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useInsanity) setCertTrust(cert_to_modify_trust, 'C,p,C'); check_cert_err_generic(ee_cert, 0, certificateUsageSSLServer); check_cert_err_generic(ee_cert, isRootCA ? SEC_ERROR_UNTRUSTED_ISSUER - : useInsanity ? SEC_ERROR_UNTRUSTED_ISSUER - : 0, // Insanity is OK, NSS bug + : useMozillaPKIX ? SEC_ERROR_UNTRUSTED_ISSUER + : 0, // Insanity is OK, NSS bug certificateUsageSSLClient); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageSSLCA); check_cert_err_generic(ee_cert, SEC_ERROR_UNTRUSTED_ISSUER, certificateUsageEmailSigner); check_cert_err_generic(ee_cert, SEC_ERROR_UNTRUSTED_ISSUER, certificateUsageEmailRecipient); - check_cert_err_generic(ee_cert, useInsanity ? 0 - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? 0 + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INVALID_ARGS, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); @@ -189,34 +189,34 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useInsanity) //inherited EMAIL Trust setCertTrust(cert_to_modify_trust, 'C,,C'); check_cert_err_generic(ee_cert, 0, certificateUsageSSLServer); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER : 0, certificateUsageSSLClient); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageSSLCA); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER : 0, certificateUsageEmailSigner); - check_cert_err_generic(ee_cert, isRootCA ? useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER + check_cert_err_generic(ee_cert, isRootCA ? useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER : 0, certificateUsageEmailRecipient); - check_cert_err_generic(ee_cert, useInsanity ? 0 - : SEC_ERROR_INADEQUATE_CERT_TYPE, + check_cert_err_generic(ee_cert, useMozillaPKIX ? 0 + : SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageObjectSigner); - check_cert_err_generic(ee_cert, useInsanity ? SEC_ERROR_CA_CERT_INVALID - : SEC_ERROR_INVALID_ARGS, + check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID + : SEC_ERROR_INVALID_ARGS, certificateUsageVerifyCA); check_cert_err_generic(ee_cert, SEC_ERROR_INADEQUATE_CERT_TYPE, certificateUsageStatusResponder); } -function run_test_in_mode(useInsanity) { - Services.prefs.setBoolPref("security.use_insanity_verification", useInsanity); +function run_test_in_mode(useMozillaPKIX) { + Services.prefs.setBoolPref("security.use_mozillapkix_verification", useMozillaPKIX); let ca_cert = certdb.findCertByNickname(null, 'ca'); do_check_false(!ca_cert) @@ -226,10 +226,10 @@ function run_test_in_mode(useInsanity) { do_check_false(!ee_cert); setup_basic_trusts(ca_cert, int_cert); - test_ca_distrust(ee_cert, ca_cert, true, useInsanity); + test_ca_distrust(ee_cert, ca_cert, true, useMozillaPKIX); setup_basic_trusts(ca_cert, int_cert); - test_ca_distrust(ee_cert, int_cert, false, useInsanity); + test_ca_distrust(ee_cert, int_cert, false, useMozillaPKIX); } function run_test() { diff --git a/security/manager/ssl/tests/unit/test_certificate_usages.js b/security/manager/ssl/tests/unit/test_certificate_usages.js index 4b0be71d5d4d..aee7d81898ec 100644 --- a/security/manager/ssl/tests/unit/test_certificate_usages.js +++ b/security/manager/ssl/tests/unit/test_certificate_usages.js @@ -35,36 +35,36 @@ function run_test() { run_test_in_mode(false); } -function run_test_in_mode(useInsanity) { - Services.prefs.setBoolPref("security.use_insanity_verification", useInsanity); +function run_test_in_mode(useMozillaPKIX) { + Services.prefs.setBoolPref("security.use_mozillapkix_verification", useMozillaPKIX); clearOCSPCache(); clearSessionCache(); - // insanity::pkix does not allow CA certs to be validated for non-CA usages. - var allCAUsages = useInsanity + // mozilla::pkix does not allow CA certs to be validated for non-CA usages. + var allCAUsages = useMozillaPKIX ? 'SSL CA' : 'Client,Server,Sign,Encrypt,SSL CA,Status Responder'; - // insanity::pkix doesn't allow CA certificates to have the Status Responder + // mozilla::pkix doesn't allow CA certificates to have the Status Responder // EKU. var ca_usages = [allCAUsages, 'SSL CA', allCAUsages, - useInsanity ? '' - : 'Client,Server,Sign,Encrypt,Status Responder']; + useMozillaPKIX ? '' + : 'Client,Server,Sign,Encrypt,Status Responder']; - // insanity::pkix doesn't implement the Netscape Object Signer restriction. - var basicEndEntityUsages = useInsanity + // mozilla::pkix doesn't implement the Netscape Object Signer restriction. + var basicEndEntityUsages = useMozillaPKIX ? 'Client,Server,Sign,Encrypt,Object Signer' : 'Client,Server,Sign,Encrypt'; var basicEndEntityUsagesWithObjectSigner = basicEndEntityUsages + ",Object Signer" - // insanity::pkix won't let a certificate with the "Status Responder" EKU get + // mozilla::pkix won't let a certificate with the "Status Responder" EKU get // validated for any other usage. - var statusResponderUsages = (useInsanity ? "" : "Server,") + "Status Responder"; + var statusResponderUsages = (useMozillaPKIX ? "" : "Server,") + "Status Responder"; var statusResponderUsagesFull - = useInsanity ? statusResponderUsages - : basicEndEntityUsages + ',Object Signer,Status Responder'; + = useMozillaPKIX ? statusResponderUsages + : basicEndEntityUsages + ',Object Signer,Status Responder'; var ee_usages = [ [ basicEndEntityUsages, @@ -101,16 +101,16 @@ function run_test_in_mode(useInsanity) { // // The 'classic' NSS mode uses the 'union' of the // capabilites so the cert is considered a CA. - // insanity::pkix and libpkix use the intersection of + // mozilla::pkix and libpkix use the intersection of // capabilites, so the cert is NOT considered a CA. - [ useInsanity ? '' : basicEndEntityUsages, - useInsanity ? '' : basicEndEntityUsages, - useInsanity ? '' : basicEndEntityUsages, + [ useMozillaPKIX ? '' : basicEndEntityUsages, + useMozillaPKIX ? '' : basicEndEntityUsages, + useMozillaPKIX ? '' : basicEndEntityUsages, '', - useInsanity ? '' : statusResponderUsagesFull, - useInsanity ? '' : 'Client,Server', - useInsanity ? '' : 'Sign,Encrypt,Object Signer', - useInsanity ? '' : 'Server,Status Responder' + useMozillaPKIX ? '' : statusResponderUsagesFull, + useMozillaPKIX ? '' : 'Client,Server', + useMozillaPKIX ? '' : 'Sign,Encrypt,Object Signer', + useMozillaPKIX ? '' : 'Server,Status Responder' ] ]; diff --git a/security/manager/ssl/tests/unit/test_ev_certs.js b/security/manager/ssl/tests/unit/test_ev_certs.js index ee440f4b3dbc..682a3b675db3 100644 --- a/security/manager/ssl/tests/unit/test_ev_certs.js +++ b/security/manager/ssl/tests/unit/test_ev_certs.js @@ -119,11 +119,11 @@ function run_test() { run_next_test(); } -function add_tests_in_mode(useInsanity) +function add_tests_in_mode(useMozillaPKIX) { add_test(function () { - Services.prefs.setBoolPref("security.use_insanity_verification", - useInsanity); + Services.prefs.setBoolPref("security.use_mozillapkix_verification", + useMozillaPKIX); run_next_test(); }); @@ -162,8 +162,8 @@ function add_tests_in_mode(useInsanity) clearOCSPCache(); let ocspResponder = failingOCSPResponder(); check_cert_err("ev-valid", - useInsanity ? SEC_ERROR_UNKNOWN_ISSUER - : SEC_ERROR_UNTRUSTED_ISSUER); + useMozillaPKIX ? SEC_ERROR_UNKNOWN_ISSUER + : SEC_ERROR_UNTRUSTED_ISSUER); ocspResponder.stop(run_next_test); }); @@ -186,23 +186,23 @@ function add_tests_in_mode(useInsanity) add_test(function () { check_no_ocsp_requests("ev-valid", - useInsanity ? SEC_ERROR_POLICY_VALIDATION_FAILED - : (isDebugBuild ? SEC_ERROR_REVOKED_CERTIFICATE - : SEC_ERROR_EXTENSION_NOT_FOUND)); + useMozillaPKIX ? SEC_ERROR_POLICY_VALIDATION_FAILED + : (isDebugBuild ? SEC_ERROR_REVOKED_CERTIFICATE + : SEC_ERROR_EXTENSION_NOT_FOUND)); }); add_test(function () { check_no_ocsp_requests("non-ev-root", - useInsanity ? SEC_ERROR_POLICY_VALIDATION_FAILED - : (isDebugBuild ? SEC_ERROR_UNTRUSTED_ISSUER - : SEC_ERROR_EXTENSION_NOT_FOUND)); + useMozillaPKIX ? SEC_ERROR_POLICY_VALIDATION_FAILED + : (isDebugBuild ? SEC_ERROR_UNTRUSTED_ISSUER + : SEC_ERROR_EXTENSION_NOT_FOUND)); }); add_test(function () { check_no_ocsp_requests("no-ocsp-url-cert", - useInsanity ? SEC_ERROR_POLICY_VALIDATION_FAILED - : (isDebugBuild ? SEC_ERROR_REVOKED_CERTIFICATE - : SEC_ERROR_EXTENSION_NOT_FOUND)); + useMozillaPKIX ? SEC_ERROR_POLICY_VALIDATION_FAILED + : (isDebugBuild ? SEC_ERROR_REVOKED_CERTIFICATE + : SEC_ERROR_EXTENSION_NOT_FOUND)); }); // Test the EV continues to work with flags after successful EV verification @@ -226,8 +226,8 @@ function add_tests_in_mode(useInsanity) do_check_eq(hasEVPolicy.value, isDebugBuild); do_check_eq(error, isDebugBuild ? 0 - : (useInsanity ? SEC_ERROR_POLICY_VALIDATION_FAILED - : SEC_ERROR_EXTENSION_NOT_FOUND)); + : (useMozillaPKIX ? SEC_ERROR_POLICY_VALIDATION_FAILED + : SEC_ERROR_EXTENSION_NOT_FOUND)); failingOcspResponder.stop(run_next_test); }); }); diff --git a/security/manager/ssl/tests/unit/test_getchain.js b/security/manager/ssl/tests/unit/test_getchain.js index 7510f5db1df0..911b56fe6e04 100644 --- a/security/manager/ssl/tests/unit/test_getchain.js +++ b/security/manager/ssl/tests/unit/test_getchain.js @@ -70,8 +70,8 @@ function check_getchain(ee_cert, ssl_ca, email_ca){ check_matching_issuer_and_getchain(ee_cert.issuer.serialNumber, ee_cert); } -function run_test_in_mode(useInsanity) { - Services.prefs.setBoolPref("security.use_insanity_verification", useInsanity); +function run_test_in_mode(useMozillaPKIX) { + Services.prefs.setBoolPref("security.use_mozillapkix_verification", useMozillaPKIX); clearOCSPCache(); clearSessionCache(); diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js index 72aa31bca5c4..675ae5d75821 100644 --- a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js @@ -38,18 +38,18 @@ function test_cert_for_usages(certChainNicks, expected_usages_string) { do_check_eq(expected_usages_string, usages.value); } -function run_test_in_mode(useInsanity) { - Services.prefs.setBoolPref("security.use_insanity_verification", useInsanity); +function run_test_in_mode(useMozillaPKIX) { + Services.prefs.setBoolPref("security.use_mozillapkix_verification", useMozillaPKIX); - // insanity::pkix doesn't support the obsolete Netscape object signing + // mozilla::pkix doesn't support the obsolete Netscape object signing // extension, but NSS does. - let ee_usage1 = useInsanity + let ee_usage1 = useMozillaPKIX ? 'Client,Server,Sign,Encrypt,Object Signer' : 'Client,Server,Sign,Encrypt' - // insanity::pkix doesn't validate CA certificates for non-CA uses, but + // mozilla::pkix doesn't validate CA certificates for non-CA uses, but // NSS does. - let ca_usage1 = useInsanity + let ca_usage1 = useMozillaPKIX ? "SSL CA" : 'Client,Server,Sign,Encrypt,SSL CA,Status Responder'; @@ -85,10 +85,10 @@ function run_test_in_mode(useInsanity) { // int-limited-depth-invalid (cA==true) // // XXX: It seems the NSS code does not consider the path length of the - // certificate we're validating, but insanity::pkix does. insanity::pkix's + // certificate we're validating, but mozilla::pkix does. mozilla::pkix's // behavior is correct. test_cert_for_usages(["int-limited-depth-invalid", "int-limited-depth"], - useInsanity ? "" : ca_usage1); + useMozillaPKIX ? "" : ca_usage1); test_cert_for_usages(["ee-int-limited-depth-invalid", "int-limited-depth-invalid", "int-limited-depth"], @@ -100,11 +100,11 @@ function run_test_in_mode(useInsanity) { ee_usage1); // int-bad-ku-no-eku has basicConstraints.cA==true and has a KU extension - // but the KU extension is missing keyCertSign. Note that insanity::pkix + // but the KU extension is missing keyCertSign. Note that mozilla::pkix // doesn't validate certificates with basicConstraints.Ca==true for non-CA // uses, but NSS does. test_cert_for_usages(["int-bad-ku-no-eku"], - useInsanity + useMozillaPKIX ? "" : 'Client,Server,Sign,Encrypt,Status Responder'); test_cert_for_usages(["ee-int-bad-ku-no-eku", "int-bad-ku-no-eku"], ""); diff --git a/security/manager/ssl/tests/unit/test_name_constraints.js b/security/manager/ssl/tests/unit/test_name_constraints.js index b79d89dff12a..23719298f8ea 100644 --- a/security/manager/ssl/tests/unit/test_name_constraints.js +++ b/security/manager/ssl/tests/unit/test_name_constraints.js @@ -50,8 +50,8 @@ function check_fail_ca(x) { return check_cert_err_generic(x, SEC_ERROR_CERT_NOT_IN_NAME_SPACE, certificateUsageSSLCA); } -function run_test_in_mode(useInsanity) { - Services.prefs.setBoolPref("security.use_insanity_verification", useInsanity); +function run_test_in_mode(useMozillaPKIX) { + Services.prefs.setBoolPref("security.use_mozillapkix_verification", useMozillaPKIX); // Note that CN is only looked at when there is NO subjectAltName! @@ -261,7 +261,7 @@ function run_test_in_mode(useInsanity) { check_fail(certFromFile('cn-www.foo.com_o-bar_c-us-alt-foo.com-a.a.us-b.a.us-int-ca-nc-perm-foo.com.der')); // We don't enforce dNSName name constraints on CN unless we're validating - // for the server EKU. libpkix gets this wrong but insanity::pkix and classic + // for the server EKU. libpkix gets this wrong but mozilla::pkix and classic // NSS get it right. { let cert = certFromFile('cn-www.foo.org-int-nc-perm-foo.com-ca-nc.der'); diff --git a/security/manager/ssl/tests/unit/test_ocsp_caching.js b/security/manager/ssl/tests/unit/test_ocsp_caching.js index bfd27c1b4e8a..447c2d489191 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_caching.js +++ b/security/manager/ssl/tests/unit/test_ocsp_caching.js @@ -47,10 +47,10 @@ function run_test() { run_next_test(); } -function add_tests_in_mode(useInsanity) { +function add_tests_in_mode(useMozillaPKIX) { add_test(function () { - Services.prefs.setBoolPref("security.use_insanity_verification", - useInsanity); + Services.prefs.setBoolPref("security.use_mozillapkix_verification", + useMozillaPKIX); run_next_test(); }); @@ -107,8 +107,8 @@ function add_tests_in_mode(useInsanity) { clearSessionCache); add_test(function() { do_check_eq(gFetchCount, 1); run_next_test(); }); - // TODO(bug 977865): implement this for insanity - if (!useInsanity) { + // TODO(bug 977865): implement this for mozilla::pkix + if (!useMozillaPKIX) { // The error entry will prevent a fetch from happening for a while. add_connection_test("ocsp-stapling-none.example.com", Cr.NS_OK, clearSessionCache); diff --git a/security/manager/ssl/tests/unit/test_ocsp_required.js b/security/manager/ssl/tests/unit/test_ocsp_required.js index 4f2c74e1007d..568444f2684f 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_required.js +++ b/security/manager/ssl/tests/unit/test_ocsp_required.js @@ -40,11 +40,11 @@ function run_test() { run_next_test(); } -function add_tests_in_mode(useInsanity) +function add_tests_in_mode(useMozillaPKIX) { add_test(function () { - Services.prefs.setBoolPref("security.use_insanity_verification", - useInsanity); + Services.prefs.setBoolPref("security.use_mozillapkix_verification", + useMozillaPKIX); run_next_test(); }); @@ -53,9 +53,9 @@ function add_tests_in_mode(useInsanity) add_connection_test("ocsp-stapling-none.example.com", getXPCOMStatusFromNSS(SEC_ERROR_OCSP_BAD_SIGNATURE)); add_test(function () { - // TODO(bug 977865): insanity::pkix keeps requesting responses from + // TODO(bug 977865): mozilla::pkix keeps requesting responses from // failing responders - do_check_eq(gOCSPRequestCount, useInsanity ? 2 : 1); + do_check_eq(gOCSPRequestCount, useMozillaPKIX ? 2 : 1); gOCSPRequestCount = 0; run_next_test(); }); diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling.js b/security/manager/ssl/tests/unit/test_ocsp_stapling.js index 7cf955ed255d..ad3488a5b739 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_stapling.js +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling.js @@ -21,10 +21,10 @@ function add_ocsp_test(aHost, aExpectedResult, aStaplingEnabled) { }); } -function add_tests_in_mode(useInsanity, certDB, otherTestCA) { +function add_tests_in_mode(useMozillaPKIX, certDB, otherTestCA) { add_test(function () { - Services.prefs.setBoolPref("security.use_insanity_verification", - useInsanity); + Services.prefs.setBoolPref("security.use_mozillapkix_verification", + useMozillaPKIX); run_next_test(); }); @@ -54,7 +54,7 @@ function add_tests_in_mode(useInsanity, certDB, otherTestCA) { // SEC_ERROR_OCSP_INVALID_SIGNING_CERT vs SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE // depends on whether the CA that signed the response is a trusted CA - // (but only with the classic implementation - insanity::pkix always + // (but only with the classic implementation - mozilla::pkix always // results in the error SEC_ERROR_OCSP_INVALID_SIGNING_CERT). // This stapled response is from a CA that is untrusted and did not issue @@ -113,7 +113,7 @@ function add_tests_in_mode(useInsanity, certDB, otherTestCA) { getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_RESPONSE), true); // TODO(bug 979070): NSS can't handle this yet. - if (useInsanity) { + if (useMozillaPKIX) { add_ocsp_test("ocsp-stapling-skip-responseBytes.example.com", getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_RESPONSE), true); } diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js b/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js index 76fb9a84694f..2938fe31ee07 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js @@ -62,11 +62,11 @@ function run_test() { run_next_test(); } -function add_tests_in_mode(useInsanity) +function add_tests_in_mode(useMozillaPKIX) { add_test(function () { - Services.prefs.setBoolPref("security.use_insanity_verification", - useInsanity); + Services.prefs.setBoolPref("security.use_mozillapkix_verification", + useMozillaPKIX); run_next_test(); }); diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js b/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js index 90e6bbd4a77c..d903a9f2a71d 100644 --- a/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js @@ -44,10 +44,10 @@ function run_test() { run_next_test(); } -function add_tests_in_mode(useInsanity) { +function add_tests_in_mode(useMozillaPKIX) { add_test(function () { - Services.prefs.setBoolPref("security.use_insanity_verification", - useInsanity); + Services.prefs.setBoolPref("security.use_mozillapkix_verification", + useMozillaPKIX); run_next_test(); }); diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/Makefile.in b/security/manager/ssl/tests/unit/tlsserver/cmd/Makefile.in index 0cda7123d291..d045112c8c9c 100644 --- a/security/manager/ssl/tests/unit/tlsserver/cmd/Makefile.in +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/Makefile.in @@ -10,8 +10,8 @@ LIBS = \ $(NSPR_LIBS) \ $(NSS_LIBS) \ $(MOZALLOC_LIB) \ - ../../../../../../insanity/$(LIB_PREFIX)insanitypkix.$(LIB_SUFFIX) \ - ../../../../../../insanity/test/lib/$(LIB_PREFIX)pkixtestutil.$(LIB_SUFFIX) \ + ../../../../../../pkix/$(LIB_PREFIX)mozillapkix.$(LIB_SUFFIX) \ + ../../../../../../pkix/test/lib/$(LIB_PREFIX)pkixtestutil.$(LIB_SUFFIX) \ ../lib/$(LIB_PREFIX)tlsserver.$(LIB_SUFFIX) \ $(NULL) diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp index e3cbcbf2eb90..d0360bd2bdcd 100644 --- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp @@ -13,6 +13,7 @@ using namespace mozilla; using namespace mozilla::test; +using namespace mozilla::pkix::test; SECItemArray * @@ -38,7 +39,7 @@ GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert, PRTime oneDay = 60*60*24 * (PRTime)PR_USEC_PER_SEC; PRTime oldNow = now - (8 * oneDay); - insanity::test::OCSPResponseContext context(aArena, aCert, now); + OCSPResponseContext context(aArena, aCert, now); if (aORT == ORTGoodOtherCert) { context.cert = PK11_FindCertFromNickname(aAdditionalCertName, nullptr); @@ -103,7 +104,7 @@ GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert, context.signerCert = CERT_DupCertificate(context.issuerCert.get()); } - SECItem* response = insanity::test::CreateEncodedOCSPResponse(context); + SECItem* response = CreateEncodedOCSPResponse(context); if (!response) { PrintPRError("CreateEncodedOCSPResponse failed"); return nullptr; diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/moz.build b/security/manager/ssl/tests/unit/tlsserver/lib/moz.build index 14ebd3636bdf..d2ce36eca6e9 100644 --- a/security/manager/ssl/tests/unit/tlsserver/lib/moz.build +++ b/security/manager/ssl/tests/unit/tlsserver/lib/moz.build @@ -10,8 +10,8 @@ UNIFIED_SOURCES += [ ] LOCAL_INCLUDES += [ - '../../../../../../insanity/include', - '../../../../../../insanity/test/lib', + '../../../../../../pkix/include', + '../../../../../../pkix/test/lib', ] LIBRARY_NAME = 'tlsserver' diff --git a/security/insanity/include/insanity/ScopedPtr.h b/security/pkix/include/pkix/ScopedPtr.h similarity index 90% rename from security/insanity/include/insanity/ScopedPtr.h rename to security/pkix/include/pkix/ScopedPtr.h index e957110a6798..1bec8793c429 100644 --- a/security/insanity/include/insanity/ScopedPtr.h +++ b/security/pkix/include/pkix/ScopedPtr.h @@ -1,26 +1,26 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* Copyright 2013 Mozilla Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/* Copyright 2013 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ -#ifndef insanity_pkix__ScopedPtr_h -#define insanity_pkix__ScopedPtr_h +#ifndef mozilla_pkix__ScopedPtr_h +#define mozilla_pkix__ScopedPtr_h -#include "insanity/nullptr.h" +#include "pkix/nullptr.h" -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { // Similar to boost::scoped_ptr and std::unique_ptr. Does not support copying // or assignment. @@ -94,6 +94,6 @@ operator!=(const ScopedPtr& a, T* b) return a.get() != b; } -} } // namespace insanity::pkix +} } // namespace mozilla::pkix -#endif // insanity_pkix__ScopedPtr_h +#endif // mozilla_pkix__ScopedPtr_h diff --git a/security/insanity/include/insanity/bind.h b/security/pkix/include/pkix/bind.h similarity index 93% rename from security/insanity/include/insanity/bind.h rename to security/pkix/include/pkix/bind.h index df2cd67922bb..a50ca617b6ea 100644 --- a/security/insanity/include/insanity/bind.h +++ b/security/pkix/include/pkix/bind.h @@ -19,8 +19,8 @@ // implementation isn't intended to be complete; rather, it is the minimal // implementation needed to make our use of std::bind work. -#ifndef insanity_pkix__bind_h -#define insanity_pkix__bind_h +#ifndef mozilla_pkix__bind_h +#define mozilla_pkix__bind_h #ifdef _MSC_VER #pragma warning(disable:4275) //Suppress spurious MSVC warning @@ -30,7 +30,7 @@ #pragma warning(default:4275) #endif -namespace insanity { +namespace mozilla { namespace pkix { #ifdef _MSC_VER @@ -92,6 +92,6 @@ bind(R (*f)(P1&, B1&, B2&), Placeholder1 &, B1 & b1, B2 & b2) #endif // _MSC_VER -} // namespace insanity +} } // namespace mozilla::pkix -#endif // insanity_pkix__bind_h +#endif // mozilla_pkix__bind_h diff --git a/security/insanity/include/insanity/nullptr.h b/security/pkix/include/pkix/nullptr.h similarity index 89% rename from security/insanity/include/insanity/nullptr.h rename to security/pkix/include/pkix/nullptr.h index b500b5625a38..89f47d2adadd 100644 --- a/security/insanity/include/insanity/nullptr.h +++ b/security/pkix/include/pkix/nullptr.h @@ -15,8 +15,8 @@ * limitations under the License. */ -#ifndef insanity_pkix__nullptr_h -#define insanity_pkix__nullptr_h +#ifndef mozilla_pkix__nullptr_h +#define mozilla_pkix__nullptr_h // GCC does not understand nullptr until 4.6 #if defined(__GNUC__) && !defined(__clang__) @@ -25,4 +25,4 @@ #endif #endif -#endif // insanity_pkix__nullptr_h +#endif // mozilla_pkix__nullptr_h diff --git a/security/insanity/include/insanity/pkix.h b/security/pkix/include/pkix/pkix.h similarity index 97% rename from security/insanity/include/insanity/pkix.h rename to security/pkix/include/pkix/pkix.h index 32eb2d925859..7d23ccefb0cc 100644 --- a/security/insanity/include/insanity/pkix.h +++ b/security/pkix/include/pkix/pkix.h @@ -15,13 +15,13 @@ * limitations under the License. */ -#ifndef insanity_pkix__pkix_h -#define insanity_pkix__pkix_h +#ifndef mozilla_pkix__pkix_h +#define mozilla_pkix__pkix_h #include "pkixtypes.h" #include "prtime.h" -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { // ---------------------------------------------------------------------------- // LIMITED SUPPORT FOR CERTIFICATE POLICIES @@ -118,6 +118,6 @@ SECStatus VerifyEncodedOCSPResponse(TrustDomain& trustDomain, /* optional out */ PRTime* thisUpdate, /* optional out */ PRTime* validThrough); -} } // namespace insanity::pkix +} } // namespace mozilla::pkix -#endif // insanity_pkix__pkix_h +#endif // mozilla_pkix__pkix_h diff --git a/security/insanity/include/insanity/pkixtypes.h b/security/pkix/include/pkix/pkixtypes.h similarity index 94% rename from security/insanity/include/insanity/pkixtypes.h rename to security/pkix/include/pkix/pkixtypes.h index 23a43e8d8fa1..da00ad25e2c9 100644 --- a/security/insanity/include/insanity/pkixtypes.h +++ b/security/pkix/include/pkix/pkixtypes.h @@ -15,15 +15,15 @@ * limitations under the License. */ -#ifndef insanity_pkix__pkixtypes_h -#define insanity_pkix__pkixtypes_h +#ifndef mozilla_pkix__pkixtypes_h +#define mozilla_pkix__pkixtypes_h -#include "insanity/ScopedPtr.h" +#include "pkix/ScopedPtr.h" #include "plarena.h" #include "cert.h" #include "keyhi.h" -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { typedef ScopedPtr ScopedPLArenaPool; @@ -88,7 +88,7 @@ public: // certificate is not trying to use EC(DSA) parameter inheritance. // // Most implementations of this function should probably forward the call - // directly to insanity::pkix::VerifySignedData. + // directly to mozilla::pkix::VerifySignedData. virtual SECStatus VerifySignedData(const CERTSignedData* signedData, const CERTCertificate* cert) = 0; @@ -108,6 +108,6 @@ private: void operator=(const TrustDomain&) /* = delete */; }; -} } // namespace insanity::pkix +} } // namespace mozilla::pkix -#endif // insanity_pkix__pkixtypes_h +#endif // mozilla_pkix__pkixtypes_h diff --git a/security/insanity/lib/pkixbind.cpp b/security/pkix/lib/pkixbind.cpp similarity index 89% rename from security/insanity/lib/pkixbind.cpp rename to security/pkix/lib/pkixbind.cpp index 39f094d7f410..ce3c151bcb36 100644 --- a/security/insanity/lib/pkixbind.cpp +++ b/security/pkix/lib/pkixbind.cpp @@ -17,12 +17,12 @@ #ifndef _MSC_VER -#include "insanity/bind.h" +#include "pkix/bind.h" -namespace insanity { +namespace mozilla { namespace pkix { Placeholder1 _1; - -} // namespace insanity + +} } // namespace mozilla::pkix #endif // _MSC_VER diff --git a/security/insanity/lib/pkixbuild.cpp b/security/pkix/lib/pkixbuild.cpp similarity index 99% rename from security/insanity/lib/pkixbuild.cpp rename to security/pkix/lib/pkixbuild.cpp index 41fdb1b47ab9..67e36a420bc4 100644 --- a/security/insanity/lib/pkixbuild.cpp +++ b/security/pkix/lib/pkixbuild.cpp @@ -15,14 +15,14 @@ * limitations under the License. */ -#include "insanity/pkix.h" +#include "pkix/pkix.h" #include #include "pkixcheck.h" #include "pkixder.h" -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { // We assume ext has been zero-initialized by its constructor and otherwise // not modified. @@ -172,7 +172,7 @@ BuildForwardInner(TrustDomain& trustDomain, // Be very careful about changing the order of checks. The order is significant // because it affects which error we return when a certificate or certificate // chain has multiple problems. See the error ranking documentation in -// insanity/pkix.h. +// pkix/pkix.h. static Result BuildForward(TrustDomain& trustDomain, BackCert& subject, @@ -363,4 +363,4 @@ BackCert::PrependNSSCertToList(CERTCertList* results) return Success; } -} } // namespace insanity::pkix +} } // namespace mozilla::pkix diff --git a/security/insanity/lib/pkixcheck.cpp b/security/pkix/lib/pkixcheck.cpp similarity index 99% rename from security/insanity/lib/pkixcheck.cpp rename to security/pkix/lib/pkixcheck.cpp index 56aa9b792689..1728b0b57c07 100644 --- a/security/insanity/lib/pkixcheck.cpp +++ b/security/pkix/lib/pkixcheck.cpp @@ -15,13 +15,13 @@ * limitations under the License. */ -#include "insanity/pkix.h" +#include "pkix/pkix.h" #include "pkixcheck.h" #include "pkixder.h" #include "pkixutil.h" #include "secder.h" -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { Result CheckTimes(const CERTCertificate* cert, PRTime time) @@ -479,4 +479,4 @@ CheckIssuerIndependentProperties(TrustDomain& trustDomain, return Success; } -} } // namespace insanity::pkix +} } // namespace mozilla::pkix diff --git a/security/insanity/lib/pkixcheck.h b/security/pkix/lib/pkixcheck.h similarity index 87% rename from security/insanity/lib/pkixcheck.h rename to security/pkix/lib/pkixcheck.h index 26b3ed9155c5..bee9345236c6 100644 --- a/security/insanity/lib/pkixcheck.h +++ b/security/pkix/lib/pkixcheck.h @@ -15,13 +15,13 @@ * limitations under the License. */ -#ifndef insanity__pkixcheck_h -#define insanity__pkixcheck_h +#ifndef mozilla_pkix__pkixcheck_h +#define mozilla_pkix__pkixcheck_h #include "pkixutil.h" #include "certt.h" -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { Result CheckIssuerIndependentProperties( TrustDomain& trustDomain, @@ -36,6 +36,6 @@ Result CheckIssuerIndependentProperties( Result CheckNameConstraints(BackCert& cert); -} } // namespace insanity::pkix +} } // namespace mozilla::pkix -#endif // insanity__pkixcheck_h +#endif // mozilla_pkix__pkixcheck_h diff --git a/security/insanity/lib/pkixder.cpp b/security/pkix/lib/pkixder.cpp similarity index 95% rename from security/insanity/lib/pkixder.cpp rename to security/pkix/lib/pkixder.cpp index fca4b190b49c..fa30e5b96f42 100644 --- a/security/insanity/lib/pkixder.cpp +++ b/security/pkix/lib/pkixder.cpp @@ -17,7 +17,7 @@ #include "pkixder.h" -namespace insanity { namespace der { +namespace mozilla { namespace pkix { namespace der { // not inline Result @@ -78,4 +78,4 @@ ExpectTagAndGetLength(Input& input, uint8_t expectedTag, uint16_t& length) return Success; } -} } // namespace insanity::der +} } } // namespace mozilla::pkix::der diff --git a/security/insanity/lib/pkixder.h b/security/pkix/lib/pkixder.h similarity index 98% rename from security/insanity/lib/pkixder.h rename to security/pkix/lib/pkixder.h index 99004b1a176e..b9800c2d5162 100644 --- a/security/insanity/lib/pkixder.h +++ b/security/pkix/lib/pkixder.h @@ -15,10 +15,10 @@ * limitations under the License. */ -#ifndef insanity_pkix__pkixder_h -#define insanity_pkix__pkixder_h +#ifndef mozilla_pkix__pkixder_h +#define mozilla_pkix__pkixder_h -#include "insanity/nullptr.h" +#include "pkix/nullptr.h" #include "prerror.h" #include "prlog.h" @@ -27,7 +27,7 @@ #include "secoidt.h" #include "stdint.h" -namespace insanity { namespace der { +namespace mozilla { namespace pkix { namespace der { enum Class { @@ -519,6 +519,6 @@ OptionalVersion(Input& input, /*out*/ uint8_t& version) return Success; } -} } // namespace insanity::der +} } } // namespace mozilla::pkix::der -#endif // insanity_pkix__pkixder_h +#endif // mozilla_pkix__pkixder_h diff --git a/security/insanity/lib/pkixkey.cpp b/security/pkix/lib/pkixkey.cpp similarity index 96% rename from security/insanity/lib/pkixkey.cpp rename to security/pkix/lib/pkixkey.cpp index 7a8a20e3c180..a2c7e9fa92a4 100644 --- a/security/insanity/lib/pkixkey.cpp +++ b/security/pkix/lib/pkixkey.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "insanity/pkix.h" +#include "pkix/pkix.h" #include #include @@ -25,7 +25,7 @@ #include "prerror.h" #include "secerr.h" -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { SECStatus VerifySignedData(const CERTSignedData* sd, const CERTCertificate* cert, @@ -86,4 +86,4 @@ VerifySignedData(const CERTSignedData* sd, const CERTCertificate* cert, return SECSuccess; } -} } // namespace insanity::pkix +} } // namespace mozilla::pkix diff --git a/security/insanity/lib/pkixocsp.cpp b/security/pkix/lib/pkixocsp.cpp similarity index 99% rename from security/insanity/lib/pkixocsp.cpp rename to security/pkix/lib/pkixocsp.cpp index 84ada127c99c..8e51f01d9869 100644 --- a/security/insanity/lib/pkixocsp.cpp +++ b/security/pkix/lib/pkixocsp.cpp @@ -17,8 +17,8 @@ #include -#include "insanity/bind.h" -#include "insanity/pkix.h" +#include "pkix/bind.h" +#include "pkix/pkix.h" #include "pkixcheck.h" #include "pkixder.h" @@ -36,7 +36,7 @@ // TODO: use typed/qualified typedefs everywhere? // TODO: When should we return SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE? -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { static const PRTime ONE_DAY = INT64_C(24) * INT64_C(60) * INT64_C(60) * PR_USEC_PER_SEC; @@ -993,4 +993,4 @@ CreateEncodedOCSPRequest(PLArenaPool* arena, return encodedRequest; } -} } // namespace insanity::pkix +} } // namespace mozilla::pkix diff --git a/security/insanity/lib/pkixutil.h b/security/pkix/lib/pkixutil.h similarity index 95% rename from security/insanity/lib/pkixutil.h rename to security/pkix/lib/pkixutil.h index c6e3173da437..a9b7edfd4d23 100644 --- a/security/insanity/lib/pkixutil.h +++ b/security/pkix/lib/pkixutil.h @@ -15,15 +15,15 @@ * limitations under the License. */ -#ifndef insanity_pkix__pkixutil_h -#define insanity_pkix__pkixutil_h +#ifndef mozilla_pkix__pkixutil_h +#define mozilla_pkix__pkixutil_h -#include "insanity/pkixtypes.h" +#include "pkix/pkixtypes.h" #include "prerror.h" #include "seccomon.h" #include "secerr.h" -namespace insanity { namespace pkix { +namespace mozilla { namespace pkix { enum Result { @@ -141,6 +141,6 @@ private: void operator=(const BackCert&); /* = delete */; }; -} } // namespace insanity::pkix +} } // namespace mozilla::pkix -#endif // insanity_pkix__pkixutil_h +#endif // mozilla_pkix__pkixutil_h diff --git a/security/insanity/moz.build b/security/pkix/moz.build similarity index 95% rename from security/insanity/moz.build rename to security/pkix/moz.build index 07f3fd38c05c..45114d788fde 100644 --- a/security/insanity/moz.build +++ b/security/pkix/moz.build @@ -23,6 +23,6 @@ DIRS += [ FAIL_ON_WARNINGS = True -LIBRARY_NAME = 'insanitypkix' +LIBRARY_NAME = 'mozillapkix' FINAL_LIBRARY = 'xul' diff --git a/security/insanity/test/lib/moz.build b/security/pkix/test/lib/moz.build similarity index 100% rename from security/insanity/test/lib/moz.build rename to security/pkix/test/lib/moz.build diff --git a/security/insanity/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp similarity index 99% rename from security/insanity/test/lib/pkixtestutil.cpp rename to security/pkix/test/lib/pkixtestutil.cpp index 2eed68672750..80f1883bfe77 100644 --- a/security/insanity/test/lib/pkixtestutil.cpp +++ b/security/pkix/test/lib/pkixtestutil.cpp @@ -25,7 +25,7 @@ #include "prinit.h" #include "secder.h" -namespace insanity { namespace test { +namespace mozilla { namespace pkix { namespace test { class Output { @@ -632,4 +632,4 @@ CertStatus(OCSPResponseContext& context) return nullptr; } -} } // namespace insanity::test +} } } // namespace mozilla::pkix::test diff --git a/security/insanity/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h similarity index 88% rename from security/insanity/test/lib/pkixtestutil.h rename to security/pkix/test/lib/pkixtestutil.h index 74ad48c9fb64..5e800d97344b 100644 --- a/security/insanity/test/lib/pkixtestutil.h +++ b/security/pkix/test/lib/pkixtestutil.h @@ -15,14 +15,14 @@ * limitations under the License. */ -#ifndef insanity_test__pkixtestutils_h -#define insanity_test__pkixtestutils_h +#ifndef mozilla_pkix_test__pkixtestutils_h +#define mozilla_pkix_test__pkixtestutils_h -#include "insanity/ScopedPtr.h" -#include "insanity/pkixtypes.h" +#include "pkix/ScopedPtr.h" +#include "pkix/pkixtypes.h" #include "seccomon.h" -namespace insanity { namespace test { +namespace mozilla { namespace pkix { namespace test { class OCSPResponseContext { @@ -62,6 +62,6 @@ public: // error of the failed operation). However, this is not guaranteed. SECItem* CreateEncodedOCSPResponse(OCSPResponseContext& context); -} } // namespace insanity::test +} } } // namespace mozilla::pkix::test -#endif // insanity_test__pkixtestutils_h +#endif // mozilla_pkix_test__pkixtestutils_h diff --git a/toolkit/components/telemetry/Histograms.json b/toolkit/components/telemetry/Histograms.json index 0ab3c7fdbbe5..8b9212065701 100644 --- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -4254,13 +4254,13 @@ "extended_statistics_ok": true, "description": "Time spent on a successful cert verification in classic mode (ms)" }, - "SSL_SUCCESFUL_CERT_VALIDATION_TIME_INSANITY" : { + "SSL_SUCCESFUL_CERT_VALIDATION_TIME_MOZILLAPKIX" : { "expires_in_version": "never", "kind": "exponential", "high": "60000", "n_buckets": 50, "extended_statistics_ok": true, - "description": "Time spent on a successful cert verification in insanity mode (ms)" + "description": "Time spent on a successful cert verification in mozilla::pkix mode (ms)" }, "SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_LIBPKIX" : { "expires_in_version": "never", @@ -4278,13 +4278,13 @@ "extended_statistics_ok": true, "description": "Time spent on an initially failed cert verification in classic mode (ms)" }, - "SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_INSANITY" : { + "SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_MOZILLAPKIX" : { "expires_in_version": "never", "kind": "exponential", "high": "60000", "n_buckets": 50, "extended_statistics_ok": true, - "description": "Time spent on an initially failed cert verification in insanity mode (ms)" + "description": "Time spent on an initially failed cert verification in mozilla::pkix mode (ms)" }, "HEALTHREPORT_DB_OPEN_FIRSTRUN_MS": { "expires_in_version": "never", From 03d118d71c6dbb603ceb2c7ddec810c32181f3ff Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Fri, 7 Feb 2014 16:50:28 -0800 Subject: [PATCH 025/101] Bug 985695 - Rename JSContext::getLazyType to getSingletonType, because that's the only sense in which it's used. r=terrence --HG-- extra : rebase_source : db9807b0c311c334ae38409f0dfee259f968b8d3 --- js/src/jscntxt.h | 2 +- js/src/jsinfer.cpp | 3 ++- js/src/jsobjinlines.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 119d49294eb1..747bd80e70e3 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -367,7 +367,7 @@ class ExclusiveContext : public ThreadSafeContext // Zone local methods that can be used freely from an ExclusiveContext. types::TypeObject *getNewType(const Class *clasp, TaggedProto proto, JSFunction *fun = nullptr); - types::TypeObject *getLazyType(const Class *clasp, TaggedProto proto); + types::TypeObject *getSingletonType(const Class *clasp, TaggedProto proto); inline js::LifoAlloc &typeLifoAlloc(); // Current global. This is only safe to use within the scope of the diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 26a3b2b45147..d6b7a5fd9470 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -3923,7 +3923,7 @@ JSCompartment::checkNewTypeObjectTableAfterMovingGC() #endif TypeObject * -ExclusiveContext::getLazyType(const Class *clasp, TaggedProto proto) +ExclusiveContext::getSingletonType(const Class *clasp, TaggedProto proto) { JS_ASSERT_IF(proto.isObject(), compartment() == proto.toObject()->compartment()); @@ -3951,6 +3951,7 @@ ExclusiveContext::getLazyType(const Class *clasp, TaggedProto proto) return nullptr; type->initSingleton((JSObject *) TypeObject::LAZY_SINGLETON); + MOZ_ASSERT(type->singleton(), "created type must be a proper singleton"); return type; } diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index 9b3e04d7c305..0a20d7f33688 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -376,7 +376,7 @@ JSObject::setSingletonType(js::ExclusiveContext *cx, js::HandleObject obj) JS_ASSERT_IF(cx->isJSContext(), !IsInsideNursery(cx->asJSContext()->runtime(), obj.get())); - js::types::TypeObject *type = cx->getLazyType(obj->getClass(), obj->getTaggedProto()); + js::types::TypeObject *type = cx->getSingletonType(obj->getClass(), obj->getTaggedProto()); if (!type) return false; From b44fa4bf74dbfd73b13890ef73ab730a6be99dd1 Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Tue, 11 Mar 2014 12:03:56 -0700 Subject: [PATCH 026/101] Bug 985687 - Remove vestigial tinyid/shortid references, as well as the field in JSPropertySpec. Followup to bug 975069. r=luke --HG-- extra : rebase_source : 4a9d1d783e658648c4ff210760b38f8353631458 --- dom/bindings/Codegen.py | 2 +- js/src/frontend/Parser.cpp | 4 --- js/src/jsapi.h | 11 +++--- js/src/shell/js.cpp | 2 +- js/src/tests/js1_8_5/extensions/mega-let.js | 39 +++++++++++++++++++++ js/src/vm/ScopeObject.cpp | 16 +++------ js/src/vm/ScopeObject.h | 8 ----- 7 files changed, 51 insertions(+), 31 deletions(-) create mode 100644 js/src/tests/js1_8_5/extensions/mega-let.js diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 74afeecb7eb3..2ae72c6e955a 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -1830,7 +1830,7 @@ class AttrDefiner(PropertyDefiner): return self.generatePrefableArray( array, name, - ' { "%s", 0, %s, %s, %s}', + ' { "%s", %s, %s, %s}', ' JS_PS_END', 'JSPropertySpec', PropertyDefiner.getControllingCondition, specData, doIdArrays) diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 793355da5691..515bf3c12401 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -2693,10 +2693,6 @@ Parser::bindLet(BindData *data, Rooted blockObj(cx, data->let.blockObj); unsigned index = blockObj->numVariables(); - if (index >= StaticBlockObject::LOCAL_INDEX_LIMIT) { - parser->report(ParseError, false, pn, data->let.overflow); - return false; - } /* * Assign block-local index to pn->pn_cookie right away, encoding it as an diff --git a/js/src/jsapi.h b/js/src/jsapi.h index a2024446c528..f8f5a24f0b32 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2395,7 +2395,6 @@ struct JSPropertySpec { }; const char *name; - int8_t tinyid; uint8_t flags; union { JSPropertyOpWrapper propertyOp; @@ -2449,26 +2448,26 @@ CheckIsCharacterLiteral(const char (&arr)[N]); * JSNatives. */ #define JS_PSG(name, getter, flags) \ - {name, 0, \ + {name, \ uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \ JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \ JSOP_NULLWRAPPER} #define JS_PSGS(name, getter, setter, flags) \ - {name, 0, \ + {name, \ uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \ JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \ JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp))} #define JS_SELF_HOSTED_GET(name, getterName, flags) \ - {name, 0, \ + {name, \ uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \ { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \ JSOP_NULLWRAPPER } #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \ - {name, 0, \ + {name, \ uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \ { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \ { nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo *) } } -#define JS_PS_END {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER } +#define JS_PS_END { nullptr, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER } /* * To define a native function, set call to a JSNativeWrapper. To define a diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 4b2e049ddbee..4b9d2ea72cd5 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -5159,7 +5159,7 @@ static const JSJitInfo doFoo_methodinfo = { }; static const JSPropertySpec dom_props[] = { - {"x", 0, + {"x", JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS, { { (JSPropertyOp)dom_genericGetter, &dom_x_getterinfo } }, { { (JSStrictPropertyOp)dom_genericSetter, &dom_x_setterinfo } } diff --git a/js/src/tests/js1_8_5/extensions/mega-let.js b/js/src/tests/js1_8_5/extensions/mega-let.js new file mode 100644 index 000000000000..e0551a2ff0ae --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/mega-let.js @@ -0,0 +1,39 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +//----------------------------------------------------------------------------- +var BUGNUMBER = 999999; +var summary = + "Allow defining more than 2**16 let-variables in a single scope"; + +print(BUGNUMBER + ": " + summary); + +/************** + * BEGIN TEST * + **************/ + +print("Creating binding string..."); + +var bindings = []; +var codeStr = "let "; +for (var i = 0; i < Math.pow(2, 20); i++) + bindings.push("x" + i + " = " + i); + +var codeStr = "let " + bindings.join(", ") + ";"; + +print("Binding string created, testing with global eval..."); + +eval(codeStr); + +print("Testing with Function..."); + +Function(codeStr)(); + +print("Testing inside a function..."); + +eval("function q() { " + codeStr + " }; q();"); + +if (typeof reportCompare === "function") + reportCompare(true, true); + +print("Tests complete"); diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index f5d62fccdf15..ff190ef61835 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -684,7 +684,6 @@ StaticBlockObject::addVar(ExclusiveContext *cx, Handle block unsigned index, bool *redeclared) { JS_ASSERT(JSID_IS_ATOM(id)); - JS_ASSERT(index < LOCAL_INDEX_LIMIT); *redeclared = false; @@ -755,19 +754,19 @@ js::XDRStaticBlockObject(XDRState *xdr, HandleObject enclosingScope, if (!xdr->codeUint32(&offset)) return false; + /* + * XDR the block object's properties. We know that there are 'count' + * properties to XDR, stored as id/aliased pairs. (The empty string as + * id indicates an int id.) + */ if (mode == XDR_DECODE) { obj->setLocalOffset(offset); - /* - * XDR the block object's properties. We know that there are 'count' - * properties to XDR, stored as id/shortid pairs. - */ for (unsigned i = 0; i < count; i++) { RootedAtom atom(cx); if (!XDRAtom(xdr, &atom)) return false; - /* The empty string indicates an int id. */ RootedId id(cx, atom != cx->runtime()->emptyString ? AtomToId(atom) : INT_TO_JSID(i)); @@ -793,10 +792,6 @@ js::XDRStaticBlockObject(XDRState *xdr, HandleObject enclosingScope, for (Shape::Range r(obj->lastProperty()); !r.empty(); r.popFront()) shapes[obj->shapeToIndex(r.front())] = &r.front(); - /* - * XDR the block object's properties. We know that there are 'count' - * properties to XDR, stored as id/shortid pairs. - */ RootedShape shape(cx); RootedId propid(cx); RootedAtom atom(cx); @@ -808,7 +803,6 @@ js::XDRStaticBlockObject(XDRState *xdr, HandleObject enclosingScope, propid = shape->propid(); JS_ASSERT(JSID_IS_ATOM(propid) || JSID_IS_INT(propid)); - /* The empty string indicates an int id. */ atom = JSID_IS_ATOM(propid) ? JSID_TO_ATOM(propid) : cx->runtime()->emptyString; diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index b5fe4bd40506..3423c6a5f1f4 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -532,14 +532,6 @@ class StaticBlockObject : public BlockObject return reinterpret_cast(v.toPrivate()); } - /* - * While ScopeCoordinate can generally reference up to 2^24 slots, block objects have an - * additional limitation that all slot indices must be storable as uint16_t short-ids in the - * associated Shape. If we could remove the block dependencies on shape->shortid, we could - * remove INDEX_LIMIT. - */ - static const unsigned LOCAL_INDEX_LIMIT = JS_BIT(16); - static Shape *addVar(ExclusiveContext *cx, Handle block, HandleId id, unsigned index, bool *redeclared); }; From a375bd024ed70af5987bdf1b1982f09d4ecdbe73 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Thu, 20 Mar 2014 14:38:43 -0700 Subject: [PATCH 027/101] Bug 986147 - Loosen assertions to allow IsAboutToBeFinalized to be used during MinorGC; r=sfink --- js/src/gc/Marking.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 3ad3c9d3c406..b71e39a367c9 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -358,10 +358,11 @@ IsAboutToBeFinalized(T **thingp) * We should return false for things that have been allocated during * incremental sweeping, but this possibility doesn't occur at the moment * because this function is only called at the very start of the sweeping a - * compartment group. Rather than do the extra check, we just assert that - * it's not necessary. + * compartment group and during minor gc. Rather than do the extra check, + * we just assert that it's not necessary. */ - JS_ASSERT(!(*thingp)->arenaHeader()->allocatedDuringIncremental); + JS_ASSERT_IF(!(*thingp)->runtimeFromAnyThread()->isHeapMinorCollecting(), + !(*thingp)->arenaHeader()->allocatedDuringIncremental); return !(*thingp)->isMarked(); } From dc2736131bb719b5b6f64b16b6c067055c953718 Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Thu, 20 Mar 2014 15:07:57 -0700 Subject: [PATCH 028/101] Bug 986139 - Purge caches when preserving PJS JIT code. (r=terrence) --- js/src/gc/Zone.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index 82a413ff1725..53ce8adafc05 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -198,10 +198,12 @@ Zone::discardJitCode(FreeOp *fop) // parallel. Note that we mark their baseline scripts as active as // well to preserve them. if (script->hasParallelIonScript()) { - if (jit::ShouldPreserveParallelJITCode(runtimeFromMainThread(), script)) + if (jit::ShouldPreserveParallelJITCode(runtimeFromMainThread(), script)) { + script->parallelIonScript()->purgeCaches(this); script->baselineScript()->setActive(); - else + } else { jit::FinishInvalidation(fop, script); + } } /* From bb12e92049a42600983d60083c06974018dbfeb5 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Thu, 20 Mar 2014 23:23:48 +0100 Subject: [PATCH 029/101] Bug 970643 - Valgrind does not understand OdinMonkey's guard page mechanism. r=luke. --- js/src/vm/ArrayBufferObject.cpp | 19 ++++++++++++++++++- js/src/vm/SharedArrayObject.cpp | 20 +++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 611f3f29a1ea..ef87c77d12d9 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -15,6 +15,10 @@ # include #endif +#ifdef MOZ_VALGRIND +# include +#endif + #include "jsapi.h" #include "jsarray.h" #include "jscntxt.h" @@ -428,10 +432,16 @@ ArrayBufferObject::prepareForAsmJS(JSContext *cx, Handle buf return false; } # else - if (mprotect(data, buffer->byteLength(), PROT_READ | PROT_WRITE)) { + size_t validLength = buffer->byteLength(); + if (mprotect(data, validLength, PROT_READ | PROT_WRITE)) { munmap(data, AsmJSMappedSize); return false; } +# if defined(MOZ_VALGRIND) && defined(VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE) + // Tell Valgrind/Memcheck to not report accesses in the inaccessible region. + VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE((unsigned char*)data + validLength, + AsmJSMappedSize-validLength); +# endif # endif // Copy over the current contents of the typed array. @@ -458,6 +468,13 @@ ArrayBufferObject::releaseAsmJSArray(FreeOp *fop) VirtualFree(data, 0, MEM_RELEASE); # else munmap(data, AsmJSMappedSize); +# if defined(MOZ_VALGRIND) && defined(VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE) + // Tell Valgrind/Memcheck to recommence reporting accesses in the + // previously-inaccessible region. + if (AsmJSMappedSize > 0) { + VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(data, AsmJSMappedSize); + } +# endif # endif } #else /* defined(JS_ION) && defined(JS_CPU_X64) */ diff --git a/js/src/vm/SharedArrayObject.cpp b/js/src/vm/SharedArrayObject.cpp index dcd32b13f2b0..a5052b0f05e6 100644 --- a/js/src/vm/SharedArrayObject.cpp +++ b/js/src/vm/SharedArrayObject.cpp @@ -15,6 +15,10 @@ # include #endif +#ifdef MOZ_VALGRIND +# include +#endif + #include "mozilla/Atomics.h" #include "jit/AsmJS.h" @@ -79,10 +83,16 @@ SharedArrayRawBuffer::New(uint32_t length) if (!p) return nullptr; - if (!MarkValidRegion(p, AsmJSPageSize + length)) { + size_t validLength = AsmJSPageSize + length; + if (!MarkValidRegion(p, validLength)) { UnmapMemory(p, AsmJSMappedSize); return nullptr; } +# if defined(MOZ_VALGRIND) && defined(VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE) + // Tell Valgrind/Memcheck to not report accesses in the inaccessible region. + VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE((unsigned char*)p + validLength, + AsmJSMappedSize-validLength); +# endif #else uint32_t allocSize = length + AsmJSPageSize; if (allocSize <= length) @@ -116,6 +126,14 @@ SharedArrayRawBuffer::dropReference() JS_ASSERT(uintptr_t(p) % AsmJSPageSize == 0); #ifdef JS_CPU_X64 UnmapMemory(p, AsmJSMappedSize); +# if defined(MOZ_VALGRIND) \ + && defined(VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE) + // Tell Valgrind/Memcheck to recommence reporting accesses in the + // previously-inaccessible region. + if (AsmJSMappedSize > 0) { + VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(p, AsmJSMappedSize); + } +# endif #else UnmapMemory(p, this->length + AsmJSPageSize); #endif From d6d6c34306e0ab845dfb094d4c6f25c85a347c3a Mon Sep 17 00:00:00 2001 From: David Keeler Date: Thu, 20 Mar 2014 15:36:23 -0700 Subject: [PATCH 030/101] bug 985201 - follow-up: fix comment mentioning "Insanity" (it should be "mozilla::pkix") r=me DONTBUILD --- security/manager/ssl/tests/unit/test_cert_trust.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/manager/ssl/tests/unit/test_cert_trust.js b/security/manager/ssl/tests/unit/test_cert_trust.js index 9a522f3b149d..c688abe28f0a 100644 --- a/security/manager/ssl/tests/unit/test_cert_trust.js +++ b/security/manager/ssl/tests/unit/test_cert_trust.js @@ -167,7 +167,7 @@ function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA, useMozillaPKI check_cert_err_generic(ee_cert, 0, certificateUsageSSLServer); check_cert_err_generic(ee_cert, isRootCA ? SEC_ERROR_UNTRUSTED_ISSUER : useMozillaPKIX ? SEC_ERROR_UNTRUSTED_ISSUER - : 0, // Insanity is OK, NSS bug + : 0, // mozilla::pkix is OK, NSS bug certificateUsageSSLClient); check_cert_err_generic(ee_cert, useMozillaPKIX ? SEC_ERROR_CA_CERT_INVALID : SEC_ERROR_INADEQUATE_CERT_TYPE, From 2a95c9882655414f9395a79fd1c064c41fc57367 Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Fri, 21 Mar 2014 11:47:17 +1300 Subject: [PATCH 031/101] Bug 984698 - Reduce the amount of audio prerolled when we are not also decoding video in the same file. r=padenot --- content/media/MediaDecoderStateMachine.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/content/media/MediaDecoderStateMachine.cpp b/content/media/MediaDecoderStateMachine.cpp index 1ff51ea0a66b..a72db1d4fd6c 100644 --- a/content/media/MediaDecoderStateMachine.cpp +++ b/content/media/MediaDecoderStateMachine.cpp @@ -74,6 +74,13 @@ static const uint32_t LOW_AUDIO_USECS = 300000; // less than the low audio threshold. const int64_t AMPLE_AUDIO_USECS = 1000000; +// When we're only playing audio and we don't have a video stream, we divide +// AMPLE_AUDIO_USECS and LOW_AUDIO_USECS by the following value. This reduces +// the amount of decoded audio we buffer, reducing our memory usage. We only +// need to decode far ahead when we're decoding video using software decoding, +// as otherwise a long video decode could cause an audio underrun. +const int64_t NO_VIDEO_AMPLE_AUDIO_DIVISOR = 8; + // Maximum number of bytes we'll allocate and write at once to the audio // hardware when the audio stream contains missing frames and we're // writing silence in order to fill the gap. We limit our silence-writes @@ -1856,6 +1863,14 @@ nsresult MediaDecoderStateMachine::DecodeMetadata() mDecoder.get(), mStartTime, mEndTime, GetDuration(), mTransportSeekable, mMediaSeekable)); + if (HasAudio() && !HasVideo()) { + // We're playing audio only. We don't need to worry about slow video + // decodes causing audio underruns, so don't buffer so much audio in + // order to reduce memory usage. + mAmpleAudioThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR; + mLowAudioThresholdUsecs /= NO_VIDEO_AMPLE_AUDIO_DIVISOR; + } + // Inform the element that we've loaded the metadata and the first frame, // setting the default framebuffer size for audioavailable events. Also, // if there is audio, let the MozAudioAvailable event manager know about From 4f8a213abd7075278d933d0ad6139fecdbee0b3e Mon Sep 17 00:00:00 2001 From: David Keeler Date: Thu, 20 Mar 2014 15:50:12 -0700 Subject: [PATCH 032/101] bug 985021 - mozilla::pkix: temporarily accept pathLenConstraint in EE basic constraints extensions r=briansmith --- security/pkix/lib/pkixcheck.cpp | 63 ++++++++++++++++++++++++++++++--- security/pkix/lib/pkixder.h | 17 +++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/security/pkix/lib/pkixcheck.cpp b/security/pkix/lib/pkixcheck.cpp index 1728b0b57c07..ca5a8b93beef 100644 --- a/security/pkix/lib/pkixcheck.cpp +++ b/security/pkix/lib/pkixcheck.cpp @@ -147,6 +147,62 @@ CheckCertificatePolicies(BackCert& cert, EndEntityOrCA endEntityOrCA, return RecoverableError; } +// BasicConstraints ::= SEQUENCE { +// cA BOOLEAN DEFAULT FALSE, +// pathLenConstraint INTEGER (0..MAX) OPTIONAL } +der::Result +DecodeBasicConstraints(const SECItem* encodedBasicConstraints, + CERTBasicConstraints& basicConstraints) +{ + PR_ASSERT(encodedBasicConstraints); + if (!encodedBasicConstraints) { + return der::Fail(SEC_ERROR_INVALID_ARGS); + } + + basicConstraints.isCA = false; + basicConstraints.pathLenConstraint = 0; + + der::Input input; + if (input.Init(encodedBasicConstraints->data, encodedBasicConstraints->len) + != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + + if (der::ExpectTagAndIgnoreLength(input, der::SEQUENCE) != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + + bool isCA = false; + if (der::OptionalBoolean(input, isCA) != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + basicConstraints.isCA = isCA; + + if (input.Peek(der::INTEGER)) { + SECItem pathLenConstraintEncoded; + if (der::Integer(input, pathLenConstraintEncoded) != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + unsigned long pathLenConstraint = DER_GetInteger(&pathLenConstraintEncoded); + if (pathLenConstraint == std::numeric_limits::max() || + pathLenConstraint > std::numeric_limits::max()) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + basicConstraints.pathLenConstraint = static_cast(pathLenConstraint); + // TODO(bug 985025): If isCA is false, pathLenConstraint MUST NOT + // be included (as per RFC 5280 section 4.2.1.9), but for compatibility + // reasons, we don't check this for now. + } else if (basicConstraints.isCA) { + // If this is a CA but the path length is omitted, it is unlimited. + basicConstraints.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT; + } + + if (der::End(input) != der::Success) { + return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); + } + return der::Success; +} + // RFC5280 4.2.1.9. Basic Constraints (id-ce-basicConstraints) Result CheckBasicConstraints(const BackCert& cert, @@ -156,10 +212,9 @@ CheckBasicConstraints(const BackCert& cert, { CERTBasicConstraints basicConstraints; if (cert.encodedBasicConstraints) { - SECStatus rv = CERT_DecodeBasicConstraintValue(&basicConstraints, - cert.encodedBasicConstraints); - if (rv != SECSuccess) { - return MapSECStatus(rv); + if (DecodeBasicConstraints(cert.encodedBasicConstraints, + basicConstraints) != der::Success) { + return RecoverableError; } } else { // Synthesize a non-CA basic constraints by default diff --git a/security/pkix/lib/pkixder.h b/security/pkix/lib/pkixder.h index b9800c2d5162..608466af2b5b 100644 --- a/security/pkix/lib/pkixder.h +++ b/security/pkix/lib/pkixder.h @@ -380,6 +380,23 @@ Boolean(Input& input, /*out*/ bool& value) } } +// This is for any BOOLEAN DEFAULT FALSE. +// (If it is present and false, this is a bad encoding.) +inline Result +OptionalBoolean(Input& input, /*out*/ bool& value) +{ + value = false; + if (input.Peek(BOOLEAN)) { + if (Boolean(input, value) != Success) { + return Failure; + } + if (!value) { + return Fail(SEC_ERROR_BAD_DER); + } + } + return Success; +} + inline Result Enumerated(Input& input, uint8_t& value) { From 5e94cb110d739a0b53ec7729c9de89e4cf3a2446 Mon Sep 17 00:00:00 2001 From: David Keeler Date: Thu, 20 Mar 2014 16:06:15 -0700 Subject: [PATCH 033/101] backout bug 985021 (de535cd27ee7) for build breakage r=backout --- security/pkix/lib/pkixcheck.cpp | 63 +++------------------------------ security/pkix/lib/pkixder.h | 17 --------- 2 files changed, 4 insertions(+), 76 deletions(-) diff --git a/security/pkix/lib/pkixcheck.cpp b/security/pkix/lib/pkixcheck.cpp index ca5a8b93beef..1728b0b57c07 100644 --- a/security/pkix/lib/pkixcheck.cpp +++ b/security/pkix/lib/pkixcheck.cpp @@ -147,62 +147,6 @@ CheckCertificatePolicies(BackCert& cert, EndEntityOrCA endEntityOrCA, return RecoverableError; } -// BasicConstraints ::= SEQUENCE { -// cA BOOLEAN DEFAULT FALSE, -// pathLenConstraint INTEGER (0..MAX) OPTIONAL } -der::Result -DecodeBasicConstraints(const SECItem* encodedBasicConstraints, - CERTBasicConstraints& basicConstraints) -{ - PR_ASSERT(encodedBasicConstraints); - if (!encodedBasicConstraints) { - return der::Fail(SEC_ERROR_INVALID_ARGS); - } - - basicConstraints.isCA = false; - basicConstraints.pathLenConstraint = 0; - - der::Input input; - if (input.Init(encodedBasicConstraints->data, encodedBasicConstraints->len) - != der::Success) { - return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); - } - - if (der::ExpectTagAndIgnoreLength(input, der::SEQUENCE) != der::Success) { - return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); - } - - bool isCA = false; - if (der::OptionalBoolean(input, isCA) != der::Success) { - return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); - } - basicConstraints.isCA = isCA; - - if (input.Peek(der::INTEGER)) { - SECItem pathLenConstraintEncoded; - if (der::Integer(input, pathLenConstraintEncoded) != der::Success) { - return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); - } - unsigned long pathLenConstraint = DER_GetInteger(&pathLenConstraintEncoded); - if (pathLenConstraint == std::numeric_limits::max() || - pathLenConstraint > std::numeric_limits::max()) { - return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); - } - basicConstraints.pathLenConstraint = static_cast(pathLenConstraint); - // TODO(bug 985025): If isCA is false, pathLenConstraint MUST NOT - // be included (as per RFC 5280 section 4.2.1.9), but for compatibility - // reasons, we don't check this for now. - } else if (basicConstraints.isCA) { - // If this is a CA but the path length is omitted, it is unlimited. - basicConstraints.pathLenConstraint = CERT_UNLIMITED_PATH_CONSTRAINT; - } - - if (der::End(input) != der::Success) { - return der::Fail(SEC_ERROR_EXTENSION_VALUE_INVALID); - } - return der::Success; -} - // RFC5280 4.2.1.9. Basic Constraints (id-ce-basicConstraints) Result CheckBasicConstraints(const BackCert& cert, @@ -212,9 +156,10 @@ CheckBasicConstraints(const BackCert& cert, { CERTBasicConstraints basicConstraints; if (cert.encodedBasicConstraints) { - if (DecodeBasicConstraints(cert.encodedBasicConstraints, - basicConstraints) != der::Success) { - return RecoverableError; + SECStatus rv = CERT_DecodeBasicConstraintValue(&basicConstraints, + cert.encodedBasicConstraints); + if (rv != SECSuccess) { + return MapSECStatus(rv); } } else { // Synthesize a non-CA basic constraints by default diff --git a/security/pkix/lib/pkixder.h b/security/pkix/lib/pkixder.h index 608466af2b5b..b9800c2d5162 100644 --- a/security/pkix/lib/pkixder.h +++ b/security/pkix/lib/pkixder.h @@ -380,23 +380,6 @@ Boolean(Input& input, /*out*/ bool& value) } } -// This is for any BOOLEAN DEFAULT FALSE. -// (If it is present and false, this is a bad encoding.) -inline Result -OptionalBoolean(Input& input, /*out*/ bool& value) -{ - value = false; - if (input.Peek(BOOLEAN)) { - if (Boolean(input, value) != Success) { - return Failure; - } - if (!value) { - return Fail(SEC_ERROR_BAD_DER); - } - } - return Success; -} - inline Result Enumerated(Input& input, uint8_t& value) { From 0f227f399dc6a150817558e51a7104a2e7283013 Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Thu, 20 Mar 2014 17:16:40 -0600 Subject: [PATCH 034/101] Bug 967704 - Disable a few tests on Android 2.3 for intermittent failures --- mobile/android/base/tests/robocop.ini | 8 ++++++++ testing/mochitest/android23.json | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mobile/android/base/tests/robocop.ini b/mobile/android/base/tests/robocop.ini index dff29c3d0da0..fe43363c4159 100644 --- a/mobile/android/base/tests/robocop.ini +++ b/mobile/android/base/tests/robocop.ini @@ -32,6 +32,8 @@ skip-if = android_version == "10" skip-if = android_version == "10" || processor == "x86" [testDistribution] [testDoorHanger] +# disabled on 2.3; bug 986172 +skip-if = android_version == "10" [testFindInPage] # disabled on Android 2.3; bug 975155 skip-if = android_version == "10" @@ -52,6 +54,8 @@ skip-if = android_version == "10" || processor == "x86" [testInputUrlBar] [testJarReader] [testLinkContextMenu] +# disabled on 2.3; bug 918494 +skip-if = android_version == "10" # [testHomeListsProvider] # see bug 952310 [testHomeProvider] [testLoad] @@ -63,6 +67,8 @@ skip-if = android_version == "10" # disabled on 2.3; bug 979621 skip-if = android_version == "10" [testOverscroll] +# disabled on 2.3; bug 836818 +skip-if = android_version == "10" [testPanCorrectness] # disabled on x86 only; bug 927476 skip-if = processor == "x86" @@ -70,6 +76,8 @@ skip-if = processor == "x86" [testPasswordProvider] # [testPermissions] # see bug 757475 [testPictureLinkContextMenu] +# disabled on 2.3; bug 986164 +skip-if = android_version == "10" [testPrefsObserver] [testPrivateBrowsing] [testPromptGridInput] diff --git a/testing/mochitest/android23.json b/testing/mochitest/android23.json index ee3a770651a4..74e1dde4b8b0 100644 --- a/testing/mochitest/android23.json +++ b/testing/mochitest/android23.json @@ -6,6 +6,7 @@ "content/media/test/test_audio_event_adopt.html": "Android 2.3 only; bug 981898", "content/media/test/test_autoplay.html": "Android 2.3 only; bug 981898", "content/media/test/test_autoplay_contentEditable.html": "Android 2.3 only; bug 981898", + "content/media/test/test_bug448534.html": "Android 2.3 only; bug 981898", "content/media/test/test_chaining.html": "Android 2.3 only; bug 981898", "content/media/test/test_loop.html": "Android 2.3 only; bug 981898", "content/media/test/test_mediarecorder_record_4ch_audiocontext.html": "Android 2.3 only; bug 981898", @@ -16,6 +17,7 @@ "content/media/test/test_mediarecorder_record_stopms.html": "Android 2.3 only; bug 981898", "content/media/test/test_mediarecorder_record_timeslice.html": "Android 2.3 only; bug 981898", "content/media/test/test_mediarecorder_unsupported_src.html": "Android 2.3 only; bug 981898", + "content/media/test/test_play_twice.html": "Android 2.3 only; bug 981898", "content/media/test/test_playback.html": "Android 2.3 only; bug 981898", "content/media/test/test_streams_autoplay.html": "Android 2.3 only; bug 981898", "content/media/test/test_streams_element_capture.html": "Android 2.3 only; bug 981898", @@ -30,9 +32,13 @@ "content/media/webaudio/test/test_bug866737.html": "Android 2.3 only; bug 981889", "content/media/webaudio/test/test_bug867104.html": "Android 2.3 only; bug 981889", "content/media/webaudio/test/test_bug938022.html": "Android 2.3 only; bug 981889", + "content/media/webaudio/test/test_channelMergerNodeWithVolume.html": "Android 2.3 only; bug 981889", + "content/media/webaudio/test/test_channelSplitterNode.html": "Android 2.3 only; bug 981889", + "content/media/webaudio/test/test_channelSplitterNodeWithVolume.html": "Android 2.3 only; bug 981889", "content/media/webaudio/test/test_convolverNodeChannelCount.html": "Android 2.3 only; bug 981889", "content/media/webaudio/test/test_convolverNodeWithGain.html": "Android 2.3 only; bug 981889", "content/media/webaudio/test/test_delayNode.html": "Android 2.3 only; bug 981889", + "content/media/webaudio/test/test_delayNodeAtMax.html": "Android 2.3 only; bug 981889", "content/media/webaudio/test/test_delayNodeTailWithDisconnect.html": "Android 2.3 only; bug 981889", "content/media/webaudio/test/test_delayNodeTailWithGain.html": "Android 2.3 only; bug 981889", "content/media/webaudio/test/test_delayNodeTailWithReconnect.html": "Android 2.3 only; bug 981889", @@ -80,6 +86,7 @@ "dom/media/tests/mochitest/test_peerConnection_basicAudioVideoCombined.html":"Android 2.3 only; bug 981881", "dom/media/tests/mochitest/test_peerConnection_basicVideo.htm":"Android 2.3 only; bug 981881", "dom/media/tests/mochitest/test_peerConnection_bug825703.html":"Android 2.3 only; bug 981881", - "dom/media/tests/mochitest/test_peerConnection_bug827843.html":"Android 2.3 only; bug 981881" + "dom/media/tests/mochitest/test_peerConnection_bug827843.html":"Android 2.3 only; bug 981881", + "layout/style/test/test_media_queries.html": "Android 2.3 only; bug 981881" } } From 25725839ca6d488664b3a03268a1b1dc3354c6fd Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Thu, 20 Mar 2014 18:23:16 -0500 Subject: [PATCH 035/101] Bug 874950. Record on display items if they are inside a fixed position subtree. r=roc --- layout/base/nsDisplayList.cpp | 1 + layout/base/nsDisplayList.h | 32 ++++++++++++++++++++++++++++++++ layout/generic/nsFrame.cpp | 7 +++++++ 3 files changed, 40 insertions(+) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 564132935dda..f8cf77cc4cfb 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -531,6 +531,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, mAllowMergingAndFlattening(true), mWillComputePluginGeometry(false), mInTransform(false), + mInFixedPos(false), mSyncDecodeImages(false), mIsPaintingToWindow(false), mIsCompositingCheap(false), diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 02a4ffd31de9..1b0d6364a89c 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -374,6 +374,12 @@ public: */ void SetInTransform(bool aInTransform) { mInTransform = aInTransform; } + /** + * Returns true if we're currently building display items that are in + * true fixed position subtree. + */ + bool IsInFixedPos() const { return mInFixedPos; } + /** * @return true if images have been set to decode synchronously. */ @@ -574,6 +580,25 @@ public: bool mOldValue; }; + /** + * A helper class to temporarily set the value of mInFixedPos. + */ + class AutoInFixedPosSetter; + friend class AutoInFixedPosSetter; + class AutoInFixedPosSetter { + public: + AutoInFixedPosSetter(nsDisplayListBuilder* aBuilder, bool aInFixedPos) + : mBuilder(aBuilder), mOldValue(aBuilder->mInFixedPos) { + aBuilder->mInFixedPos = aInFixedPos; + } + ~AutoInFixedPosSetter() { + mBuilder->mInFixedPos = mOldValue; + } + private: + nsDisplayListBuilder* mBuilder; + bool mOldValue; + }; + // Helpers for tables nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; } void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; } @@ -691,6 +716,7 @@ private: // True when we're building a display list that's directly or indirectly // under an nsDisplayTransform bool mInTransform; + bool mInFixedPos; bool mSyncDecodeImages; bool mIsPaintingToWindow; bool mIsCompositingCheap; @@ -745,6 +771,7 @@ public: nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) : mFrame(aFrame) , mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder)) + , mInFixedPos(aBuilder->IsInFixedPos()) #ifdef MOZ_DUMP_PAINTING , mPainted(false) #endif @@ -759,6 +786,7 @@ public: , mClip(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder)) , mReferenceFrame(aReferenceFrame) , mToReferenceFrame(aToReferenceFrame) + , mInFixedPos(aBuilder->IsInFixedPos()) #ifdef MOZ_DUMP_PAINTING , mPainted(false) #endif @@ -772,6 +800,7 @@ public: : mFrame(aFrame) , mClip(nullptr) , mReferenceFrame(nullptr) + , mInFixedPos(false) #ifdef MOZ_DUMP_PAINTING , mPainted(false) #endif @@ -1258,6 +1287,8 @@ public: // should set the visible region, usually in BuildContainerLayer. virtual bool SetVisibleRegionOnLayer() { return true; } + bool IsInFixedPos() { return mInFixedPos; } + protected: friend class nsDisplayList; @@ -1275,6 +1306,7 @@ protected: // of the item. Paint implementations can use this to limit their drawing. // Guaranteed to be contained in GetBounds(). nsRect mVisibleRect; + bool mInFixedPos; #ifdef MOZ_DUMP_PAINTING // True if this frame has been painted. bool mPainted; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 005c97973513..1cc69bc3345a 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2299,6 +2299,13 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, NS_ASSERTION(!isStackingContext || pseudoStackingContext, "Stacking contexts must also be pseudo-stacking-contexts"); + bool isInFixedPos = aBuilder->IsInFixedPos() || + (isPositioned && + disp->mPosition == NS_STYLE_POSITION_FIXED && + nsLayoutUtils::IsReallyFixedPos(child)); + nsDisplayListBuilder::AutoInFixedPosSetter + buildingInFixedPos(aBuilder, isFixedPos); + nsDisplayListBuilder::AutoBuildingDisplayList buildingForChild(aBuilder, child, pseudoStackingContext); DisplayListClipState::AutoClipMultiple clipState(aBuilder); From b8a6537bd44e1490a3b2a4c06df29694f7ccc60c Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Thu, 20 Mar 2014 18:23:16 -0500 Subject: [PATCH 036/101] Bug 874950. Don't let fixed position conclude occlude async scrolled content. r=roc It would be incorrect to occlude async scrolled content. Instead of doing a lot of extra frame tree walking just use the flags on display items to tell if they are in fixed position subtrees. Also, don't let the fixed position flag on display items get set if we start building display items inside a subdocument. If didn't do this non-fixed content in a subdocument that is in fixed content in the parent document would be marked as in fixed position, and no occlusion would occur at all. This means that the fix applies to slightly less cases which are less important so that a more important case works the same as before. --- layout/base/nsDisplayList.cpp | 26 +++++++------------------- layout/generic/nsSubDocumentFrame.cpp | 7 +++++++ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index f8cf77cc4cfb..398a3e1df29c 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1123,11 +1123,6 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder, bool forceTransparentSurface = false; - nsIFrame* displayPortRoot = nullptr; - if (aDisplayPortFrame) { - displayPortRoot = aDisplayPortFrame->PresContext()->PresShell()->GetRootFrame(); - } - for (int32_t i = elements.Length() - 1; i >= 0; --i) { nsDisplayItem* item = elements[i]; nsDisplayItem* belowItem = i < 1 ? nullptr : elements[i - 1]; @@ -1174,21 +1169,14 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder, // If we're in a displayport, we need to make sure that fixed position // items do not subtract from the visible region, as async scrolling // may expose these occluded areas. - // Recurse up this frame to make sure it isn't fixed position, and if it - // is and they're in the same document, don't let it occlude this list. + // If the item is fixed pos in the same document as the displayport + // then don't let it occlude this list. The only other case possible + // is that the fixed pos content is in a child document, in which it + // would scroll with the rest of the content. bool occlude = true; - if (aDisplayPortFrame) { - for (nsIFrame* frame = item->Frame(); frame && frame != displayPortRoot; - frame = nsLayoutUtils::GetCrossDocParentFrame(frame)) { - // Check if this is a fixed position frame on the root frame of the - // document. - if (frame->StyleDisplay()->mPosition == NS_STYLE_POSITION_FIXED && - frame->GetParent() && !frame->GetParent()->GetParent()) { - if (frame->PresContext() == aDisplayPortFrame->PresContext()) { - occlude = false; - } - break; - } + if (aDisplayPortFrame && item->IsInFixedPos()) { + if (item->Frame()->PresContext() == aDisplayPortFrame->PresContext()) { + occlude = false; } } diff --git a/layout/generic/nsSubDocumentFrame.cpp b/layout/generic/nsSubDocumentFrame.cpp index d56977e237d5..044baa042955 100644 --- a/layout/generic/nsSubDocumentFrame.cpp +++ b/layout/generic/nsSubDocumentFrame.cpp @@ -411,6 +411,13 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, haveDisplayPort || presContext->IsRootContentDocument() || (sf && sf->IsScrollingActive()); + // Don't let in fixed pos propagate down to child documents. This makes + // it a little less effective but doesn't regress an important case of a + // child document being in a fixed pos element where we would do no occlusion + // at all if we let it propagate down. + nsDisplayListBuilder::AutoInFixedPosSetter + buildingInFixedPos(aBuilder, false); + nsDisplayList childItems; { From e3c61577eadd6cf99bb58fbfa9f9377e0612e18c Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Thu, 20 Mar 2014 16:31:20 -0700 Subject: [PATCH 037/101] Bug 933462 - [e10s] Pop-up blocking notifications (r=felipe) --- browser/base/content/browser.js | 49 ++++++------- browser/base/content/tabbrowser.xml | 16 ++--- toolkit/content/browser-content.js | 102 ++++++++++++++++++++++++++++ toolkit/content/widgets/browser.xml | 69 +++++++------------ 4 files changed, 154 insertions(+), 82 deletions(-) diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 4be040b95b4c..dd7d24beb5b9 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -433,7 +433,7 @@ var gPopupBlockerObserver = { if (!this._reportButton && gURLBar) this._reportButton = document.getElementById("page-report-button"); - if (!gBrowser.pageReport) { + if (!gBrowser.selectedBrowser.blockedPopups) { // Hide the icon in the location bar (if the location bar exists) if (gURLBar) this._reportButton.hidden = true; @@ -446,11 +446,11 @@ var gPopupBlockerObserver = { // Only show the notification again if we've not already shown it. Since // notifications are per-browser, we don't need to worry about re-adding // it. - if (!gBrowser.pageReport.reported) { + if (!gBrowser.selectedBrowser.blockedPopups.reported) { if (gPrefService.getBoolPref("privacy.popups.showBrowserMessage")) { var brandBundle = document.getElementById("bundle_brand"); var brandShortName = brandBundle.getString("brandShortName"); - var popupCount = gBrowser.pageReport.length; + var popupCount = gBrowser.selectedBrowser.blockedPopups.length; #ifdef XP_WIN var popupButtonText = gNavigatorBundle.getString("popupWarningButton"); var popupButtonAccesskey = gNavigatorBundle.getString("popupWarningButton.accesskey"); @@ -485,7 +485,7 @@ var gPopupBlockerObserver = { // Record the fact that we've reported this blocked popup, so we don't // show it again. - gBrowser.pageReport.reported = true; + gBrowser.selectedBrowser.blockedPopups.reported = true; } }, @@ -502,7 +502,7 @@ var gPopupBlockerObserver = { fillPopupList: function (aEvent) { // XXXben - rather than using |currentURI| here, which breaks down on multi-framed sites - // we should really walk the pageReport and create a list of "allow for " + // we should really walk the blockedPopups and create a list of "allow for " // menuitems for the common subset of hosts present in the report, this will // make us frame-safe. // @@ -510,7 +510,8 @@ var gPopupBlockerObserver = { // also back out the fix for bug 343772 where // nsGlobalWindow::CheckOpenAllow() was changed to also // check if the top window's location is whitelisted. - var uri = gBrowser.currentURI; + let browser = gBrowser.selectedBrowser; + var uri = browser.currentURI; var blockedPopupAllowSite = document.getElementById("blockedPopupAllowSite"); try { blockedPopupAllowSite.removeAttribute("hidden"); @@ -540,16 +541,18 @@ var gPopupBlockerObserver = { blockedPopupAllowSite.removeAttribute("disabled"); var foundUsablePopupURI = false; - var pageReports = gBrowser.pageReport; - if (pageReports) { - for (let pageReport of pageReports) { + var blockedPopups = browser.blockedPopups; + if (blockedPopups) { + for (let i = 0; i < blockedPopups.length; i++) { + let blockedPopup = blockedPopups[i]; + // popupWindowURI will be null if the file picker popup is blocked. // xxxdz this should make the option say "Show file picker" and do it (Bug 590306) - if (!pageReport.popupWindowURI) + if (!blockedPopup.popupWindowURI) continue; - var popupURIspec = pageReport.popupWindowURI.spec; + var popupURIspec = blockedPopup.popupWindowURI; - // Sometimes the popup URI that we get back from the pageReport + // Sometimes the popup URI that we get back from the blockedPopup // isn't useful (for instance, netscape.com's popup URI ends up // being "http://www.netscape.com", which isn't really the URI of // the popup they're trying to show). This isn't going to be @@ -570,11 +573,11 @@ var gPopupBlockerObserver = { [popupURIspec]); menuitem.setAttribute("label", label); menuitem.setAttribute("popupWindowURI", popupURIspec); - menuitem.setAttribute("popupWindowFeatures", pageReport.popupWindowFeatures); - menuitem.setAttribute("popupWindowName", pageReport.popupWindowName); + menuitem.setAttribute("popupWindowFeatures", blockedPopup.popupWindowFeatures); + menuitem.setAttribute("popupWindowName", blockedPopup.popupWindowName); menuitem.setAttribute("oncommand", "gPopupBlockerObserver.showBlockedPopup(event);"); - menuitem.requestingWindow = pageReport.requestingWindow; - menuitem.requestingDocument = pageReport.requestingDocument; + menuitem.setAttribute("popupReportIndex", i); + menuitem.popupReportBrowser = browser; aEvent.target.appendChild(menuitem); } } @@ -613,17 +616,9 @@ var gPopupBlockerObserver = { showBlockedPopup: function (aEvent) { var target = aEvent.target; - var popupWindowURI = target.getAttribute("popupWindowURI"); - var features = target.getAttribute("popupWindowFeatures"); - var name = target.getAttribute("popupWindowName"); - - var dwi = target.requestingWindow; - - // If we have a requesting window and the requesting document is - // still the current document, open the popup. - if (dwi && dwi.document == target.requestingDocument) { - dwi.open(popupWindowURI, name, features); - } + var popupReportIndex = target.getAttribute("popupReportIndex"); + let browser = target.popupReportBrowser; + browser.unblockPopup(popupReportIndex); }, editPopupSettings: function () diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 908fea48f8c3..9086e875eedd 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -996,11 +996,11 @@ oldBrowser.docShellIsActive = false; } - var updatePageReport = false; + var updateBlockedPopups = false; if (!oldBrowser || - (oldBrowser.pageReport && !newBrowser.pageReport) || - (!oldBrowser.pageReport && newBrowser.pageReport)) - updatePageReport = true; + (oldBrowser.blockedPopups && !newBrowser.blockedPopups) || + (!oldBrowser.blockedPopups && newBrowser.blockedPopups)) + updateBlockedPopups = true; newBrowser.setAttribute("type", "content-primary"); newBrowser.docShellIsActive = @@ -1020,8 +1020,8 @@ this._appendStatusPanel(); - if (updatePageReport) - this.mCurrentBrowser.updatePageReport(); + if (updateBlockedPopups) + this.mCurrentBrowser.updateBlockedPopups(false); // Update the URL bar. var loc = this.mCurrentBrowser.currentURI; @@ -2795,10 +2795,6 @@ ]]> - - diff --git a/toolkit/content/browser-content.js b/toolkit/content/browser-content.js index 00d8adcf16f3..976857e59d9f 100644 --- a/toolkit/content/browser-content.js +++ b/toolkit/content/browser-content.js @@ -238,3 +238,105 @@ let ClickEventHandler = { }, }; ClickEventHandler.init(); + +let PopupBlocking = { + popupData: null, + popupDataInternal: null, + + init: function() { + addEventListener("DOMPopupBlocked", this, true); + addEventListener("pageshow", this, true); + addEventListener("pagehide", this, true); + + addMessageListener("PopupBlocking:UnblockPopup", this); + }, + + receiveMessage: function(msg) { + switch (msg.name) { + case "PopupBlocking:UnblockPopup": { + let i = msg.data.index; + if (this.popupData && this.popupData[i]) { + let data = this.popupData[i]; + let internals = this.popupDataInternal[i]; + let dwi = internals.requestingWindow; + + // If we have a requesting window and the requesting document is + // still the current document, open the popup. + if (dwi && dwi.document == internals.requestingDocument) { + dwi.open(data.popupWindowURI, data.popupWindowName, data.popupWindowFeatures); + } + } + break; + } + } + }, + + handleEvent: function(ev) { + switch (ev.type) { + case "DOMPopupBlocked": + return this.onPopupBlocked(ev); + case "pageshow": + return this.onPageShow(ev); + case "pagehide": + return this.onPageHide(ev); + } + }, + + onPopupBlocked: function(ev) { + if (!this.popupData) { + this.popupData = new Array(); + this.popupDataInternal = new Array(); + } + + let obj = { + popupWindowURI: ev.popupWindowURI.spec, + popupWindowFeatures: ev.popupWindowFeatures, + popupWindowName: ev.popupWindowName + }; + + let internals = { + requestingWindow: ev.requestingWindow, + requestingDocument: ev.requestingWindow.document, + }; + + this.popupData.push(obj); + this.popupDataInternal.push(internals); + this.updateBlockedPopups(true); + }, + + onPageShow: function(ev) { + if (this.popupData) { + let i = 0; + while (i < this.popupData.length) { + // Filter out irrelevant reports. + if (this.popupDataInternal[i].requestingWindow && + (this.popupDataInternal[i].requestingWindow.document == + this.popupDataInternal[i].requestingDocument)) { + i++; + } else { + this.popupData.splice(i, 1); + this.popupDataInternal.splice(i, 1); + } + } + if (this.popupData.length == 0) { + this.popupData = null; + this.popupDataInternal = null; + } + this.updateBlockedPopups(false); + } + }, + + onPageHide: function(ev) { + if (this.popupData) { + this.popupData = null; + this.popupDataInternal = null; + this.updateBlockedPopups(false); + } + }, + + updateBlockedPopups: function(freshPopup) { + sendAsyncMessage("PopupBlocking:UpdateBlockedPopups", + {blockedPopups: this.popupData, freshPopup: freshPopup}); + }, +}; +PopupBlocking.init(); \ No newline at end of file diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index 57e70afc0487..48764b7d8819 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -562,22 +562,6 @@ @@ -586,10 +570,6 @@ - + + + - - - - - + + + - null + null + + + @@ -784,9 +761,9 @@ // Listen for first load for lazy attachment to form fill controller this.addEventListener("pageshow", this.onPageShow, true); this.addEventListener("pagehide", this.onPageHide, true); - this.addEventListener("DOMPopupBlocked", this.onPopupBlocked, true); if (this.messageManager) { + this.messageManager.addMessageListener("PopupBlocking:UpdateBlockedPopups", this); this.messageManager.addMessageListener("Autoscroll:Start", this); this.messageManager.addMessageListener("Autoscroll:Cancel", this); this.messageManager.loadFrameScript("chrome://global/content/browser-content.js", true); @@ -831,7 +808,6 @@ this.removeEventListener("pageshow", this.onPageShow, true); this.removeEventListener("pagehide", this.onPageHide, true); - this.removeEventListener("DOMPopupBlocked", this.onPopupBlocked, true); if (this._autoScrollNeedsCleanup) { // we polluted the global scope, so clean it up @@ -850,6 +826,9 @@ Date: Thu, 20 Mar 2014 16:39:30 -0700 Subject: [PATCH 038/101] Back out bug 985687, likely cause of js1_8_5/extensions/recursion.js cantankering. r=CLOSED TREE --- dom/bindings/Codegen.py | 2 +- js/src/frontend/Parser.cpp | 4 +++ js/src/jsapi.h | 11 +++--- js/src/shell/js.cpp | 2 +- js/src/tests/js1_8_5/extensions/mega-let.js | 39 --------------------- js/src/vm/ScopeObject.cpp | 16 ++++++--- js/src/vm/ScopeObject.h | 8 +++++ 7 files changed, 31 insertions(+), 51 deletions(-) delete mode 100644 js/src/tests/js1_8_5/extensions/mega-let.js diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 2ae72c6e955a..74afeecb7eb3 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -1830,7 +1830,7 @@ class AttrDefiner(PropertyDefiner): return self.generatePrefableArray( array, name, - ' { "%s", %s, %s, %s}', + ' { "%s", 0, %s, %s, %s}', ' JS_PS_END', 'JSPropertySpec', PropertyDefiner.getControllingCondition, specData, doIdArrays) diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 515bf3c12401..793355da5691 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -2693,6 +2693,10 @@ Parser::bindLet(BindData *data, Rooted blockObj(cx, data->let.blockObj); unsigned index = blockObj->numVariables(); + if (index >= StaticBlockObject::LOCAL_INDEX_LIMIT) { + parser->report(ParseError, false, pn, data->let.overflow); + return false; + } /* * Assign block-local index to pn->pn_cookie right away, encoding it as an diff --git a/js/src/jsapi.h b/js/src/jsapi.h index f8f5a24f0b32..a2024446c528 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2395,6 +2395,7 @@ struct JSPropertySpec { }; const char *name; + int8_t tinyid; uint8_t flags; union { JSPropertyOpWrapper propertyOp; @@ -2448,26 +2449,26 @@ CheckIsCharacterLiteral(const char (&arr)[N]); * JSNatives. */ #define JS_PSG(name, getter, flags) \ - {name, \ + {name, 0, \ uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \ JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \ JSOP_NULLWRAPPER} #define JS_PSGS(name, getter, setter, flags) \ - {name, \ + {name, 0, \ uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_NATIVE_ACCESSORS), \ JSOP_WRAPPER(JS_CAST_NATIVE_TO(getter, JSPropertyOp)), \ JSOP_WRAPPER(JS_CAST_NATIVE_TO(setter, JSStrictPropertyOp))} #define JS_SELF_HOSTED_GET(name, getterName, flags) \ - {name, \ + {name, 0, \ uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER), \ { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \ JSOP_NULLWRAPPER } #define JS_SELF_HOSTED_GETSET(name, getterName, setterName, flags) \ - {name, \ + {name, 0, \ uint8_t(JS_CHECK_ACCESSOR_FLAGS(flags) | JSPROP_SHARED | JSPROP_GETTER | JSPROP_SETTER), \ { nullptr, JS_CAST_STRING_TO(getterName, const JSJitInfo *) }, \ { nullptr, JS_CAST_STRING_TO(setterName, const JSJitInfo *) } } -#define JS_PS_END { nullptr, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER } +#define JS_PS_END {0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER } /* * To define a native function, set call to a JSNativeWrapper. To define a diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 4b9d2ea72cd5..4b2e049ddbee 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -5159,7 +5159,7 @@ static const JSJitInfo doFoo_methodinfo = { }; static const JSPropertySpec dom_props[] = { - {"x", + {"x", 0, JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS, { { (JSPropertyOp)dom_genericGetter, &dom_x_getterinfo } }, { { (JSStrictPropertyOp)dom_genericSetter, &dom_x_setterinfo } } diff --git a/js/src/tests/js1_8_5/extensions/mega-let.js b/js/src/tests/js1_8_5/extensions/mega-let.js deleted file mode 100644 index e0551a2ff0ae..000000000000 --- a/js/src/tests/js1_8_5/extensions/mega-let.js +++ /dev/null @@ -1,39 +0,0 @@ -// Any copyright is dedicated to the Public Domain. -// http://creativecommons.org/licenses/publicdomain/ - -//----------------------------------------------------------------------------- -var BUGNUMBER = 999999; -var summary = - "Allow defining more than 2**16 let-variables in a single scope"; - -print(BUGNUMBER + ": " + summary); - -/************** - * BEGIN TEST * - **************/ - -print("Creating binding string..."); - -var bindings = []; -var codeStr = "let "; -for (var i = 0; i < Math.pow(2, 20); i++) - bindings.push("x" + i + " = " + i); - -var codeStr = "let " + bindings.join(", ") + ";"; - -print("Binding string created, testing with global eval..."); - -eval(codeStr); - -print("Testing with Function..."); - -Function(codeStr)(); - -print("Testing inside a function..."); - -eval("function q() { " + codeStr + " }; q();"); - -if (typeof reportCompare === "function") - reportCompare(true, true); - -print("Tests complete"); diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index ff190ef61835..f5d62fccdf15 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -684,6 +684,7 @@ StaticBlockObject::addVar(ExclusiveContext *cx, Handle block unsigned index, bool *redeclared) { JS_ASSERT(JSID_IS_ATOM(id)); + JS_ASSERT(index < LOCAL_INDEX_LIMIT); *redeclared = false; @@ -754,19 +755,19 @@ js::XDRStaticBlockObject(XDRState *xdr, HandleObject enclosingScope, if (!xdr->codeUint32(&offset)) return false; - /* - * XDR the block object's properties. We know that there are 'count' - * properties to XDR, stored as id/aliased pairs. (The empty string as - * id indicates an int id.) - */ if (mode == XDR_DECODE) { obj->setLocalOffset(offset); + /* + * XDR the block object's properties. We know that there are 'count' + * properties to XDR, stored as id/shortid pairs. + */ for (unsigned i = 0; i < count; i++) { RootedAtom atom(cx); if (!XDRAtom(xdr, &atom)) return false; + /* The empty string indicates an int id. */ RootedId id(cx, atom != cx->runtime()->emptyString ? AtomToId(atom) : INT_TO_JSID(i)); @@ -792,6 +793,10 @@ js::XDRStaticBlockObject(XDRState *xdr, HandleObject enclosingScope, for (Shape::Range r(obj->lastProperty()); !r.empty(); r.popFront()) shapes[obj->shapeToIndex(r.front())] = &r.front(); + /* + * XDR the block object's properties. We know that there are 'count' + * properties to XDR, stored as id/shortid pairs. + */ RootedShape shape(cx); RootedId propid(cx); RootedAtom atom(cx); @@ -803,6 +808,7 @@ js::XDRStaticBlockObject(XDRState *xdr, HandleObject enclosingScope, propid = shape->propid(); JS_ASSERT(JSID_IS_ATOM(propid) || JSID_IS_INT(propid)); + /* The empty string indicates an int id. */ atom = JSID_IS_ATOM(propid) ? JSID_TO_ATOM(propid) : cx->runtime()->emptyString; diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index 3423c6a5f1f4..b5fe4bd40506 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -532,6 +532,14 @@ class StaticBlockObject : public BlockObject return reinterpret_cast(v.toPrivate()); } + /* + * While ScopeCoordinate can generally reference up to 2^24 slots, block objects have an + * additional limitation that all slot indices must be storable as uint16_t short-ids in the + * associated Shape. If we could remove the block dependencies on shape->shortid, we could + * remove INDEX_LIMIT. + */ + static const unsigned LOCAL_INDEX_LIMIT = JS_BIT(16); + static Shape *addVar(ExclusiveContext *cx, Handle block, HandleId id, unsigned index, bool *redeclared); }; From a32b8effb86643e09ccd7b38d04d7e1231d01843 Mon Sep 17 00:00:00 2001 From: Timothy Nikkel Date: Thu, 20 Mar 2014 18:46:30 -0500 Subject: [PATCH 039/101] Bug 874950. Fix variable name to fix the build. on a CLOSED TREE --- layout/generic/nsFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 1cc69bc3345a..d39a86c4936d 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2304,7 +2304,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, disp->mPosition == NS_STYLE_POSITION_FIXED && nsLayoutUtils::IsReallyFixedPos(child)); nsDisplayListBuilder::AutoInFixedPosSetter - buildingInFixedPos(aBuilder, isFixedPos); + buildingInFixedPos(aBuilder, isInFixedPos); nsDisplayListBuilder::AutoBuildingDisplayList buildingForChild(aBuilder, child, pseudoStackingContext); From 2f79d9a171a8da9d64eefb3dad1db91c55c0f5f9 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Fri, 21 Mar 2014 11:56:32 +1100 Subject: [PATCH 040/101] Bug 983528 - Enable paint-order by default on Release/Beta. r=jwatt --- modules/libpref/src/init/all.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index f4178a06c40e..367c7290e770 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -2010,11 +2010,7 @@ pref("svg.display-lists.hit-testing.enabled", true); pref("svg.display-lists.painting.enabled", true); // Is support for the SVG 2 paint-order property enabled? -#ifdef RELEASE_BUILD -pref("svg.paint-order.enabled", false); -#else pref("svg.paint-order.enabled", true); -#endif // Is support for the new marker features from SVG 2 enabled? Currently // this just includes . From 7a7cb4581f8b2e6e47d4c619870e3a4c9ebb40b1 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 20 Mar 2014 17:46:13 -0700 Subject: [PATCH 041/101] No bug. Fix a misplaced comma in build/automationutils.py. r=nalexander. --HG-- extra : rebase_source : 7f82b008c72c15dfa696d240497c01a44a1fadfa --- build/automationutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/automationutils.py b/build/automationutils.py index 80fc2fe21baa..0a79b2f8bbea 100644 --- a/build/automationutils.py +++ b/build/automationutils.py @@ -81,7 +81,7 @@ DEBUGGER_INFO = { "interactive": False, "args": " ".join(["--leak-check=full", "--show-possibly-lost=no", - "--smc-check=all-non-file," + "--smc-check=all-non-file", "--vex-iropt-register-updates=allregs-at-mem-access"]) } } From 501666c62735f72aee35269e0c7c876a100511af Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 21 Mar 2014 09:16:20 +0800 Subject: [PATCH 042/101] Bug 984786 part 1: Add MOZ_FINAL and private destructors to some refcounted classes in layout. r=dbaron --- layout/base/FrameLayerBuilder.h | 4 +- layout/base/RestyleManager.h | 7 ++++ layout/base/nsPresShell.h | 4 ++ layout/generic/nsGfxScrollFrame.cpp | 3 ++ layout/style/Loader.h | 4 ++ layout/style/nsCSSValue.h | 65 ++++++++++++++++++++++++----- layout/style/nsStyleStruct.h | 9 +++- 7 files changed, 82 insertions(+), 14 deletions(-) diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 195978451d23..e9e6ce865ddc 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -388,15 +388,15 @@ public: /** * Retained data for a display item. */ - class DisplayItemData { + class DisplayItemData MOZ_FINAL { public: friend class FrameLayerBuilder; uint32_t GetDisplayItemKey() { return mDisplayItemKey; } Layer* GetLayer() { return mLayer; } void Invalidate() { mIsInvalid = true; } - protected: + private: DisplayItemData(LayerManagerData* aParent, uint32_t aKey, Layer* aLayer, LayerState aLayerState, uint32_t aGeneration); DisplayItemData(DisplayItemData &toCopy); diff --git a/layout/base/RestyleManager.h b/layout/base/RestyleManager.h index 469496ae46ff..92f1d15dae40 100644 --- a/layout/base/RestyleManager.h +++ b/layout/base/RestyleManager.h @@ -35,6 +35,13 @@ public: RestyleManager(nsPresContext* aPresContext); +private: + // Private destructor, to discourage deletion outside of Release(): + ~RestyleManager() + { + } + +public: NS_INLINE_DECL_REFCOUNTING(mozilla::RestyleManager) void Disconnect() { diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index 71b1da22cc12..b59e6b36220e 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -593,10 +593,14 @@ protected: : mPresShell(aPresShell), mFromScroll(aFromScroll) { NS_ASSERTION(mPresShell, "null parameter"); } + + private: + // Private destructor, to discourage deletion outside of Release(): ~nsSynthMouseMoveEvent() { Revoke(); } + public: NS_INLINE_DECL_REFCOUNTING(nsSynthMouseMoveEvent) void Revoke() { diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 66937c6310e9..d85aecff83c4 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1249,10 +1249,13 @@ public: , mCallee(nullptr) {} +private: + // Private destructor, to discourage deletion outside of Release(): ~AsyncScroll() { RemoveObserver(); } +public: nsPoint PositionAt(TimeStamp aTime); nsSize VelocityAt(TimeStamp aTime); // In nscoords per second diff --git a/layout/style/Loader.h b/layout/style/Loader.h index 34670251dd9f..53e4ce41e292 100644 --- a/layout/style/Loader.h +++ b/layout/style/Loader.h @@ -131,8 +131,12 @@ class Loader MOZ_FINAL { public: Loader(); Loader(nsIDocument*); + + private: + // Private destructor, to discourage deletion outside of Release(): ~Loader(); + public: NS_INLINE_DECL_REFCOUNTING(Loader) void DropDocumentReference(); // notification that doc is going away diff --git a/layout/style/nsCSSValue.h b/layout/style/nsCSSValue.h index 1a4e0c76fa7f..f08429626f3c 100644 --- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -629,7 +629,7 @@ protected: } mValue; }; -struct nsCSSValue::Array { +struct nsCSSValue::Array MOZ_FINAL { // return |Array| with reference count of zero static Array* Create(size_t aItemCount) { @@ -763,17 +763,23 @@ private: // nsCSSValueList_heap differs from nsCSSValueList only in being // refcounted. It should not be necessary to use this class directly; // it's an implementation detail of nsCSSValue. -struct nsCSSValueList_heap : public nsCSSValueList { +struct nsCSSValueList_heap MOZ_FINAL : public nsCSSValueList { NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap) size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + // Private destructor, to discourage deletion outside of Release(): + ~nsCSSValueList_heap() + { + } }; // This is a reference counted list value. Note that the object is // a wrapper for the reference count and a pointer to the head of the // list, whereas the other list types (such as nsCSSValueList) do // not have such a wrapper. -struct nsCSSValueSharedList { +struct nsCSSValueSharedList MOZ_FINAL { nsCSSValueSharedList() : mHead(nullptr) { @@ -787,8 +793,11 @@ struct nsCSSValueSharedList { MOZ_COUNT_CTOR(nsCSSValueSharedList); } +private: + // Private destructor, to discourage deletion outside of Release(): ~nsCSSValueSharedList(); +public: NS_INLINE_DECL_REFCOUNTING(nsCSSValueSharedList) void AppendToString(nsCSSProperty aProperty, nsAString& aResult, @@ -885,10 +894,16 @@ struct nsCSSRect { // nsCSSRect_heap differs from nsCSSRect only in being // refcounted. It should not be necessary to use this class directly; // it's an implementation detail of nsCSSValue. -struct nsCSSRect_heap : public nsCSSRect { +struct nsCSSRect_heap MOZ_FINAL : public nsCSSRect { NS_INLINE_DECL_REFCOUNTING(nsCSSRect_heap) size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + // Private destructor, to discourage deletion outside of Release(): + ~nsCSSRect_heap() + { + } }; // This has to be here so that the relationship between nsCSSRect @@ -974,7 +989,7 @@ struct nsCSSValuePair { // nsCSSValuePair_heap differs from nsCSSValuePair only in being // refcounted. It should not be necessary to use this class directly; // it's an implementation detail of nsCSSValue. -struct nsCSSValuePair_heap : public nsCSSValuePair { +struct nsCSSValuePair_heap MOZ_FINAL : public nsCSSValuePair { // forward constructor nsCSSValuePair_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue) : nsCSSValuePair(aXValue, aYValue) @@ -983,6 +998,12 @@ struct nsCSSValuePair_heap : public nsCSSValuePair { NS_INLINE_DECL_REFCOUNTING(nsCSSValuePair_heap) size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + // Private destructor, to discourage deletion outside of Release(): + ~nsCSSValuePair_heap() + { + } }; struct nsCSSValueTriplet { @@ -1059,7 +1080,7 @@ struct nsCSSValueTriplet { // nsCSSValueTriplet_heap differs from nsCSSValueTriplet only in being // refcounted. It should not be necessary to use this class directly; // it's an implementation detail of nsCSSValue. -struct nsCSSValueTriplet_heap : public nsCSSValueTriplet { +struct nsCSSValueTriplet_heap MOZ_FINAL : public nsCSSValueTriplet { // forward constructor nsCSSValueTriplet_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue, const nsCSSValue& aZValue) : nsCSSValueTriplet(aXValue, aYValue, aZValue) @@ -1068,6 +1089,12 @@ struct nsCSSValueTriplet_heap : public nsCSSValueTriplet { NS_INLINE_DECL_REFCOUNTING(nsCSSValueTriplet_heap) size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + // Private destructor, to discourage deletion outside of Release(): + ~nsCSSValueTriplet_heap() + { + } }; // This has to be here so that the relationship between nsCSSValuePair @@ -1130,10 +1157,16 @@ private: // nsCSSValuePairList_heap differs from nsCSSValuePairList only in being // refcounted. It should not be necessary to use this class directly; // it's an implementation detail of nsCSSValue. -struct nsCSSValuePairList_heap : public nsCSSValuePairList { +struct nsCSSValuePairList_heap MOZ_FINAL : public nsCSSValuePairList { NS_INLINE_DECL_REFCOUNTING(nsCSSValuePairList_heap) size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + // Private destructor, to discourage deletion outside of Release(): + ~nsCSSValuePairList_heap() + { + } }; // This has to be here so that the relationship between nsCSSValuePairList @@ -1201,7 +1234,7 @@ public: size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; }; -struct nsCSSValueGradient { +struct nsCSSValueGradient MOZ_FINAL { nsCSSValueGradient(bool aIsRadial, bool aIsRepeating); // true if gradient is radial, false if it is linear @@ -1293,14 +1326,23 @@ public: size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; private: + // Private destructor, to discourage deletion outside of Release(): + ~nsCSSValueGradient() + { + } + nsCSSValueGradient(const nsCSSValueGradient& aOther) MOZ_DELETE; nsCSSValueGradient& operator=(const nsCSSValueGradient& aOther) MOZ_DELETE; }; -struct nsCSSValueTokenStream { +struct nsCSSValueTokenStream MOZ_FINAL { nsCSSValueTokenStream(); + +private: + // Private destructor, to discourage deletion outside of Release(): ~nsCSSValueTokenStream(); +public: bool operator==(const nsCSSValueTokenStream& aOther) const { bool eq; @@ -1372,7 +1414,7 @@ private: nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) MOZ_DELETE; }; -class nsCSSValueFloatColor { +class nsCSSValueFloatColor MOZ_FINAL { public: nsCSSValueFloatColor(float aComponent1, float aComponent2, float aComponent3, float aAlpha) @@ -1384,11 +1426,14 @@ public: MOZ_COUNT_CTOR(nsCSSValueFloatColor); } +private: + // Private destructor, to discourage deletion outside of Release(): ~nsCSSValueFloatColor() { MOZ_COUNT_DTOR(nsCSSValueFloatColor); } +public: bool operator==(nsCSSValueFloatColor& aOther) const; nscolor GetColorValue(nsCSSUnit aUnit) const; diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index 41a84b385621..0f004042e3df 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -131,7 +131,7 @@ struct nsStyleGradientStop { nscolor mColor; }; -class nsStyleGradient { +class nsStyleGradient MOZ_FINAL { public: nsStyleGradient(); uint8_t mShape; // NS_STYLE_GRADIENT_SHAPE_* @@ -162,6 +162,7 @@ public: NS_INLINE_DECL_REFCOUNTING(nsStyleGradient) private: + // Private destructor, to discourage deletion outside of Release(): ~nsStyleGradient() {} nsStyleGradient(const nsStyleGradient& aOther) MOZ_DELETE; @@ -706,7 +707,7 @@ struct nsCSSShadowItem { } }; -class nsCSSShadowArray { +class nsCSSShadowArray MOZ_FINAL { public: void* operator new(size_t aBaseSize, uint32_t aArrayLen) { // We can allocate both this nsCSSShadowArray and the @@ -728,6 +729,9 @@ class nsCSSShadowArray { new (&mArray[i]) nsCSSShadowItem(); } } + +private: + // Private destructor, to discourage deletion outside of Release(): ~nsCSSShadowArray() { MOZ_COUNT_DTOR(nsCSSShadowArray); for (uint32_t i = 1; i < mLength; ++i) { @@ -735,6 +739,7 @@ class nsCSSShadowArray { } } +public: uint32_t Length() const { return mLength; } nsCSSShadowItem* ShadowAt(uint32_t i) { NS_ABORT_IF_FALSE(i < mLength, "Accessing too high an index in the text shadow array!"); From 3fb7e0486adcf0546e3d5a9ac93e7fee2f660291 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Fri, 21 Mar 2014 09:16:23 +0800 Subject: [PATCH 043/101] Bug 985955: Add eStyleUnit_FlexFraction to list of ignored style units in accessibility code that checks text positioning properties. r=tbsaunde --- accessible/src/base/StyleInfo.cpp | 1 + accessible/src/base/TextAttrs.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/accessible/src/base/StyleInfo.cpp b/accessible/src/base/StyleInfo.cpp index 0f14e45019d1..c4e2203ffa6b 100644 --- a/accessible/src/base/StyleInfo.cpp +++ b/accessible/src/base/StyleInfo.cpp @@ -74,6 +74,7 @@ StyleInfo::TextIndent(nsAString& aValue) case eStyleUnit_Grad: case eStyleUnit_Radian: case eStyleUnit_Turn: + case eStyleUnit_FlexFraction: case eStyleUnit_Integer: case eStyleUnit_Enumerated: case eStyleUnit_Calc: diff --git a/accessible/src/base/TextAttrs.cpp b/accessible/src/base/TextAttrs.cpp index 191025383df5..3e94af8afa70 100644 --- a/accessible/src/base/TextAttrs.cpp +++ b/accessible/src/base/TextAttrs.cpp @@ -861,6 +861,7 @@ TextAttrsMgr::TextPosTextAttr:: case eStyleUnit_Grad: case eStyleUnit_Radian: case eStyleUnit_Turn: + case eStyleUnit_FlexFraction: case eStyleUnit_Integer: case eStyleUnit_Calc: break; From 0c395be75f7ef542946cc4fb44c8c75c3e11758f Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:21:03 +1200 Subject: [PATCH 044/101] Bug 917755. Part 1: Add nsLayoutUtils::TransformCSSPoints and nsLayoutUtils::GetFirstNonAnonymousFrame. r=matspal --HG-- extra : rebase_source : 06e2c83a984d12fce29cd23b93dde54a2e05cf43 --- layout/base/nsLayoutUtils.cpp | 97 +++++++++++++++++++++++++++++++++++ layout/base/nsLayoutUtils.h | 71 +++++++++++++++++-------- 2 files changed, 146 insertions(+), 22 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 29c40af562f9..173eaae5c2c9 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1893,6 +1893,66 @@ nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncesto return ctm; } +static nsIFrame* +FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2) +{ + nsAutoTArray ancestors1; + nsAutoTArray ancestors2; + nsIFrame* commonAncestor = nullptr; + if (aFrame1->PresContext() == aFrame2->PresContext()) { + commonAncestor = aFrame1->PresContext()->PresShell()->GetRootFrame(); + } + for (nsIFrame* f = aFrame1; f != commonAncestor; + f = nsLayoutUtils::GetCrossDocParentFrame(f)) { + ancestors1.AppendElement(f); + } + for (nsIFrame* f = aFrame2; f != commonAncestor; + f = nsLayoutUtils::GetCrossDocParentFrame(f)) { + ancestors2.AppendElement(f); + } + uint32_t minLengths = std::min(ancestors1.Length(), ancestors2.Length()); + for (uint32_t i = 1; i <= minLengths; ++i) { + if (ancestors1[ancestors1.Length() - i] == ancestors2[ancestors2.Length() - i]) { + commonAncestor = ancestors1[ancestors1.Length() - i]; + } else { + break; + } + } + return commonAncestor; +} + +nsLayoutUtils::TransformResult +nsLayoutUtils::TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame, + uint32_t aPointCount, CSSPoint* aPoints) +{ + nsIFrame* nearestCommonAncestor = FindNearestCommonAncestorFrame(aFromFrame, aToFrame); + if (!nearestCommonAncestor) { + return NO_COMMON_ANCESTOR; + } + gfx3DMatrix downToDest = GetTransformToAncestor(aToFrame, nearestCommonAncestor); + if (downToDest.IsSingular()) { + return NONINVERTIBLE_TRANSFORM; + } + downToDest.Invert(); + gfx3DMatrix upToAncestor = GetTransformToAncestor(aFromFrame, nearestCommonAncestor); + CSSToLayoutDeviceScale devPixelsPerCSSPixelFromFrame( + double(nsPresContext::AppUnitsPerCSSPixel())/ + aFromFrame->PresContext()->AppUnitsPerDevPixel()); + CSSToLayoutDeviceScale devPixelsPerCSSPixelToFrame( + double(nsPresContext::AppUnitsPerCSSPixel())/ + aToFrame->PresContext()->AppUnitsPerDevPixel()); + for (uint32_t i = 0; i < aPointCount; ++i) { + LayoutDevicePoint devPixels = aPoints[i] * devPixelsPerCSSPixelFromFrame; + gfxPoint toDevPixels = downToDest.ProjectPoint( + upToAncestor.ProjectPoint(gfxPoint(devPixels.x, devPixels.y))); + // Divide here so that when the devPixelsPerCSSPixels are the same, we get the correct + // answer instead of some inaccuracy multiplying a number by its reciprocal. + aPoints[i] = LayoutDevicePoint(toDevPixels.x, toDevPixels.y) / + devPixelsPerCSSPixelToFrame; + } + return TRANSFORM_SUCCEEDED; +} + bool nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame, gfx3DMatrix* aTransform) @@ -2586,6 +2646,43 @@ nsLayoutUtils::GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback) } } +nsIFrame* +nsLayoutUtils::GetFirstNonAnonymousFrame(nsIFrame* aFrame) +{ + while (aFrame) { + nsIAtom* pseudoType = aFrame->StyleContext()->GetPseudo(); + + if (pseudoType == nsCSSAnonBoxes::tableOuter) { + nsIFrame* f = GetFirstNonAnonymousFrame(aFrame->GetFirstPrincipalChild()); + if (f) { + return f; + } + nsIFrame* kid = aFrame->GetFirstChild(nsIFrame::kCaptionList); + if (kid) { + f = GetFirstNonAnonymousFrame(kid); + if (f) { + return f; + } + } + } else if (pseudoType == nsCSSAnonBoxes::mozAnonymousBlock || + pseudoType == nsCSSAnonBoxes::mozAnonymousPositionedBlock || + pseudoType == nsCSSAnonBoxes::mozMathMLAnonymousBlock || + pseudoType == nsCSSAnonBoxes::mozXULAnonymousBlock) { + for (nsIFrame* kid = aFrame->GetFirstPrincipalChild(); kid; kid = kid->GetNextSibling()) { + nsIFrame* f = GetFirstNonAnonymousFrame(kid); + if (f) { + return f; + } + } + } else { + return aFrame; + } + + aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame); + } + return nullptr; +} + struct BoxToRect : public nsLayoutUtils::BoxCallback { nsIFrame* mRelativeTo; nsLayoutUtils::RectCallback* mCallback; diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index a5eeeacec8c5..e61449e5539c 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -6,6 +6,29 @@ #ifndef nsLayoutUtils_h__ #define nsLayoutUtils_h__ +#include "mozilla/MemoryReporting.h" +#include "nsChangeHint.h" +#include "nsAutoPtr.h" +#include "nsFrameList.h" +#include "nsThreadUtils.h" +#include "nsIPrincipal.h" +#include "GraphicsFilter.h" +#include "nsCSSPseudoElements.h" +#include "FrameMetrics.h" +#include "gfx3DMatrix.h" +#include "nsIWidget.h" +#include "nsCSSProperty.h" +#include "nsStyleCoord.h" +#include "nsStyleConsts.h" +#include "nsGkAtoms.h" +#include "nsRuleNode.h" +#include "imgIContainer.h" +#include "mozilla/gfx/2D.h" +#include "Units.h" + +#include +#include + class nsIFormControlFrame; class nsPresContext; class nsIContent; @@ -30,32 +53,11 @@ class gfxContext; class nsPIDOMWindow; class imgIRequest; class nsIDocument; +class gfxPoint; struct nsStyleFont; struct nsStyleImageOrientation; struct nsOverflowAreas; -#include "mozilla/MemoryReporting.h" -#include "nsChangeHint.h" -#include "nsAutoPtr.h" -#include "nsFrameList.h" -#include "nsThreadUtils.h" -#include "nsIPrincipal.h" -#include "GraphicsFilter.h" -#include "nsCSSPseudoElements.h" -#include "FrameMetrics.h" -#include "gfx3DMatrix.h" -#include "nsIWidget.h" -#include "nsCSSProperty.h" -#include "nsStyleCoord.h" -#include "nsStyleConsts.h" -#include "nsGkAtoms.h" -#include "nsRuleNode.h" -#include "imgIContainer.h" -#include "mozilla/gfx/2D.h" - -#include -#include - namespace mozilla { class SVGImageContext; struct IntrinsicSize; @@ -107,6 +109,7 @@ class nsLayoutUtils public: typedef mozilla::layers::FrameMetrics FrameMetrics; typedef FrameMetrics::ViewID ViewID; + typedef mozilla::CSSPoint CSSPoint; /** * Finds previously assigned ViewID for the given content element, if any. @@ -683,6 +686,24 @@ public: */ static gfx3DMatrix GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor); + /** + * Transforms a list of CSSPoints from aFromFrame to aToFrame, taking into + * account all relevant transformations on the frames up to (but excluding) + * their nearest common ancestor. + * If we encounter a transform that we need to invert but which is + * non-invertible, we return NONINVERTIBLE_TRANSFORM. If the frames have + * no common ancestor, we return NO_COMMON_ANCESTOR. + * If this returns TRANSFORM_SUCCEEDED, the points in aPoints are transformed + * in-place, otherwise they are untouched. + */ + enum TransformResult { + TRANSFORM_SUCCEEDED, + NO_COMMON_ANCESTOR, + NONINVERTIBLE_TRANSFORM + }; + static TransformResult TransformPoints(nsIFrame* aFromFrame, nsIFrame* aToFrame, + uint32_t aPointCount, CSSPoint* aPoints); + /** * Return true if a "layer transform" could be computed for aFrame, * and optionally return the computed transform. The returned @@ -877,6 +898,12 @@ public: */ static void GetAllInFlowBoxes(nsIFrame* aFrame, BoxCallback* aCallback); + /** + * Find the first frame descendant of aFrame (including aFrame) which is + * not an anonymous frame that getBoxQuads/getClientRects should ignore. + */ + static nsIFrame* GetFirstNonAnonymousFrame(nsIFrame* aFrame); + class RectCallback { public: virtual void AddRect(const nsRect& aRect) = 0; From 98c2c7100d1831ac0ed08ce5ef8e97026ea8242d Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:37 +0800 Subject: [PATCH 045/101] Bug 917755. Part 1.5: Make nsImageLoadingContent more robust in unified builds. r=matspal --HG-- extra : rebase_source : be9acaac5b213666d02d1f6a95f132c46a7ada48 --- content/base/src/nsImageLoadingContent.cpp | 2 +- content/base/src/nsImageLoadingContent.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/content/base/src/nsImageLoadingContent.cpp b/content/base/src/nsImageLoadingContent.cpp index 64c7b0c8afd4..9548bc94e903 100644 --- a/content/base/src/nsImageLoadingContent.cpp +++ b/content/base/src/nsImageLoadingContent.cpp @@ -47,7 +47,7 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/ScriptSettings.h" -#if defined(XP_WIN) +#ifdef LoadImage // Undefine LoadImage to prevent naming conflict with Windows. #undef LoadImage #endif diff --git a/content/base/src/nsImageLoadingContent.h b/content/base/src/nsImageLoadingContent.h index 328124a757e6..7d5c5f3422fa 100644 --- a/content/base/src/nsImageLoadingContent.h +++ b/content/base/src/nsImageLoadingContent.h @@ -31,6 +31,11 @@ class nsPresContext; class nsIContent; class imgRequestProxy; +#ifdef LoadImage +// Undefine LoadImage to prevent naming conflict with Windows. +#undef LoadImage +#endif + class nsImageLoadingContent : public nsIImageLoadingContent, public imgIOnloadBlocker { From 7adeaa75fa6db5fe7d592f3043b275ee610165d3 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:37 +0800 Subject: [PATCH 046/101] Bug 917755. Part 2: Implement DOMPoint. r=jst DOMPointReadOnly is not currently used by anything but it's in the spec so we might as well support it. It would be useful for adding "topLeft"-style APIs to DOMRect. --HG-- extra : rebase_source : 8df6b51b3305e91c7c7693128e70e3e928d44b27 --- content/base/src/DOMPoint.cpp | 43 ++++++++++ content/base/src/DOMPoint.h | 78 +++++++++++++++++++ content/base/src/moz.build | 2 + dom/bindings/Bindings.conf | 5 ++ .../mochitest/general/test_interfaces.html | 4 + dom/webidl/DOMPoint.webidl | 37 +++++++++ dom/webidl/moz.build | 1 + modules/libpref/src/init/all.js | 3 + 8 files changed, 173 insertions(+) create mode 100644 content/base/src/DOMPoint.cpp create mode 100644 content/base/src/DOMPoint.h create mode 100644 dom/webidl/DOMPoint.webidl diff --git a/content/base/src/DOMPoint.cpp b/content/base/src/DOMPoint.cpp new file mode 100644 index 000000000000..5414455683fa --- /dev/null +++ b/content/base/src/DOMPoint.cpp @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/DOMPoint.h" + +#include "mozilla/dom/DOMPointBinding.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "nsAutoPtr.h" + +using namespace mozilla; +using namespace mozilla::dom; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMPoint, mParent) + +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMPoint, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMPoint, Release) + +already_AddRefed +DOMPoint::Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams, + ErrorResult& aRV) +{ + nsRefPtr obj = + new DOMPoint(aGlobal.GetAsSupports(), aParams.mX, aParams.mY, + aParams.mZ, aParams.mW); + return obj.forget(); +} + +already_AddRefed +DOMPoint::Constructor(const GlobalObject& aGlobal, double aX, double aY, + double aZ, double aW, ErrorResult& aRV) +{ + nsRefPtr obj = + new DOMPoint(aGlobal.GetAsSupports(), aX, aY, aZ, aW); + return obj.forget(); +} + +JSObject* +DOMPoint::WrapObject(JSContext* aCx, JS::Handle aScope) +{ + return DOMPointBinding::Wrap(aCx, aScope, this); +} diff --git a/content/base/src/DOMPoint.h b/content/base/src/DOMPoint.h new file mode 100644 index 000000000000..6e69f7aae73a --- /dev/null +++ b/content/base/src/DOMPoint.h @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_DOMPOINT_H_ +#define MOZILLA_DOMPOINT_H_ + +#include "nsWrapperCache.h" +#include "nsISupports.h" +#include "nsCycleCollectionParticipant.h" +#include "mozilla/Attributes.h" +#include "mozilla/ErrorResult.h" +#include "nsCOMPtr.h" +#include "mozilla/dom/BindingDeclarations.h" + +namespace mozilla { +namespace dom { + +class GlobalObject; +class DOMPointInit; + +class DOMPointReadOnly : public nsWrapperCache +{ +public: + DOMPointReadOnly(nsISupports* aParent, double aX, double aY, + double aZ, double aW) + : mParent(aParent) + , mX(aX) + , mY(aY) + , mZ(aZ) + , mW(aW) + { + SetIsDOMBinding(); + } + + double X() const { return mX; } + double Y() const { return mY; } + double Z() const { return mZ; } + double W() const { return mW; } + +protected: + nsCOMPtr mParent; + double mX, mY, mZ, mW; +}; + +class DOMPoint MOZ_FINAL : public DOMPointReadOnly +{ +public: + DOMPoint(nsISupports* aParent, double aX = 0.0, double aY = 0.0, + double aZ = 0.0, double aW = 1.0) + : DOMPointReadOnly(aParent, aX, aY, aZ, aW) + {} + + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMPoint) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMPoint) + + static already_AddRefed + Constructor(const GlobalObject& aGlobal, const DOMPointInit& aParams, + ErrorResult& aRV); + static already_AddRefed + Constructor(const GlobalObject& aGlobal, double aX, double aY, + double aZ, double aW, ErrorResult& aRV); + + nsISupports* GetParentObject() const { return mParent; } + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aScope) MOZ_OVERRIDE; + + void SetX(double aX) { mX = aX; } + void SetY(double aY) { mY = aY; } + void SetZ(double aZ) { mZ = aZ; } + void SetW(double aW) { mW = aW; } +}; + +} +} + +#endif /*MOZILLA_DOMPOINT_H_*/ diff --git a/content/base/src/moz.build b/content/base/src/moz.build index c7bb37fd8517..bda6ff921fc3 100644 --- a/content/base/src/moz.build +++ b/content/base/src/moz.build @@ -60,6 +60,7 @@ EXPORTS.mozilla.dom += [ 'DocumentType.h', 'DOMImplementation.h', 'DOMParser.h', + 'DOMPoint.h', 'DOMRect.h', 'DOMStringList.h', 'EventSource.h', @@ -79,6 +80,7 @@ UNIFIED_SOURCES += [ 'DocumentType.cpp', 'DOMImplementation.cpp', 'DOMParser.cpp', + 'DOMPoint.cpp', 'DOMRect.cpp', 'DOMStringList.cpp', 'Element.cpp', diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index e6209f63f03a..561d234b163c 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -225,6 +225,11 @@ DOMInterfaces = { 'resultNotAddRefed': [ 'item' ] }, +'DOMPointReadOnly': { + 'headerFile': 'mozilla/dom/DOMPoint.h', + 'concrete': False, +}, + 'Console': { 'implicitJSContext': [ 'trace', 'time', 'timeEnd' ], }, diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 146665b4b69b..52b5711aa3fa 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -305,6 +305,10 @@ var interfaceNamesInGlobalScope = "DOMMMIError", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMParser", +// IMPORTANT: Do not change this list without review from a DOM peer! + "DOMPoint", +// IMPORTANT: Do not change this list without review from a DOM peer! + "DOMPointReadOnly", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMRect", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/DOMPoint.webidl b/dom/webidl/DOMPoint.webidl new file mode 100644 index 000000000000..d092d900f51e --- /dev/null +++ b/dom/webidl/DOMPoint.webidl @@ -0,0 +1,37 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/fxtf/geometry/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +[Pref="layout.css.DOMPoint.enabled"] +interface DOMPointReadOnly { + readonly attribute unrestricted double x; + readonly attribute unrestricted double y; + readonly attribute unrestricted double z; + readonly attribute unrestricted double w; +}; + +[Pref="layout.css.DOMPoint.enabled", + Constructor(optional DOMPointInit point), + Constructor(unrestricted double x, unrestricted double y, + optional unrestricted double z = 0, optional unrestricted double w = 1)] +interface DOMPoint : DOMPointReadOnly { + inherit attribute unrestricted double x; + inherit attribute unrestricted double y; + inherit attribute unrestricted double z; + inherit attribute unrestricted double w; +}; + +dictionary DOMPointInit { + unrestricted double x = 0; + unrestricted double y = 0; + unrestricted double z = 0; + unrestricted double w = 1; +}; \ No newline at end of file diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index ae24ef7f42cd..03f9418eee82 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -83,6 +83,7 @@ WEBIDL_FILES = [ 'DOMImplementation.webidl', 'DOMMMIError.webidl', 'DOMParser.webidl', + 'DOMPoint.webidl', 'DOMRect.webidl', 'DOMRectList.webidl', 'DOMRequest.webidl', diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 367c7290e770..587b6c3eb60b 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1810,6 +1810,9 @@ pref("layout.css.sticky.enabled", true); // Is support for CSS "will-change" enabled? pref("layout.css.will-change.enabled", false); +// Is support for DOMPoint enabled? +pref("layout.css.DOMPoint.enabled", true); + // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From 416a4278f9f98713f3a173a4fd7ad1ca59028d62 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:21:03 +1200 Subject: [PATCH 047/101] Bug 917755. Part 3: Implement DOMRect per spec. r=jst --HG-- extra : rebase_source : 46ef3a90763ceaea5bb43652e5c97e16667a9e7f --- content/base/src/DOMRect.cpp | 43 +++++- content/base/src/DOMRect.h | 139 ++++++++++++------ dom/bindings/Bindings.conf | 24 +-- .../mochitest/general/test_interfaces.html | 2 + dom/webidl/DOMRect.webidl | 36 +++-- dom/webidl/LegacyQueryInterface.webidl | 2 - 6 files changed, 176 insertions(+), 70 deletions(-) diff --git a/content/base/src/DOMRect.cpp b/content/base/src/DOMRect.cpp index 6223c158d850..f0d5a8f7120f 100644 --- a/content/base/src/DOMRect.cpp +++ b/content/base/src/DOMRect.cpp @@ -3,7 +3,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "DOMRect.h" +#include "mozilla/dom/DOMRect.h" #include "nsPresContext.h" #include "mozilla/dom/DOMRectListBinding.h" @@ -12,20 +12,30 @@ using namespace mozilla; using namespace mozilla::dom; -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMRect, mParent) -NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRect) -NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRect) -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRect) +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(DOMRectReadOnly, mParent) +NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectReadOnly) +NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectReadOnly) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMRectReadOnly) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(nsIDOMClientRect) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END +JSObject* +DOMRectReadOnly::WrapObject(JSContext* aCx, JS::Handle aScope) +{ + MOZ_ASSERT(mParent); + return DOMRectReadOnlyBinding::Wrap(aCx, aScope, this); +} + +// ----------------------------------------------------------------------------- + +NS_IMPL_ISUPPORTS_INHERITED1(DOMRect, DOMRectReadOnly, nsIDOMClientRect) + #define FORWARD_GETTER(_name) \ NS_IMETHODIMP \ DOMRect::Get ## _name(float* aResult) \ { \ - *aResult = _name(); \ + *aResult = float(_name()); \ return NS_OK; \ } @@ -43,6 +53,23 @@ DOMRect::WrapObject(JSContext* aCx, JS::Handle aScope) return DOMRectBinding::Wrap(aCx, aScope, this); } +already_AddRefed +DOMRect::Constructor(const GlobalObject& aGlobal, ErrorResult& aRV) +{ + nsRefPtr obj = + new DOMRect(aGlobal.GetAsSupports(), 0.0, 0.0, 0.0, 0.0); + return obj.forget(); +} + +already_AddRefed +DOMRect::Constructor(const GlobalObject& aGlobal, double aX, double aY, + double aWidth, double aHeight, ErrorResult& aRV) +{ + nsRefPtr obj = + new DOMRect(aGlobal.GetAsSupports(), aX, aY, aWidth, aHeight); + return obj.forget(); +} + // ----------------------------------------------------------------------------- NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(DOMRectList, mParent, mArray) @@ -57,7 +84,7 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMRectList) NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMRectList) -NS_IMETHODIMP +NS_IMETHODIMP DOMRectList::GetLength(uint32_t* aLength) { *aLength = Length(); diff --git a/content/base/src/DOMRect.h b/content/base/src/DOMRect.h index ae3db528683c..bdef9ce37c2b 100644 --- a/content/base/src/DOMRect.h +++ b/content/base/src/DOMRect.h @@ -14,33 +14,29 @@ #include "nsWrapperCache.h" #include "nsCycleCollectionParticipant.h" #include "mozilla/Attributes.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/ErrorResult.h" +#include struct nsRect; namespace mozilla { namespace dom { -class DOMRect MOZ_FINAL : public nsIDOMClientRect - , public nsWrapperCache +class DOMRectReadOnly : public nsISupports + , public nsWrapperCache { public: - DOMRect(nsISupports* aParent) - : mParent(aParent), mX(0.0), mY(0.0), mWidth(0.0), mHeight(0.0) + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRectReadOnly) + + virtual ~DOMRectReadOnly() {} + + DOMRectReadOnly(nsISupports* aParent) + : mParent(aParent) { SetIsDOMBinding(); } - virtual ~DOMRect() {} - - void SetRect(float aX, float aY, float aWidth, float aHeight) { - mX = aX; mY = aY; mWidth = aWidth; mHeight = aHeight; - } - void SetLayoutRect(const nsRect& aLayoutRect); - - - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMRect) - NS_DECL_NSIDOMCLIENTRECT - nsISupports* GetParentObject() const { @@ -50,40 +46,103 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aScope) MOZ_OVERRIDE; + virtual double X() const = 0; + virtual double Y() const = 0; + virtual double Width() const = 0; + virtual double Height() const = 0; - float Left() const + double Left() const { - return mX; + double x = X(), w = Width(); + return std::min(x, x + w); } - - float Top() const + double Top() const { - return mY; + double y = Y(), h = Height(); + return std::min(y, y + h); } - - float Right() const + double Right() const { - return mX + mWidth; + double x = X(), w = Width(); + return std::max(x, x + w); } - - float Bottom() const + double Bottom() const { - return mY + mHeight; - } - - float Width() const - { - return mWidth; - } - - float Height() const - { - return mHeight; + double y = Y(), h = Height(); + return std::max(y, y + h); } protected: nsCOMPtr mParent; - float mX, mY, mWidth, mHeight; +}; + +class DOMRect MOZ_FINAL : public DOMRectReadOnly + , public nsIDOMClientRect +{ +public: + DOMRect(nsISupports* aParent, double aX = 0, double aY = 0, + double aWidth = 0, double aHeight = 0) + : DOMRectReadOnly(aParent) + , mX(aX) + , mY(aY) + , mWidth(aWidth) + , mHeight(aHeight) + { + } + + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIDOMCLIENTRECT + + static already_AddRefed + Constructor(const GlobalObject& aGlobal, ErrorResult& aRV); + static already_AddRefed + Constructor(const GlobalObject& aGlobal, double aX, double aY, + double aWidth, double aHeight, ErrorResult& aRV); + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aScope) MOZ_OVERRIDE; + + void SetRect(float aX, float aY, float aWidth, float aHeight) { + mX = aX; mY = aY; mWidth = aWidth; mHeight = aHeight; + } + void SetLayoutRect(const nsRect& aLayoutRect); + + virtual double X() const MOZ_OVERRIDE + { + return mX; + } + virtual double Y() const MOZ_OVERRIDE + { + return mY; + } + virtual double Width() const MOZ_OVERRIDE + { + return mWidth; + } + virtual double Height() const MOZ_OVERRIDE + { + return mHeight; + } + + void SetX(double aX) + { + mX = aX; + } + void SetY(double aY) + { + mY = aY; + } + void SetWidth(double aWidth) + { + mWidth = aWidth; + } + void SetHeight(double aHeight) + { + mHeight = aHeight; + } + +protected: + double mX, mY, mWidth, mHeight; }; class DOMRectList MOZ_FINAL : public nsIDOMClientRectList, @@ -145,9 +204,7 @@ public: } protected: - virtual ~DOMRectList() {} - - nsTArray< nsRefPtr > mArray; + nsTArray > mArray; nsCOMPtr mParent; }; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 561d234b163c..63bd7b9ec2da 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -220,16 +220,6 @@ DOMInterfaces = { 'nativeType': 'mozilla::dom::workers::ChromeWorkerPrivate', }, -'DOMRectList': { - 'headerFile': 'mozilla/dom/DOMRect.h', - 'resultNotAddRefed': [ 'item' ] -}, - -'DOMPointReadOnly': { - 'headerFile': 'mozilla/dom/DOMPoint.h', - 'concrete': False, -}, - 'Console': { 'implicitJSContext': [ 'trace', 'time', 'timeEnd' ], }, @@ -338,6 +328,20 @@ DOMInterfaces = { }, }, +'DOMPointReadOnly': { + 'headerFile': 'mozilla/dom/DOMPoint.h', + 'concrete': False, +}, + +'DOMRectList': { + 'headerFile': 'mozilla/dom/DOMRect.h', + 'resultNotAddRefed': [ 'item' ] +}, + +'DOMRectReadOnly': { + 'headerFile': 'mozilla/dom/DOMRect.h', +}, + 'DOMSettableTokenList': { 'nativeType': 'nsDOMSettableTokenList', }, diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 52b5711aa3fa..0cf08f3cfeb5 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -313,6 +313,8 @@ var interfaceNamesInGlobalScope = "DOMRect", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMRectList", +// IMPORTANT: Do not change this list without review from a DOM peer! + "DOMRectReadOnly", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMRequest", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/DOMRect.webidl b/dom/webidl/DOMRect.webidl index 73adf4a4bedf..1e817106cdb9 100644 --- a/dom/webidl/DOMRect.webidl +++ b/dom/webidl/DOMRect.webidl @@ -1,14 +1,32 @@ /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/fxtf/geometry/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ -interface DOMRect -{ - readonly attribute float left; - readonly attribute float top; - readonly attribute float right; - readonly attribute float bottom; - readonly attribute float width; - readonly attribute float height; +[Constructor, + Constructor(unrestricted double x, unrestricted double y, + unrestricted double width, unrestricted double height)] +interface DOMRect : DOMRectReadOnly { + inherit attribute unrestricted double x; + inherit attribute unrestricted double y; + inherit attribute unrestricted double width; + inherit attribute unrestricted double height; }; + +interface DOMRectReadOnly { + readonly attribute unrestricted double x; + readonly attribute unrestricted double y; + readonly attribute unrestricted double width; + readonly attribute unrestricted double height; + readonly attribute unrestricted double top; + readonly attribute unrestricted double right; + readonly attribute unrestricted double bottom; + readonly attribute unrestricted double left; +}; \ No newline at end of file diff --git a/dom/webidl/LegacyQueryInterface.webidl b/dom/webidl/LegacyQueryInterface.webidl index fbe00d2c9f8b..20d70c5d6f33 100644 --- a/dom/webidl/LegacyQueryInterface.webidl +++ b/dom/webidl/LegacyQueryInterface.webidl @@ -24,8 +24,6 @@ CSSStyleDeclaration implements LegacyQueryInterface; CSSValueList implements LegacyQueryInterface; DOMImplementation implements LegacyQueryInterface; DOMParser implements LegacyQueryInterface; -DOMRect implements LegacyQueryInterface; -DOMRectList implements LegacyQueryInterface; DOMStringMap implements LegacyQueryInterface; DOMTokenList implements LegacyQueryInterface; Document implements LegacyQueryInterface; From 67b726752bf584fe1dc7739a6019570db2569b32 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:21:04 +1200 Subject: [PATCH 048/101] Bug 917755. Part 4: Add DOMQuad implementation. r=jst --HG-- extra : rebase_source : e74d516f27c004ecf5deea40fb397c2a8f5acfae --- content/base/src/DOMQuad.cpp | 159 ++++++++++++++++++ content/base/src/DOMQuad.h | 70 ++++++++ content/base/src/moz.build | 2 + dom/bindings/Bindings.conf | 4 + .../mochitest/general/test_interfaces.html | 2 + dom/webidl/DOMQuad.webidl | 23 +++ dom/webidl/moz.build | 1 + modules/libpref/src/init/all.js | 3 + 8 files changed, 264 insertions(+) create mode 100644 content/base/src/DOMQuad.cpp create mode 100644 content/base/src/DOMQuad.h create mode 100644 dom/webidl/DOMQuad.webidl diff --git a/content/base/src/DOMQuad.cpp b/content/base/src/DOMQuad.cpp new file mode 100644 index 000000000000..1445a531f06d --- /dev/null +++ b/content/base/src/DOMQuad.cpp @@ -0,0 +1,159 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/DOMQuad.h" + +#include "mozilla/dom/DOMQuadBinding.h" +#include "mozilla/dom/DOMPoint.h" +#include "mozilla/dom/DOMRect.h" +#include + +using namespace mozilla; +using namespace mozilla::dom; +using namespace mozilla::gfx; + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_6(DOMQuad, mParent, mBounds, mPoints[0], + mPoints[1], mPoints[2], mPoints[3]) + +NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMQuad, AddRef) +NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMQuad, Release) + +DOMQuad::DOMQuad(nsISupports* aParent, CSSPoint aPoints[4]) + : mParent(aParent) +{ + SetIsDOMBinding(); + for (uint32_t i = 0; i < 4; ++i) { + mPoints[i] = new DOMPoint(aParent, aPoints[i].x, aPoints[i].y); + } +} + +DOMQuad::DOMQuad(nsISupports* aParent) + : mParent(aParent) +{ + SetIsDOMBinding(); +} + +DOMQuad::~DOMQuad() +{ +} + +JSObject* +DOMQuad::WrapObject(JSContext* aCx, JS::Handle aScope) +{ + return DOMQuadBinding::Wrap(aCx, aScope, this); +} + +already_AddRefed +DOMQuad::Constructor(const GlobalObject& aGlobal, + const DOMPointInit& aP1, + const DOMPointInit& aP2, + const DOMPointInit& aP3, + const DOMPointInit& aP4, + ErrorResult& aRV) +{ + nsRefPtr obj = new DOMQuad(aGlobal.GetAsSupports()); + obj->mPoints[0] = DOMPoint::Constructor(aGlobal, aP1, aRV); + obj->mPoints[1] = DOMPoint::Constructor(aGlobal, aP2, aRV); + obj->mPoints[2] = DOMPoint::Constructor(aGlobal, aP3, aRV); + obj->mPoints[3] = DOMPoint::Constructor(aGlobal, aP4, aRV); + return obj.forget(); +} + +already_AddRefed +DOMQuad::Constructor(const GlobalObject& aGlobal, const DOMRectReadOnly& aRect, + ErrorResult& aRV) +{ + CSSPoint points[4]; + Float x = aRect.X(), y = aRect.Y(), w = aRect.Width(), h = aRect.Height(); + points[0] = CSSPoint(x, y); + points[1] = CSSPoint(x + w, y); + points[2] = CSSPoint(x + w, y + h); + points[3] = CSSPoint(x, y + h); + nsRefPtr obj = new DOMQuad(aGlobal.GetAsSupports(), points); + return obj.forget(); +} + +class DOMQuad::QuadBounds MOZ_FINAL : public DOMRectReadOnly +{ +public: + QuadBounds(DOMQuad* aQuad) + : DOMRectReadOnly(aQuad->GetParentObject()) + , mQuad(aQuad) + {} + + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(QuadBounds, DOMRectReadOnly) + NS_DECL_ISUPPORTS_INHERITED + + virtual double X() const + { + double x1, x2; + GetHorizontalMinMax(&x1, &x2); + return x1; + } + virtual double Y() const + { + double y1, y2; + GetVerticalMinMax(&y1, &y2); + return y1; + } + virtual double Width() const + { + double x1, x2; + GetHorizontalMinMax(&x1, &x2); + return x2 - x1; + } + virtual double Height() const + { + double y1, y2; + GetVerticalMinMax(&y1, &y2); + return y2 - y1; + } + + void GetHorizontalMinMax(double* aX1, double* aX2) const + { + double x1, x2; + x1 = x2 = mQuad->Point(0)->X(); + for (uint32_t i = 1; i < 4; ++i) { + double x = mQuad->Point(i)->X(); + x1 = std::min(x1, x); + x2 = std::max(x2, x); + } + *aX1 = x1; + *aX2 = x2; + } + + void GetVerticalMinMax(double* aY1, double* aY2) const + { + double y1, y2; + y1 = y2 = mQuad->Point(0)->Y(); + for (uint32_t i = 1; i < 4; ++i) { + double y = mQuad->Point(i)->Y(); + y1 = std::min(y1, y); + y2 = std::max(y2, y); + } + *aY1 = y1; + *aY2 = y2; + } + +protected: + nsRefPtr mQuad; +}; + +NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DOMQuad::QuadBounds, DOMRectReadOnly, mQuad) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMQuad::QuadBounds) +NS_INTERFACE_MAP_END_INHERITING(DOMRectReadOnly) + +NS_IMPL_ADDREF_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly) +NS_IMPL_RELEASE_INHERITED(DOMQuad::QuadBounds, DOMRectReadOnly) + +DOMRectReadOnly* +DOMQuad::Bounds() const +{ + if (!mBounds) { + mBounds = new QuadBounds(const_cast(this)); + } + return mBounds; +} diff --git a/content/base/src/DOMQuad.h b/content/base/src/DOMQuad.h new file mode 100644 index 000000000000..0806b246f3dd --- /dev/null +++ b/content/base/src/DOMQuad.h @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_DOMQUAD_H_ +#define MOZILLA_DOMQUAD_H_ + +#include "nsWrapperCache.h" +#include "nsISupports.h" +#include "nsCycleCollectionParticipant.h" +#include "mozilla/Attributes.h" +#include "nsCOMPtr.h" +#include "nsAutoPtr.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "mozilla/ErrorResult.h" +#include "Units.h" + +namespace mozilla { +namespace dom { + +class DOMRectReadOnly; +class DOMPoint; +struct DOMPointInit; + +class DOMQuad MOZ_FINAL : public nsWrapperCache +{ +public: + DOMQuad(nsISupports* aParent, CSSPoint aPoints[4]); + DOMQuad(nsISupports* aParent); + ~DOMQuad(); + + NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMQuad) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(DOMQuad) + + nsISupports* GetParentObject() const { return mParent; } + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aScope) MOZ_OVERRIDE; + + static already_AddRefed + Constructor(const GlobalObject& aGlobal, + const DOMPointInit& aP1, + const DOMPointInit& aP2, + const DOMPointInit& aP3, + const DOMPointInit& aP4, + ErrorResult& aRV); + static already_AddRefed + Constructor(const GlobalObject& aGlobal, const DOMRectReadOnly& aRect, + ErrorResult& aRV); + + DOMRectReadOnly* Bounds() const; + DOMPoint* P1() const { return mPoints[0]; } + DOMPoint* P2() const { return mPoints[1]; } + DOMPoint* P3() const { return mPoints[2]; } + DOMPoint* P4() const { return mPoints[3]; } + + DOMPoint* Point(uint32_t aIndex) { return mPoints[aIndex]; } + +protected: + class QuadBounds; + + nsCOMPtr mParent; + nsRefPtr mPoints[4]; + mutable nsRefPtr mBounds; // allocated lazily +}; + +} +} + +#endif /*MOZILLA_DOMRECT_H_*/ diff --git a/content/base/src/moz.build b/content/base/src/moz.build index bda6ff921fc3..82304b5f8ed0 100644 --- a/content/base/src/moz.build +++ b/content/base/src/moz.build @@ -61,6 +61,7 @@ EXPORTS.mozilla.dom += [ 'DOMImplementation.h', 'DOMParser.h', 'DOMPoint.h', + 'DOMQuad.h', 'DOMRect.h', 'DOMStringList.h', 'EventSource.h', @@ -81,6 +82,7 @@ UNIFIED_SOURCES += [ 'DOMImplementation.cpp', 'DOMParser.cpp', 'DOMPoint.cpp', + 'DOMQuad.cpp', 'DOMRect.cpp', 'DOMStringList.cpp', 'Element.cpp', diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 63bd7b9ec2da..e3afdcb20e14 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -342,6 +342,10 @@ DOMInterfaces = { 'headerFile': 'mozilla/dom/DOMRect.h', }, +'DOMQuad': { + 'resultNotAddRefed': [ 'bounds', 'p0', 'p1', 'p2', 'p3' ] +}, + 'DOMSettableTokenList': { 'nativeType': 'nsDOMSettableTokenList', }, diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 0cf08f3cfeb5..c5ce599114c7 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -309,6 +309,8 @@ var interfaceNamesInGlobalScope = "DOMPoint", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMPointReadOnly", +// IMPORTANT: Do not change this list without review from a DOM peer! + "DOMQuad", // IMPORTANT: Do not change this list without review from a DOM peer! "DOMRect", // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/DOMQuad.webidl b/dom/webidl/DOMQuad.webidl new file mode 100644 index 000000000000..b933987d5979 --- /dev/null +++ b/dom/webidl/DOMQuad.webidl @@ -0,0 +1,23 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/fxtf/geometry/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +[Pref="layout.css.DOMQuad.enabled", + Constructor(optional DOMPointInit p1, optional DOMPointInit p2, + optional DOMPointInit p3, optional DOMPointInit p4), + Constructor(DOMRectReadOnly rect)] +interface DOMQuad { + [SameObject] readonly attribute DOMPoint p1; + [SameObject] readonly attribute DOMPoint p2; + [SameObject] readonly attribute DOMPoint p3; + [SameObject] readonly attribute DOMPoint p4; + [SameObject] readonly attribute DOMRectReadOnly bounds; +}; \ No newline at end of file diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 03f9418eee82..a4dfc1a0d299 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -84,6 +84,7 @@ WEBIDL_FILES = [ 'DOMMMIError.webidl', 'DOMParser.webidl', 'DOMPoint.webidl', + 'DOMQuad.webidl', 'DOMRect.webidl', 'DOMRectList.webidl', 'DOMRequest.webidl', diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 587b6c3eb60b..3de8428def61 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1813,6 +1813,9 @@ pref("layout.css.will-change.enabled", false); // Is support for DOMPoint enabled? pref("layout.css.DOMPoint.enabled", true); +// Is support for DOMQuad enabled? +pref("layout.css.DOMQuad.enabled", true); + // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From afa45e3323154f79f86183ffa23a5987b859fc90 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:38 +0800 Subject: [PATCH 049/101] Bug 917755. Part 5: Implement GeometryUtils GetBoxQuads. r=matspal --HG-- extra : rebase_source : 6997773605684ad96e29b22fc10069d31385e63b --- layout/base/GeometryUtils.cpp | 238 ++++++++++++++++++++++++++++++++++ layout/base/GeometryUtils.h | 41 ++++++ layout/base/moz.build | 2 + 3 files changed, 281 insertions(+) create mode 100644 layout/base/GeometryUtils.cpp create mode 100644 layout/base/GeometryUtils.h diff --git a/layout/base/GeometryUtils.cpp b/layout/base/GeometryUtils.cpp new file mode 100644 index 000000000000..8f3b9f70a8ec --- /dev/null +++ b/layout/base/GeometryUtils.cpp @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "GeometryUtils.h" + +#include "mozilla/dom/GeometryUtilsBinding.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/Text.h" +#include "mozilla/dom/DOMQuad.h" +#include "nsIFrame.h" +#include "nsGenericDOMDataNode.h" +#include "nsCSSFrameConstructor.h" +#include "nsLayoutUtils.h" +#include "nsSVGUtils.h" + +using namespace mozilla; +using namespace mozilla::dom; + +namespace mozilla { + +typedef OwningTextOrElementOrDocument GeometryNode; + +enum GeometryNodeType { + GEOMETRY_NODE_ELEMENT, + GEOMETRY_NODE_TEXT, + GEOMETRY_NODE_DOCUMENT +}; + +static nsIFrame* +GetFrameForNode(nsINode* aNode, GeometryNodeType aType) +{ + nsIDocument* doc = aNode->OwnerDoc(); + doc->FlushPendingNotifications(Flush_Layout); + switch (aType) { + case GEOMETRY_NODE_ELEMENT: + return aNode->AsContent()->GetPrimaryFrame(); + case GEOMETRY_NODE_TEXT: { + nsIPresShell* presShell = doc->GetShell(); + if (presShell) { + return presShell->FrameConstructor()->EnsureFrameForTextNode( + static_cast(aNode)); + } + return nullptr; + } + case GEOMETRY_NODE_DOCUMENT: { + nsIPresShell* presShell = doc->GetShell(); + return presShell ? presShell->GetRootFrame() : nullptr; + } + default: + MOZ_ASSERT(false, "Unknown GeometryNodeType"); + return nullptr; + } +} + +static nsIFrame* +GetFrameForGeometryNode(const Optional& aGeometryNode, + nsINode* aDefaultNode) +{ + if (!aGeometryNode.WasPassed()) { + return GetFrameForNode(aDefaultNode->OwnerDoc(), GEOMETRY_NODE_DOCUMENT); + } + + const GeometryNode& value = aGeometryNode.Value(); + if (value.IsElement()) { + return GetFrameForNode(value.GetAsElement(), GEOMETRY_NODE_ELEMENT); + } + if (value.IsDocument()) { + return GetFrameForNode(value.GetAsDocument(), GEOMETRY_NODE_DOCUMENT); + } + return GetFrameForNode(value.GetAsText(), GEOMETRY_NODE_TEXT); +} + +static nsIFrame* +GetFrameForNode(nsINode* aNode) +{ + if (aNode->IsElement()) { + return GetFrameForNode(aNode, GEOMETRY_NODE_ELEMENT); + } + if (aNode == aNode->OwnerDoc()) { + return GetFrameForNode(aNode, GEOMETRY_NODE_DOCUMENT); + } + NS_ASSERTION(aNode->IsNodeOfType(nsINode::eTEXT), "Unknown node type"); + return GetFrameForNode(aNode, GEOMETRY_NODE_TEXT); +} + +static nsIFrame* +GetFirstNonAnonymousFrameForGeometryNode(const Optional& aNode, + nsINode* aDefaultNode) +{ + nsIFrame* f = GetFrameForGeometryNode(aNode, aDefaultNode); + if (f) { + f = nsLayoutUtils::GetFirstNonAnonymousFrame(f); + } + return f; +} + +/** + * This can modify aFrame to point to a different frame. This is needed to + * handle SVG, where SVG elements can only compute a rect that's valid with + * respect to the "outer SVG" frame. + */ +static nsRect +GetBoxRectForFrame(nsIFrame** aFrame, CSSBoxType aType) +{ + nsRect r; + nsIFrame* f = nsSVGUtils::GetOuterSVGFrameAndCoveredRegion(*aFrame, &r); + if (f) { + // For SVG, the BoxType is ignored. + *aFrame = f; + return r; + } + + f = *aFrame; + switch (aType) { + case CSSBoxType::Content: r = f->GetContentRectRelativeToSelf(); break; + case CSSBoxType::Padding: r = f->GetPaddingRectRelativeToSelf(); break; + case CSSBoxType::Border: r = nsRect(nsPoint(0, 0), f->GetSize()); break; + case CSSBoxType::Margin: { + r = nsRect(nsPoint(0, 0), f->GetSize()); + r.Inflate(f->GetUsedMargin()); + break; + } + default: MOZ_ASSERT(false, "unknown box type"); return r; + } + + return r; +} + +class AccumulateQuadCallback : public nsLayoutUtils::BoxCallback { +public: + AccumulateQuadCallback(nsISupports* aParentObject, + nsTArray >& aResult, + nsIFrame* aRelativeToFrame, + const nsPoint& aRelativeToBoxTopLeft, + CSSBoxType aBoxType) + : mParentObject(aParentObject) + , mResult(aResult) + , mRelativeToFrame(aRelativeToFrame) + , mRelativeToBoxTopLeft(aRelativeToBoxTopLeft) + , mBoxType(aBoxType) + { + } + + virtual void AddBox(nsIFrame* aFrame) MOZ_OVERRIDE + { + nsIFrame* f = aFrame; + nsRect box = GetBoxRectForFrame(&f, mBoxType); + nsPoint appUnits[4] = + { box.TopLeft(), box.TopRight(), box.BottomRight(), box.BottomLeft() }; + CSSPoint points[4]; + for (uint32_t i = 0; i < 4; ++i) { + points[i] = CSSPoint(nsPresContext::AppUnitsToFloatCSSPixels(appUnits[i].x), + nsPresContext::AppUnitsToFloatCSSPixels(appUnits[i].y)); + } + nsLayoutUtils::TransformResult rv = + nsLayoutUtils::TransformPoints(f, mRelativeToFrame, 4, points); + if (rv == nsLayoutUtils::TRANSFORM_SUCCEEDED) { + CSSPoint delta(nsPresContext::AppUnitsToFloatCSSPixels(mRelativeToBoxTopLeft.x), + nsPresContext::AppUnitsToFloatCSSPixels(mRelativeToBoxTopLeft.y)); + for (uint32_t i = 0; i < 4; ++i) { + points[i] -= delta; + } + } else { + PodArrayZero(points); + } + mResult.AppendElement(new DOMQuad(mParentObject, points)); + } + + nsISupports* mParentObject; + nsTArray >& mResult; + nsIFrame* mRelativeToFrame; + nsPoint mRelativeToBoxTopLeft; + CSSBoxType mBoxType; +}; + +static nsPresContext* +FindTopLevelPresContext(nsPresContext* aPC) +{ + bool isChrome = aPC->IsChrome(); + nsPresContext* pc = aPC; + for (;;) { + nsPresContext* parent = pc->GetParentPresContext(); + if (!parent || parent->IsChrome() != isChrome) { + return pc; + } + pc = parent; + } +} + +static bool +CheckFramesInSameTopLevelBrowsingContext(nsIFrame* aFrame1, nsIFrame* aFrame2) +{ + nsPresContext* pc1 = aFrame1->PresContext(); + nsPresContext* pc2 = aFrame2->PresContext(); + if (pc1 == pc2) { + return true; + } + if (nsContentUtils::IsCallerChrome()) { + return true; + } + if (FindTopLevelPresContext(pc1) == FindTopLevelPresContext(pc2)) { + return true; + } + return false; +} + +void GetBoxQuads(nsINode* aNode, + const dom::BoxQuadOptions& aOptions, + nsTArray >& aResult, + ErrorResult& aRv) +{ + nsIFrame* frame = GetFrameForNode(aNode); + if (!frame) { + // No boxes to return + return; + } + nsIDocument* ownerDoc = aNode->OwnerDoc(); + nsIFrame* relativeToFrame = + GetFirstNonAnonymousFrameForGeometryNode(aOptions.mRelativeTo, ownerDoc); + if (!relativeToFrame) { + aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR); + return; + } + if (!CheckFramesInSameTopLevelBrowsingContext(frame, relativeToFrame)) { + aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR); + return; + } + // GetBoxRectForFrame can modify relativeToFrame so call it first. + nsPoint relativeToTopLeft = + GetBoxRectForFrame(&relativeToFrame, CSSBoxType::Border).TopLeft(); + AccumulateQuadCallback callback(ownerDoc, aResult, relativeToFrame, + relativeToTopLeft, aOptions.mBox); + nsLayoutUtils::GetAllInFlowBoxes(frame, &callback); +} + +} diff --git a/layout/base/GeometryUtils.h b/layout/base/GeometryUtils.h new file mode 100644 index 000000000000..72592508fcbd --- /dev/null +++ b/layout/base/GeometryUtils.h @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MOZILLA_GEOMETRYUTILS_H_ +#define MOZILLA_GEOMETRYUTILS_H_ + +#include "mozilla/ErrorResult.h" +#include "nsTArray.h" +#include "nsCOMPtr.h" + +/** + * This file defines utility functions for converting between layout + * coordinate systems. + */ + +class nsINode; +class nsIDocument; + +namespace mozilla { + +namespace dom { +struct BoxQuadOptions; +class DOMQuad; +class Element; +class Text; +} + +/** + * Computes quads for aNode using aOptions, according to GeometryUtils.getBoxQuads. + * May set an error in aRv. + */ +void GetBoxQuads(nsINode* aNode, + const dom::BoxQuadOptions& aOptions, + nsTArray >& aResult, + ErrorResult& aRv); + +} + +#endif /* MOZILLA_GEOMETRYUTILS_H_ */ diff --git a/layout/base/moz.build b/layout/base/moz.build index 5102ba082f25..5095f56661a2 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -60,6 +60,7 @@ EXPORTS += [ ] EXPORTS.mozilla += [ + 'GeometryUtils.h', 'PaintTracker.h', ] @@ -69,6 +70,7 @@ UNIFIED_SOURCES += [ 'DisplayListClipState.cpp', 'FrameLayerBuilder.cpp', 'FramePropertyTable.cpp', + 'GeometryUtils.cpp', 'MaskLayerImageCache.cpp', 'nsCaret.cpp', 'nsCounterManager.cpp', From 729128951a04e6ab34cfb3b1495f0beed5a57465 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:38 +0800 Subject: [PATCH 050/101] Bug 917755. Part 5.5: Implement getBoxQuads DOM API. r=jst --HG-- extra : rebase_source : 02febe9fad731185bfbc50454683b485d551bf59 --- content/base/public/nsINode.h | 10 +++++++++ content/base/src/nsINode.cpp | 9 ++++++++ dom/webidl/GeometryUtils.webidl | 38 +++++++++++++++++++++++++++++++++ dom/webidl/moz.build | 1 + modules/libpref/src/init/all.js | 7 ++++++ 5 files changed, 65 insertions(+) create mode 100644 dom/webidl/GeometryUtils.webidl diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 300a95690056..3fe973fd99b5 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -66,6 +66,8 @@ inline bool IsSpaceCharacter(char aChar) { aChar == '\f'; } class Element; +struct BoxQuadOptions; +class DOMQuad; class EventHandlerNonNull; class OnErrorEventHandlerNonNull; template class Optional; @@ -279,6 +281,10 @@ private: class nsINode : public mozilla::dom::EventTarget { public: + typedef mozilla::dom::BoxQuadOptions BoxQuadOptions; + typedef mozilla::dom::DOMQuad DOMQuad; + typedef mozilla::ErrorResult ErrorResult; + NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID) // Among the sub-classes that inherit (directly or indirectly) from nsINode, @@ -1610,6 +1616,10 @@ public: mozilla::dom::Element* GetFirstElementChild() const; mozilla::dom::Element* GetLastElementChild() const; + void GetBoxQuads(const BoxQuadOptions& aOptions, + nsTArray >& aResult, + mozilla::ErrorResult& aRv); + protected: // Override this function to create a custom slots class. diff --git a/content/base/src/nsINode.cpp b/content/base/src/nsINode.cpp index d6b84d3979a2..953912d33043 100644 --- a/content/base/src/nsINode.cpp +++ b/content/base/src/nsINode.cpp @@ -103,6 +103,7 @@ #include #include "nsGlobalWindow.h" #include "nsDOMMutationObserver.h" +#include "GeometryUtils.h" using namespace mozilla; using namespace mozilla::dom; @@ -1140,6 +1141,14 @@ nsINode::PreHandleEvent(EventChainPreVisitor& aVisitor) return NS_ERROR_NOT_IMPLEMENTED; } +void +nsINode::GetBoxQuads(const BoxQuadOptions& aOptions, + nsTArray >& aResult, + mozilla::ErrorResult& aRv) +{ + mozilla::GetBoxQuads(this, aOptions, aResult, aRv); +} + nsresult nsINode::DispatchEvent(nsIDOMEvent *aEvent, bool* aRetVal) { diff --git a/dom/webidl/GeometryUtils.webidl b/dom/webidl/GeometryUtils.webidl new file mode 100644 index 000000000000..d34a614af224 --- /dev/null +++ b/dom/webidl/GeometryUtils.webidl @@ -0,0 +1,38 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/csswg/cssom-view/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +enum CSSBoxType { "margin", "border", "padding", "content" }; +dictionary BoxQuadOptions { + CSSBoxType box = "border"; + GeometryNode relativeTo; +}; + +dictionary ConvertCoordinateOptions { + CSSBoxType fromBox = "border"; + CSSBoxType toBox = "border"; +}; + +[NoInterfaceObject] +interface GeometryUtils { + [Throws, Pref="layout.css.getBoxQuads.enabled"] + sequence getBoxQuads(optional BoxQuadOptions options); +// DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional ConvertCoordinateOptions options); +// DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options); +// DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options); +}; + +Text implements GeometryUtils; +Element implements GeometryUtils; +// PseudoElement implements GeometryUtils; +Document implements GeometryUtils; + +typedef (Text or Element /* or PseudoElement */ or Document) GeometryNode; \ No newline at end of file diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index a4dfc1a0d299..f4934df66f2a 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -115,6 +115,7 @@ WEBIDL_FILES = [ 'Function.webidl', 'GainNode.webidl', 'Geolocation.webidl', + 'GeometryUtils.webidl', 'GetUserMediaRequest.webidl', 'History.webidl', 'HTMLAnchorElement.webidl', diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 3de8428def61..8feab870a89a 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1816,6 +1816,13 @@ pref("layout.css.DOMPoint.enabled", true); // Is support for DOMQuad enabled? pref("layout.css.DOMQuad.enabled", true); +// Is support for GeometryUtils.getBoxQuads enabled? +#ifdef RELEASE_BUILD +pref("layout.css.getBoxQuads.enabled", false); +#else +pref("layout.css.getBoxQuads.enabled", true); +#endif + // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From 905a9306af2676328b76dc55af2a07585c42c010 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:21:42 +1200 Subject: [PATCH 051/101] Bug 917755. Part 6: Add tests for getBoxQuads. r=matspal --HG-- extra : rebase_source : 2e49345a3035cdbe5e4d2ee7573f3c30da38da6a --- layout/base/tests/mochitest.ini | 1 + ...test_getBoxQuads_convertPointRectQuad.html | 525 ++++++++++++++++++ 2 files changed, 526 insertions(+) create mode 100644 layout/base/tests/test_getBoxQuads_convertPointRectQuad.html diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index 3cb3967cf3c6..f8e9af0ad75e 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -458,6 +458,7 @@ skip-if = toolkit == "win" skip-if = toolkit == "win" [test_flush_on_paint.html] skip-if = true || (toolkit == 'android') || (toolkit == "cocoa") # Bug 688128, bug 539356 +[test_getBoxQuads_convertPointRectQuad.html] [test_bug687297.html] skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 948948 support-files = diff --git a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html new file mode 100644 index 000000000000..5c41d6a588a6 --- /dev/null +++ b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html @@ -0,0 +1,525 @@ + + + + + + + + +

+ + +
+
+
+
+ +
+ + + +
+ + + + + + + + +
Cell
Caption
+ +
+
+
+
+ +
+ +
T +TextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextTextText
+ +
+ +
+ + + +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+ + + + +
+
+
+
+
+ + + + From a89f4549c0c52695258af6d7c52a9dc10f520df5 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:38 +0800 Subject: [PATCH 052/101] Bug 918189. Part 1: Implement GeometryUtils ConvertQuad/Rect/PointFromNode. r=mats --HG-- extra : rebase_source : deade5e87ae77b3fe9efdfde9ba2f3254318f387 --- layout/base/GeometryUtils.cpp | 141 ++++++++++++++++++++++++++++++++-- layout/base/GeometryUtils.h | 29 ++++++- 2 files changed, 163 insertions(+), 7 deletions(-) diff --git a/layout/base/GeometryUtils.cpp b/layout/base/GeometryUtils.cpp index 8f3b9f70a8ec..23273852c005 100644 --- a/layout/base/GeometryUtils.cpp +++ b/layout/base/GeometryUtils.cpp @@ -5,10 +5,13 @@ #include "GeometryUtils.h" +#include "mozilla/dom/DOMPointBinding.h" #include "mozilla/dom/GeometryUtilsBinding.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/Text.h" +#include "mozilla/dom/DOMPoint.h" #include "mozilla/dom/DOMQuad.h" +#include "mozilla/dom/DOMRect.h" #include "nsIFrame.h" #include "nsGenericDOMDataNode.h" #include "nsCSSFrameConstructor.h" @@ -20,8 +23,6 @@ using namespace mozilla::dom; namespace mozilla { -typedef OwningTextOrElementOrDocument GeometryNode; - enum GeometryNodeType { GEOMETRY_NODE_ELEMENT, GEOMETRY_NODE_TEXT, @@ -55,14 +56,14 @@ GetFrameForNode(nsINode* aNode, GeometryNodeType aType) } static nsIFrame* -GetFrameForGeometryNode(const Optional& aGeometryNode, +GetFrameForGeometryNode(const Optional& aGeometryNode, nsINode* aDefaultNode) { if (!aGeometryNode.WasPassed()) { return GetFrameForNode(aDefaultNode->OwnerDoc(), GEOMETRY_NODE_DOCUMENT); } - const GeometryNode& value = aGeometryNode.Value(); + const OwningGeometryNode& value = aGeometryNode.Value(); if (value.IsElement()) { return GetFrameForNode(value.GetAsElement(), GEOMETRY_NODE_ELEMENT); } @@ -72,6 +73,18 @@ GetFrameForGeometryNode(const Optional& aGeometryNode, return GetFrameForNode(value.GetAsText(), GEOMETRY_NODE_TEXT); } +static nsIFrame* +GetFrameForGeometryNode(const GeometryNode& aGeometryNode) +{ + if (aGeometryNode.IsElement()) { + return GetFrameForNode(&aGeometryNode.GetAsElement(), GEOMETRY_NODE_ELEMENT); + } + if (aGeometryNode.IsDocument()) { + return GetFrameForNode(&aGeometryNode.GetAsDocument(), GEOMETRY_NODE_DOCUMENT); + } + return GetFrameForNode(&aGeometryNode.GetAsText(), GEOMETRY_NODE_TEXT); +} + static nsIFrame* GetFrameForNode(nsINode* aNode) { @@ -86,7 +99,7 @@ GetFrameForNode(nsINode* aNode) } static nsIFrame* -GetFirstNonAnonymousFrameForGeometryNode(const Optional& aNode, +GetFirstNonAnonymousFrameForGeometryNode(const Optional& aNode, nsINode* aDefaultNode) { nsIFrame* f = GetFrameForGeometryNode(aNode, aDefaultNode); @@ -96,6 +109,26 @@ GetFirstNonAnonymousFrameForGeometryNode(const Optional& aNode, return f; } +static nsIFrame* +GetFirstNonAnonymousFrameForGeometryNode(const GeometryNode& aNode) +{ + nsIFrame* f = GetFrameForGeometryNode(aNode); + if (f) { + f = nsLayoutUtils::GetFirstNonAnonymousFrame(f); + } + return f; +} + +static nsIFrame* +GetFirstNonAnonymousFrameForNode(nsINode* aNode) +{ + nsIFrame* f = GetFrameForNode(aNode); + if (f) { + f = nsLayoutUtils::GetFirstNonAnonymousFrame(f); + } + return f; +} + /** * This can modify aFrame to point to a different frame. This is needed to * handle SVG, where SVG elements can only compute a rect that's valid with @@ -235,4 +268,102 @@ void GetBoxQuads(nsINode* aNode, nsLayoutUtils::GetAllInFlowBoxes(frame, &callback); } +static void +TransformPoints(nsINode* aTo, const GeometryNode& aFrom, + uint32_t aPointCount, CSSPoint* aPoints, + const ConvertCoordinateOptions& aOptions, ErrorResult& aRv) +{ + nsIFrame* fromFrame = GetFirstNonAnonymousFrameForGeometryNode(aFrom); + nsIFrame* toFrame = GetFirstNonAnonymousFrameForNode(aTo); + if (!fromFrame || !toFrame) { + aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR); + return; + } + if (!CheckFramesInSameTopLevelBrowsingContext(fromFrame, toFrame)) { + aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR); + return; + } + + nsPoint fromOffset = GetBoxRectForFrame(&fromFrame, aOptions.mFromBox).TopLeft(); + nsPoint toOffset = GetBoxRectForFrame(&toFrame, aOptions.mToBox).TopLeft(); + CSSPoint fromOffsetGfx(nsPresContext::AppUnitsToFloatCSSPixels(fromOffset.x), + nsPresContext::AppUnitsToFloatCSSPixels(fromOffset.y)); + for (uint32_t i = 0; i < aPointCount; ++i) { + aPoints[i] += fromOffsetGfx; + } + nsLayoutUtils::TransformResult rv = + nsLayoutUtils::TransformPoints(fromFrame, toFrame, aPointCount, aPoints); + if (rv == nsLayoutUtils::TRANSFORM_SUCCEEDED) { + CSSPoint toOffsetGfx(nsPresContext::AppUnitsToFloatCSSPixels(toOffset.x), + nsPresContext::AppUnitsToFloatCSSPixels(toOffset.y)); + for (uint32_t i = 0; i < aPointCount; ++i) { + aPoints[i] -= toOffsetGfx; + } + } else { + PodZero(aPoints, aPointCount); + } +} + +already_AddRefed +ConvertQuadFromNode(nsINode* aTo, dom::DOMQuad& aQuad, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + CSSPoint points[4]; + for (uint32_t i = 0; i < 4; ++i) { + DOMPoint* p = aQuad.Point(i); + if (p->W() != 1.0 || p->Z() != 0.0) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + points[i] = CSSPoint(p->X(), p->Y()); + } + TransformPoints(aTo, aFrom, 4, points, aOptions, aRv); + if (aRv.Failed()) { + return nullptr; + } + nsRefPtr result = new DOMQuad(aTo->GetParentObject().mObject, points); + return result.forget(); +} + +already_AddRefed +ConvertRectFromNode(nsINode* aTo, dom::DOMRectReadOnly& aRect, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + CSSPoint points[4]; + double x = aRect.X(), y = aRect.Y(), w = aRect.Width(), h = aRect.Height(); + points[0] = CSSPoint(x, y); + points[1] = CSSPoint(x + w, y); + points[2] = CSSPoint(x + w, y + h); + points[3] = CSSPoint(x, y + h); + TransformPoints(aTo, aFrom, 4, points, aOptions, aRv); + if (aRv.Failed()) { + return nullptr; + } + nsRefPtr result = new DOMQuad(aTo->GetParentObject().mObject, points); + return result.forget(); +} + +already_AddRefed +ConvertPointFromNode(nsINode* aTo, const dom::DOMPointInit& aPoint, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + if (aPoint.mW != 1.0 || aPoint.mZ != 0.0) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + CSSPoint point(aPoint.mX, aPoint.mY); + TransformPoints(aTo, aFrom, 1, &point, aOptions, aRv); + if (aRv.Failed()) { + return nullptr; + } + nsRefPtr result = new DOMPoint(aTo->GetParentObject().mObject, point.x, point.y); + return result.forget(); +} + } diff --git a/layout/base/GeometryUtils.h b/layout/base/GeometryUtils.h index 72592508fcbd..0f327c03c1aa 100644 --- a/layout/base/GeometryUtils.h +++ b/layout/base/GeometryUtils.h @@ -22,11 +22,18 @@ namespace mozilla { namespace dom { struct BoxQuadOptions; +struct ConvertCoordinateOptions; class DOMQuad; -class Element; -class Text; +class DOMRectReadOnly; +class DOMPoint; +class DOMPointInit; +class OwningTextOrElementOrDocument; +class TextOrElementOrDocument; } +typedef dom::TextOrElementOrDocument GeometryNode; +typedef dom::OwningTextOrElementOrDocument OwningGeometryNode; + /** * Computes quads for aNode using aOptions, according to GeometryUtils.getBoxQuads. * May set an error in aRv. @@ -36,6 +43,24 @@ void GetBoxQuads(nsINode* aNode, nsTArray >& aResult, ErrorResult& aRv); +already_AddRefed +ConvertQuadFromNode(nsINode* aTo, dom::DOMQuad& aQuad, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + +already_AddRefed +ConvertRectFromNode(nsINode* aTo, dom::DOMRectReadOnly& aRect, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + +already_AddRefed +ConvertPointFromNode(nsINode* aTo, const dom::DOMPointInit& aPoint, + const GeometryNode& aFrom, + const dom::ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + } #endif /* MOZILLA_GEOMETRYUTILS_H_ */ From 37aa0c39f67ae8f22d03d1f7ad4e42325353e495 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 12 Mar 2014 09:11:39 +0800 Subject: [PATCH 053/101] Bug 918189. Part 1.5: Implement GeometryUtils.convertPointFromNode, convertRectFromNode, and convertQuadFromNode. r=jst --HG-- extra : rebase_source : 2d01b350d84f220add776341a9cbcda5ace2ef01 --- content/base/public/nsINode.h | 25 ++++++++++++++++- content/base/src/nsINode.cpp | 27 +++++++++++++++++++ dom/webidl/GeometryUtils.webidl | 9 ++++--- editor/libeditor/html/nsHTMLEditRules.cpp | 4 +-- ...test_getBoxQuads_convertPointRectQuad.html | 3 ++- modules/libpref/src/init/all.js | 7 +++++ 6 files changed, 68 insertions(+), 7 deletions(-) diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 3fe973fd99b5..3ff35c84638f 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -65,12 +65,17 @@ inline bool IsSpaceCharacter(char aChar) { return aChar == ' ' || aChar == '\t' || aChar == '\n' || aChar == '\r' || aChar == '\f'; } -class Element; struct BoxQuadOptions; +struct ConvertCoordinateOptions; +class DOMPoint; class DOMQuad; +class DOMRectReadOnly; +class Element; class EventHandlerNonNull; class OnErrorEventHandlerNonNull; template class Optional; +class TextOrElementOrDocument; +struct DOMPointInit; } // namespace dom } // namespace mozilla @@ -282,7 +287,12 @@ class nsINode : public mozilla::dom::EventTarget { public: typedef mozilla::dom::BoxQuadOptions BoxQuadOptions; + typedef mozilla::dom::ConvertCoordinateOptions ConvertCoordinateOptions; + typedef mozilla::dom::DOMPoint DOMPoint; + typedef mozilla::dom::DOMPointInit DOMPointInit; typedef mozilla::dom::DOMQuad DOMQuad; + typedef mozilla::dom::DOMRectReadOnly DOMRectReadOnly; + typedef mozilla::dom::TextOrElementOrDocument TextOrElementOrDocument; typedef mozilla::ErrorResult ErrorResult; NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODE_IID) @@ -1620,6 +1630,19 @@ public: nsTArray >& aResult, mozilla::ErrorResult& aRv); + already_AddRefed ConvertQuadFromNode(DOMQuad& aQuad, + const TextOrElementOrDocument& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + already_AddRefed ConvertRectFromNode(DOMRectReadOnly& aRect, + const TextOrElementOrDocument& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + already_AddRefed ConvertPointFromNode(const DOMPointInit& aPoint, + const TextOrElementOrDocument& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv); + protected: // Override this function to create a custom slots class. diff --git a/content/base/src/nsINode.cpp b/content/base/src/nsINode.cpp index 953912d33043..0a7558328119 100644 --- a/content/base/src/nsINode.cpp +++ b/content/base/src/nsINode.cpp @@ -1149,6 +1149,33 @@ nsINode::GetBoxQuads(const BoxQuadOptions& aOptions, mozilla::GetBoxQuads(this, aOptions, aResult, aRv); } +already_AddRefed +nsINode::ConvertQuadFromNode(DOMQuad& aQuad, + const GeometryNode& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + return mozilla::ConvertQuadFromNode(this, aQuad, aFrom, aOptions, aRv); +} + +already_AddRefed +nsINode::ConvertRectFromNode(DOMRectReadOnly& aRect, + const GeometryNode& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + return mozilla::ConvertRectFromNode(this, aRect, aFrom, aOptions, aRv); +} + +already_AddRefed +nsINode::ConvertPointFromNode(const DOMPointInit& aPoint, + const GeometryNode& aFrom, + const ConvertCoordinateOptions& aOptions, + ErrorResult& aRv) +{ + return mozilla::ConvertPointFromNode(this, aPoint, aFrom, aOptions, aRv); +} + nsresult nsINode::DispatchEvent(nsIDOMEvent *aEvent, bool* aRetVal) { diff --git a/dom/webidl/GeometryUtils.webidl b/dom/webidl/GeometryUtils.webidl index d34a614af224..08023d4dfe2f 100644 --- a/dom/webidl/GeometryUtils.webidl +++ b/dom/webidl/GeometryUtils.webidl @@ -25,9 +25,12 @@ dictionary ConvertCoordinateOptions { interface GeometryUtils { [Throws, Pref="layout.css.getBoxQuads.enabled"] sequence getBoxQuads(optional BoxQuadOptions options); -// DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional ConvertCoordinateOptions options); -// DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options); -// DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options); + [Throws, Pref="layout.css.convertFromNode.enabled"] + DOMQuad convertQuadFromNode(DOMQuad quad, GeometryNode from, optional ConvertCoordinateOptions options); + [Throws, Pref="layout.css.convertFromNode.enabled"] + DOMQuad convertRectFromNode(DOMRectReadOnly rect, GeometryNode from, optional ConvertCoordinateOptions options); + [Throws, Pref="layout.css.convertFromNode.enabled"] + DOMPoint convertPointFromNode(DOMPointInit point, GeometryNode from, optional ConvertCoordinateOptions options); }; Text implements GeometryUtils; diff --git a/editor/libeditor/html/nsHTMLEditRules.cpp b/editor/libeditor/html/nsHTMLEditRules.cpp index 2013780f5dd9..58e86f9b1b0a 100644 --- a/editor/libeditor/html/nsHTMLEditRules.cpp +++ b/editor/libeditor/html/nsHTMLEditRules.cpp @@ -2932,7 +2932,7 @@ nsHTMLEditRules::MoveBlock(nsIDOMNode *aLeftBlock, nsIDOMNode *aRightBlock, int3 nsCOMArray arrayOfNodes; nsCOMPtr isupports; // GetNodesFromPoint is the workhorse that figures out what we wnat to move. - nsresult res = GetNodesFromPoint(DOMPoint(aRightBlock,aRightOffset), + nsresult res = GetNodesFromPoint(::DOMPoint(aRightBlock,aRightOffset), EditAction::makeList, arrayOfNodes, true); NS_ENSURE_SUCCESS(res, res); int32_t listCount = arrayOfNodes.Count(); @@ -6459,7 +6459,7 @@ nsHTMLEditRules::GetHighestInlineParent(nsIDOMNode* aNode) // of nodes from a point that will be operated on. // nsresult -nsHTMLEditRules::GetNodesFromPoint(DOMPoint point, +nsHTMLEditRules::GetNodesFromPoint(::DOMPoint point, EditAction operation, nsCOMArray &arrayOfNodes, bool dontTouchContent) diff --git a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html index 5c41d6a588a6..f35c8a46a5d7 100644 --- a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html +++ b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html @@ -216,7 +216,8 @@ window.scrollTo(0,0); function startTest() { SpecialPowers.pushPrefEnv({"set": [["layout.css.DOMPoint.enabled", true], ["layout.css.DOMQuad.enabled", true], - ["layout.css.getBoxQuads.enabled", true]]}, runTest); + ["layout.css.getBoxQuads.enabled", true], + ["layout.css.convertFromNode.enabled", true]]}, runTest); } function runTest() { diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 8feab870a89a..29973f3898dc 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -1823,6 +1823,13 @@ pref("layout.css.getBoxQuads.enabled", false); pref("layout.css.getBoxQuads.enabled", true); #endif +// Is support for GeometryUtils.getBoxQuads enabled? +#ifdef RELEASE_BUILD +pref("layout.css.convertFromNode.enabled", false); +#else +pref("layout.css.convertFromNode.enabled", true); +#endif + // Is support for CSS "text-align: true X" enabled? pref("layout.css.text-align-true-value.enabled", false); From 70162bd5b3bce7bf0652fedbeb1df500d348143e Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Fri, 20 Sep 2013 22:22:11 +1200 Subject: [PATCH 054/101] Bug 918189. Part 2: Add tests for convertPoint/Rect/QuadFromNode. r=mats --HG-- extra : rebase_source : e50c41da1a3cfc66f37e540b26fb8c9353ab5321 --- layout/base/tests/mochitest.ini | 1 + ...test_getBoxQuads_convertPointRectQuad.html | 240 ++++++++++++++---- 2 files changed, 194 insertions(+), 47 deletions(-) diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index f8e9af0ad75e..69caff9de6fd 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -459,6 +459,7 @@ skip-if = toolkit == "win" [test_flush_on_paint.html] skip-if = true || (toolkit == 'android') || (toolkit == "cocoa") # Bug 688128, bug 539356 [test_getBoxQuads_convertPointRectQuad.html] +skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 948948 [test_bug687297.html] skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 948948 support-files = diff --git a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html index f35c8a46a5d7..0d7e104652d3 100644 --- a/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html +++ b/layout/base/tests/test_getBoxQuads_convertPointRectQuad.html @@ -12,6 +12,13 @@ var f1d; var text; var suppressedText; +var suppressedText2; +var comment; +var fragment; +var openedWindow; +var zeroPoint = new DOMPoint(0,0); +var zeroRect = new DOMRect(0,0,0,0); +var zeroQuad = new DOMQuad(zeroRect); var notInDocument = document.createElement('div'); function isEval(expr, b) { @@ -38,6 +45,105 @@ function makeQuadsExpr(fromStr, options) { return fromStr + ".getBoxQuads({" + getBoxQuadsOptionParts.join(',') + "})"; } +function makePointExpr(fromStr, options, x, y) { + var convertPointOptionParts = []; + if ('box' in options) { + convertPointOptionParts.push("fromBox:'" + options.box + "'"); + } + if ('toBox' in options) { + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); + } + return ('toStr' in options ? options.toStr : "document") + + ".convertPointFromNode(new DOMPoint(" + x + "," + y + ")," + fromStr + ",{" + + convertPointOptionParts.join(",") + "})"; +} + +function checkConvertPoints(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { + var selfQuads = eval(fromStr).getBoxQuads( + {box:options.box == "" ? "border" : options.box, + relativeTo:eval(fromStr)}); + var boxWidth = selfQuads[0].bounds.width; + var boxHeight = selfQuads[0].bounds.height; + + var convertTopLeftPointExpr = makePointExpr(fromStr, options, 0, 0); + var topLeft = eval(convertTopLeftPointExpr); + isApprox(topLeft.x, x1, convertTopLeftPointExpr + ".x", options); + isApprox(topLeft.y, y1, convertTopLeftPointExpr + ".y", options); + + var convertTopRightPointExpr = makePointExpr(fromStr, options, boxWidth, 0); + var topRight = eval(convertTopRightPointExpr); + isApprox(topRight.x, x2, convertTopRightPointExpr + ".x", options); + isApprox(topRight.y, y2, convertTopRightPointExpr + ".y", options); + + var convertBottomRightPointExpr = makePointExpr(fromStr, options, boxWidth, boxHeight); + var bottomRight = eval(convertBottomRightPointExpr); + isApprox(bottomRight.x, x3, convertBottomRightPointExpr + ".x", options); + isApprox(bottomRight.y, y3, convertBottomRightPointExpr + ".y", options); + + var convertBottomLeftPointExpr = makePointExpr(fromStr, options, 0, boxHeight); + var bottomLeft = eval(convertBottomLeftPointExpr); + isApprox(bottomLeft.x, x4, convertBottomLeftPointExpr + ".x", options); + isApprox(bottomLeft.y, y4, convertBottomLeftPointExpr + ".y", options); +} + +function checkConvertRect(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { + var selfQuads = eval(fromStr).getBoxQuads( + {box:options.box == "" ? "border" : options.box, + relativeTo:eval(fromStr)}); + var boxWidth = selfQuads[0].bounds.width; + var boxHeight = selfQuads[0].bounds.height; + + var convertPointOptionParts = []; + if ('box' in options) { + convertPointOptionParts.push("fromBox:'" + options.box + "'"); + } + if ('toBox' in options) { + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); + } + + var convertRectExpr = ('toStr' in options ? options.toStr : "document") + + ".convertRectFromNode(new DOMRect(0,0," + boxWidth + "," + boxHeight + ")," + + fromStr + ",{" + convertPointOptionParts.join(",") + "})"; + var quad = eval(convertRectExpr); + isApprox(quad.p1.x, x1, convertRectExpr + ".p1.x", options); + isApprox(quad.p1.y, y1, convertRectExpr + ".p1.y", options); + isApprox(quad.p2.x, x2, convertRectExpr + ".p2.x", options); + isApprox(quad.p2.y, y2, convertRectExpr + ".p2.y", options); + isApprox(quad.p3.x, x3, convertRectExpr + ".p3.x", options); + isApprox(quad.p3.y, y3, convertRectExpr + ".p3.y", options); + isApprox(quad.p4.x, x4, convertRectExpr + ".p4.x", options); + isApprox(quad.p4.y, y4, convertRectExpr + ".p4.y", options); +} + +function checkConvertQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { + var selfQuads = eval(fromStr).getBoxQuads( + {box:options.box == "" ? "border" : options.box, + relativeTo:eval(fromStr)}); + var boxWidth = selfQuads[0].bounds.width; + var boxHeight = selfQuads[0].bounds.height; + + var convertPointOptionParts = []; + if ('box' in options) { + convertPointOptionParts.push("fromBox:'" + options.box + "'"); + } + if ('toBox' in options) { + convertPointOptionParts.push("toBox:'" + options.toBox + "'"); + } + + var convertQuadExpr = ('toStr' in options ? options.toStr : "document") + + ".convertQuadFromNode(new DOMQuad(new DOMRect(0,0," + boxWidth + "," + boxHeight + "))," + + fromStr + ",{" + convertPointOptionParts.join(",") + "})"; + var quad = eval(convertQuadExpr); + isApprox(quad.p1.x, x1, convertQuadExpr + ".p1.x", options); + isApprox(quad.p1.y, y1, convertQuadExpr + ".p1.y", options); + isApprox(quad.p2.x, x2, convertQuadExpr + ".p2.x", options); + isApprox(quad.p2.y, y2, convertQuadExpr + ".p2.y", options); + isApprox(quad.p3.x, x3, convertQuadExpr + ".p3.x", options); + isApprox(quad.p3.y, y3, convertQuadExpr + ".p3.y", options); + isApprox(quad.p4.x, x4, convertQuadExpr + ".p4.x", options); + isApprox(quad.p4.y, y4, convertQuadExpr + ".p4.y", options); +} + function checkQuadIsRect(fromStr, options, x, y, w, h) { var quadsExpr = makeQuadsExpr(fromStr, options); var quads = eval(quadsExpr); @@ -56,6 +162,10 @@ function checkQuadIsRect(fromStr, options, x, y, w, h) { isApprox(q.bounds.top, y, quadsExpr + " checking quad.bounds.top", options); isApprox(q.bounds.width, w, quadsExpr + " checking quad.bounds.width", options); isApprox(q.bounds.height, h, quadsExpr + " checking quad.bounds.height", options); + + checkConvertPoints(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); + checkConvertRect(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); + checkConvertQuad(fromStr, options, x, y, x + w, y, x + w, y + h, x, y + h); } function checkQuadIsQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { @@ -76,6 +186,33 @@ function checkQuadIsQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4) { isApprox(q.bounds.top, Math.min(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.top", options); isApprox(q.bounds.right, Math.max(x1,x2,x3,x4), quadsExpr + " checking quad.bounds.right", options); isApprox(q.bounds.bottom, Math.max(y1,y2,y3,y4), quadsExpr + " checking quad.bounds.bottom", options); + + checkConvertPoints(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); + checkConvertRect(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); + checkConvertQuad(fromStr, options, x1, y1, x2, y2, x3, y3, x4, y4); +} + +function checkException(expr, name) { + try { + eval(expr); + ok(false, "Exception should have been thrown for " + expr); + } catch (ex) { + is(ex.name, name, "Checking exception type for " + expr); + } +} + +function checkNotFound(fromStr, toStr, x1, y1, x2, y2) { + var convertPointExpr = toStr + ".convertPointFromNode(new DOMPoint(" + x1 + + "," + y1 + ")," + fromStr + ")"; + checkException(convertPointExpr, "NotFoundError"); + + var convertRectExpr = toStr + ".convertRectFromNode(new DOMRect(" + x1 + + "," + y1 + "," + x2 + "," + y2 + ")," + fromStr + ")"; + checkException(convertRectExpr, "NotFoundError"); + + var convertQuadExpr = toStr + ".convertQuadFromNode(new DOMQuad(new DOMRect(" + x1 + + "," + y1 + "," + x2 + "," + y2 + "))," + fromStr + ")"; + checkException(convertQuadExpr, "NotFoundError"); }