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
This commit is contained in:
parent
2bec26a716
commit
a62038c478
@ -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();
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user