| Index: src/core/SkScan_AntiPath.cpp
|
| diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp
|
| index e5c67a958af2ef2069ff7ec1fff2a75e402a3e39..0943646ce846c0d1d3f91a12fc320039caa28223 100644
|
| --- a/src/core/SkScan_AntiPath.cpp
|
| +++ b/src/core/SkScan_AntiPath.cpp
|
| @@ -108,7 +108,7 @@ public:
|
|
|
| virtual ~SuperBlitter() {
|
| this->flush();
|
| - sk_free(fRuns.fRuns);
|
| + sk_free(fRunsBuffer);
|
| }
|
|
|
| /// Once fRuns contains a complete supersampled row, flush() blits
|
| @@ -123,31 +123,56 @@ public:
|
| virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE;
|
|
|
| private:
|
| + // The next three variables are used to track a circular buffer that
|
| + // contains the values used in SkAlphaRuns. These variables should only
|
| + // ever be updated in advanceRuns(), and fRuns should always point to
|
| + // a valid SkAlphaRuns...
|
| + int fRunsToBuffer;
|
| + void* fRunsBuffer;
|
| + int fCurrentRun;
|
| SkAlphaRuns fRuns;
|
| +
|
| + // extra one to store the zero at the end
|
| + int getRunsSz() const { return (fWidth + 1 + (fWidth + 2)/2) * sizeof(int16_t); }
|
| +
|
| + // This function updates the fRuns variable to point to the next buffer space
|
| + // with adequate storage for a SkAlphaRuns. It mostly just advances fCurrentRun
|
| + // and resets fRuns to point to an empty scanline.
|
| + void advanceRuns() {
|
| + const size_t kRunsSz = this->getRunsSz();
|
| + fCurrentRun = (fCurrentRun + 1) % fRunsToBuffer;
|
| + fRuns.fRuns = reinterpret_cast<int16_t*>(
|
| + reinterpret_cast<uint8_t*>(fRunsBuffer) + fCurrentRun * kRunsSz);
|
| + fRuns.fAlpha = reinterpret_cast<SkAlpha*>(fRuns.fRuns + fWidth + 1);
|
| + fRuns.reset(fWidth);
|
| + }
|
| +
|
| int fOffsetX;
|
| };
|
|
|
| SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
|
| const SkRegion& clip)
|
| : BaseSuperBlitter(realBlitter, ir, clip) {
|
| - const int width = fWidth;
|
| + fRunsToBuffer = realBlitter->requestRowsPreserved();
|
| + fRunsBuffer = sk_malloc_throw(fRunsToBuffer * this->getRunsSz());
|
| + fCurrentRun = -1;
|
|
|
| - // extra one to store the zero at the end
|
| - fRuns.fRuns = (int16_t*)sk_malloc_throw((width + 1 + (width + 2)/2) * sizeof(int16_t));
|
| - fRuns.fAlpha = (uint8_t*)(fRuns.fRuns + width + 1);
|
| - fRuns.reset(width);
|
| + this->advanceRuns();
|
|
|
| fOffsetX = 0;
|
| }
|
|
|
| void SuperBlitter::flush() {
|
| if (fCurrIY >= fTop) {
|
| +
|
| + SkASSERT(fCurrentRun < fRunsToBuffer);
|
| if (!fRuns.empty()) {
|
| - // SkDEBUGCODE(fRuns.dump();)
|
| + // SkDEBUGCODE(fRuns.dump();)
|
| fRealBlitter->blitAntiH(fLeft, fCurrIY, fRuns.fAlpha, fRuns.fRuns);
|
| - fRuns.reset(fWidth);
|
| + this->advanceRuns();
|
| fOffsetX = 0;
|
| }
|
| +
|
| fCurrIY = fTop - 1;
|
| SkDEBUGCODE(fCurrX = -1;)
|
| }
|
|
|