aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkBlitter_Sprite.cpp
diff options
context:
space:
mode:
authorGravatar herb <herb@google.com>2016-05-26 10:56:17 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-05-26 10:56:18 -0700
commita62038c478be1d668b3a1cea6b6974ddb5d90281 (patch)
tree62569fe14a73cd232107db30de640746e851b086 /src/core/SkBlitter_Sprite.cpp
parent2bec26a71698105729c6a7cb0163f499b4361840 (diff)
Srcover for sprite blitters.
In order for this code to run, the gDefaultProfileIsSRGB flag needs to be true. min base min exp percent name 5601856 4689911 0.837207 top25desk_espn.skp_1 3491515 3202806 0.917311 top25desk_facebook.skp_1 5110247 4865740 0.952154 top25desk_weather_com.skp_1 605445 585520 0.96709 top25desk_techcrunch_com.skp_1 1007151 986193 0.979191 top25desk_wikipedia__1_tab_.skp_1 5951286 5889979 0.989699 top25desk_sports_yahoo_com_.skp_1 2825583 2804853 0.992663 top25desk_plus_google_com_11003.skp_1 8839265 8823249 0.998188 top25desk_twitter.skp_1 4169125 4168882 0.999942 top25desk_docs___1_open_documen.skp_1 6615327 6620663 1.00081 top25desk_youtube_com.skp_1 4613903 4647583 1.0073 top25desk_wordpress.skp_1 2532280 2554154 1.00864 top25desk_ebay_com.skp_1 4015689 4063584 1.01193 top25desk_google_com__hl_en_q_b.skp_1 9427478 9579203 1.01609 top25desk_answers_yahoo_com.skp_1 7403901 7542770 1.01876 top25desk_booking_com.skp_1 12249953 12528353 1.02273 top25desk_google_com_search_q_c.skp_1 1078648 1111050 1.03004 top25desk_games_yahoo_com.skp_1 7232627 7481555 1.03442 top25desk_pinterest.skp_1 2996819 3112091 1.03846 top25desk_google_com_calendar_.skp_1 2181531 2271677 1.04132 top25desk_amazon_com.skp_1 925245 987545 1.06733 top25desk_blogger.skp_1 4143359 4442607 1.07222 top25desk_linkedin.skp_1 4370962 4744580 1.08548 top25desk_news_yahoo_com.skp_1 4284025 4735094 1.10529 top25desk_mail_google_com_mail_.skp_1 [mtklein] We measured the noise here to be [-5%, +8%], so most of these changes fall within the noise. We manually confirmed the two above that noise window (yahoo and mail) are also noise... srcover_srgb_srgb() did not figure prominently in their profiles. The espn and facebook improvements look real. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1996683003 Review-Url: https://codereview.chromium.org/1996683003
Diffstat (limited to 'src/core/SkBlitter_Sprite.cpp')
-rw-r--r--src/core/SkBlitter_Sprite.cpp69
1 files changed, 51 insertions, 18 deletions
diff --git a/src/core/SkBlitter_Sprite.cpp b/src/core/SkBlitter_Sprite.cpp
index c0b7430d22..2ddc5f4855 100644
--- a/src/core/SkBlitter_Sprite.cpp
+++ b/src/core/SkBlitter_Sprite.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
+#include "SkOpts.h"
#include "SkSmallAllocator.h"
#include "SkSpriteBlitter.h"
@@ -43,7 +44,7 @@ void SkSpriteBlitter::blitMask(const SkMask&, const SkIRect& clip) {
// 2. paint has no modifiers (i.e. alpha, colorfilter, etc.)
// 3. xfermode needs no blending: e.g. kSrc_Mode or kSrcOver_Mode + opaque src
//
-class SkSpriteBlitter_memcpy : public SkSpriteBlitter {
+class SkSpriteBlitter_Src_SrcOver : public SkSpriteBlitter {
public:
static bool Supports(const SkPixmap& dst, const SkPixmap& src, const SkPaint& paint) {
if (dst.colorType() != src.colorType()) {
@@ -68,14 +69,32 @@ public:
if (SkXfermode::kSrcOver_Mode == mode && src.isOpaque()) {
return true;
}
- return false;
+
+ // At this point memcpy can't be used. The following check for using SrcOver.
+
+ if (dst.colorType() != kN32_SkColorType
+ || dst.info().profileType() != kSRGB_SkColorProfileType) {
+ return false;
+ }
+
+ return SkXfermode::kSrcOver_Mode == mode;
}
- SkSpriteBlitter_memcpy(const SkPixmap& src) : INHERITED(src) {}
+ SkSpriteBlitter_Src_SrcOver(const SkPixmap& src) : INHERITED(src) {}
void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override {
SkASSERT(Supports(dst, fSource, paint));
this->INHERITED::setup(dst, left, top, paint);
+ SkXfermode::Mode mode;
+ if (!SkXfermode::AsMode(paint.getXfermode(), &mode)) {
+ SkFAIL("Should never happen.");
+ }
+
+ SkASSERT(mode == SkXfermode::kSrcOver_Mode || mode == SkXfermode::kSrc_Mode);
+
+ if (mode == SkXfermode::kSrcOver_Mode && !fSource.isOpaque()) {
+ fUseMemcpy = false;
+ }
}
void blitRect(int x, int y, int width, int height) override {
@@ -83,22 +102,37 @@ public:
SkASSERT(fDst.info().profileType() == fSource.info().profileType());
SkASSERT(width > 0 && height > 0);
- char* dst = (char*)fDst.writable_addr(x, y);
- const char* src = (const char*)fSource.addr(x - fLeft, y - fTop);
- const size_t dstRB = fDst.rowBytes();
- const size_t srcRB = fSource.rowBytes();
- const size_t bytesToCopy = width << fSource.shiftPerPixel();
-
- while (--height >= 0) {
- memcpy(dst, src, bytesToCopy);
- dst += dstRB;
- src += srcRB;
+ if (fUseMemcpy) {
+ char* dst = (char*)fDst.writable_addr(x, y);
+ const char* src = (const char*)fSource.addr(x - fLeft, y - fTop);
+ const size_t dstRB = fDst.rowBytes();
+ const size_t srcRB = fSource.rowBytes();
+ const size_t bytesToCopy = width << fSource.shiftPerPixel();
+
+ while (height --> 0) {
+ memcpy(dst, src, bytesToCopy);
+ dst += dstRB;
+ src += srcRB;
+ }
+ } else {
+ uint32_t* dst = fDst.writable_addr32(x, y);
+ const uint32_t* src = fSource.addr32(x - fLeft, y - fTop);
+ const int dstStride = fDst.rowBytesAsPixels();
+ const int srcStride = fSource.rowBytesAsPixels();
+
+ while (height --> 0) {
+ SkOpts::srcover_srgb_srgb(dst, src, width, width);
+ dst += dstStride;
+ src += srcStride;
+ }
}
}
+private:
typedef SkSpriteBlitter INHERITED;
-};
+ bool fUseMemcpy {true};
+};
// returning null means the caller will call SkBlitter::Choose() and
// have wrapped the source bitmap inside a shader
@@ -115,10 +149,10 @@ SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint,
*/
SkASSERT(allocator != nullptr);
- SkSpriteBlitter* blitter;
+ SkSpriteBlitter* blitter = nullptr;
- if (SkSpriteBlitter_memcpy::Supports(dst, source, paint)) {
- blitter = allocator->createT<SkSpriteBlitter_memcpy>(source);
+ if (SkSpriteBlitter_Src_SrcOver::Supports(dst, source, paint)) {
+ blitter = allocator->createT<SkSpriteBlitter_Src_SrcOver>(source);
} else {
switch (dst.colorType()) {
case kRGB_565_SkColorType:
@@ -135,7 +169,6 @@ SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint,
blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator);
break;
default:
- blitter = nullptr;
break;
}
}