From 983a5d3860c059411a64454370665a11c2c3cbe3 Mon Sep 17 00:00:00 2001 From: "yuzhuohuang@qq.com" Date: Tue, 29 Nov 2011 08:30:42 +0800 Subject: [PATCH] Refactoring in order to cache more operation. --- src/subtitles/Rasterizer.cpp | 110 ++++++++++++++++++++++++++++--------------- src/subtitles/Rasterizer.h | 5 ++ 2 files changed, 77 insertions(+), 38 deletions(-) diff --git a/src/subtitles/Rasterizer.cpp b/src/subtitles/Rasterizer.cpp index ee0a4c6..9b6cc0d 100644 --- a/src/subtitles/Rasterizer.cpp +++ b/src/subtitles/Rasterizer.cpp @@ -974,10 +974,78 @@ static const __int64 _00ff00ff00ff00ff = 0x00ff00ff00ff00ffi64; // switchpts[i*2] contains a colour and switchpts[i*2+1] contains the coordinate to use that colour from // fBody tells whether to render the body of the subs. // fBorder tells whether to render the border of the subs. +SharedPtrByte Rasterizer::CompositeAlphaMask(SubPicDesc& spd, SharedPtrOverlay overlay, const CRect& clipRect, byte* pAlphaMask, + int xsub, int ysub, const DWORD* switchpts, bool fBody, bool fBorder, + CRect *outputDirtyRect) +{ + //fix me: check and log error + SharedPtrByte result; + *outputDirtyRect = CRect(0, 0, 0, 0); + if(!switchpts || !fBody && !fBorder) return(result); + + // clip + // Limit drawn area to intersection of rendering surface and rectangular clip area + CRect r(0, 0, spd.w, spd.h); + r &= clipRect; + // Remember that all subtitle coordinates are specified in 1/8 pixels + // (x+4)>>3 rounds to nearest whole pixel. + // ??? What is xsub, ysub, mOffsetX and mOffsetY ? + int x = (xsub + overlay->mOffsetX + 4)>>3; + int y = (ysub + overlay->mOffsetY + 4)>>3; + int w = overlay->mOverlayWidth; + int h = overlay->mOverlayHeight; + int xo = 0, yo = 0; + // Again, limiting? + if(x < r.left) {xo = r.left-x; w -= r.left-x; x = r.left;} + if(y < r.top) {yo = r.top-y; h -= r.top-y; y = r.top;} + if(x+w > r.right) w = r.right-x; + if(y+h > r.bottom) h = r.bottom-y; + // Check if there's actually anything to render + if(w <= 0 || h <= 0) return(result); + outputDirtyRect->SetRect(x, y, x+w, y+h); + *outputDirtyRect &= CRect(0, 0, spd.w, spd.h); + + bool fSingleColor = (switchpts[1]==0xffffffff); + + // draw + // Grab the first colour + DWORD color = switchpts[0]; + byte* s_base = (byte*)xy_malloc(overlay->mOverlayPitch * overlay->mOverlayHeight); + + if(fSingleColor) + { + overlay->FillAlphaMash(s_base, fBody, fBorder, xo, yo, w, h, + pAlphaMask==NULL ? NULL : pAlphaMask + spd.w * y + x, spd.w, + color>>24 ); + } + else + { + int last_x = xo; + const DWORD *sw = switchpts; + while( last_x>24; + while( sw[3]>24)==alpha ) + { + sw += 2; + } + int new_x = sw[3] < w+xo ? sw[3] : w+xo; + overlay->FillAlphaMash(s_base, fBody, fBorder, + last_x, yo, new_x-last_x, h, + pAlphaMask==NULL ? NULL : pAlphaMask + spd.w * y + x + last_x - xo, spd.w, + alpha ); + last_x = new_x; + sw += 2; + } + } + result.reset( s_base, xy_free ); + return result; +} + CRect Rasterizer::Draw(SubPicDesc& spd, SharedPtrOverlay overlay, const CRect& clipRect, byte* pAlphaMask, int xsub, int ysub, const DWORD* switchpts, bool fBody, bool fBorder) { - CRect bbox(0, 0, 0, 0); + CRect bbox(0,0,0,0); if(!switchpts || !fBody && !fBorder) return(bbox); // clip @@ -1000,8 +1068,6 @@ CRect Rasterizer::Draw(SubPicDesc& spd, SharedPtrOverlay overlay, const CRect& c if(y+h > r.bottom) h = r.bottom-y; // Check if there's actually anything to render if(w <= 0 || h <= 0) return(bbox); - bbox.SetRect(x, y, x+w, y+h); - bbox &= CRect(0, 0, spd.w, spd.h); struct DM { @@ -1019,12 +1085,8 @@ CRect Rasterizer::Draw(SubPicDesc& spd, SharedPtrOverlay overlay, const CRect& c bool fSingleColor = (switchpts[1]==0xffffffff); bool fYV12 = (spd.type==MSP_AY11); int draw_method = 0; - // if(pAlphaMask) - // draw_method |= DM::ALPHA_MASK; if(fSingleColor) draw_method |= DM::SINGLE_COLOR; - // if(fBody) - // draw_method |= DM::BODY; if(fSSE2) draw_method |= DM::SSE2; if(fYV12) @@ -1033,36 +1095,9 @@ CRect Rasterizer::Draw(SubPicDesc& spd, SharedPtrOverlay overlay, const CRect& c // draw // Grab the first colour DWORD color = switchpts[0]; - byte* s_base = (byte*)xy_malloc(overlay->mOverlayPitch * overlay->mOverlayHeight); - - if(fSingleColor) - { - overlay->FillAlphaMash(s_base, fBody, fBorder, xo, yo, w, h, - pAlphaMask==NULL ? NULL : pAlphaMask + spd.w * y + x, spd.w, - color>>24 ); - } - else - { - int last_x = xo; - const DWORD *sw = switchpts; - while( last_x>24; - while( sw[3]>24)==alpha ) - { - sw += 2; - } - int new_x = sw[3] < w+xo ? sw[3] : w+xo; - overlay->FillAlphaMash(s_base, fBody, fBorder, - last_x, yo, new_x-last_x, h, - pAlphaMask==NULL ? NULL : pAlphaMask + spd.w * y + x + last_x - xo, spd.w, - alpha ); - last_x = new_x; - sw += 2; - } - } - - const byte* s = s_base + overlay->mOverlayPitch*yo + xo; + SharedPtrByte s_base = CompositeAlphaMask(spd, overlay, clipRect, pAlphaMask, xsub, ysub, switchpts, + fBody, fBorder, &bbox); + const byte* s = s_base.get() + overlay->mOverlayPitch*yo + xo; // How would this differ from src? unsigned long* dst = (unsigned long *)(((char *)spd.bits + spd.pitch * y) + ((x*spd.bpp)>>3)); @@ -1237,7 +1272,6 @@ CRect Rasterizer::Draw(SubPicDesc& spd, SharedPtrOverlay overlay, const CRect& c // Remember to EMMS! // Rendering fails in funny ways if we don't do this. _mm_empty(); - xy_free(s_base); return bbox; } diff --git a/src/subtitles/Rasterizer.h b/src/subtitles/Rasterizer.h index c47aa6b..1f63fde 100644 --- a/src/subtitles/Rasterizer.h +++ b/src/subtitles/Rasterizer.h @@ -112,6 +112,8 @@ public: typedef ::boost::shared_ptr SharedPtrConstScanLineData; typedef ::boost::shared_ptr SharedPtrScanLineData; +typedef ::boost::shared_ptr SharedPtrByte; + struct Overlay { public: @@ -187,6 +189,9 @@ public: int xsub, int ysub, const DWORD* switchpts, bool fBody, bool fBorder); + static SharedPtrByte CompositeAlphaMask(SubPicDesc& spd, SharedPtrOverlay overlay, const CRect& clipRect, byte* pAlphaMask, + int xsub, int ysub, const DWORD* switchpts, bool fBody, bool fBorder, + CRect *outputDirtyRect); static CRect Draw(SubPicDesc& spd, DrawItem& draw_item); static CRect DryDraw(SubPicDesc& spd, DrawItem& draw_item); -- 2.11.4.GIT