diff --git a/dm/DM.cpp b/dm/DM.cpp index 2f1cd0bdee..057b7e1926 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -623,7 +623,6 @@ static Sink* create_sink(const SkCommandLineConfig* config) { static Sink* create_via(const SkString& tag, Sink* wrapped) { #define VIA(t, via, ...) if (tag.equals(t)) { return new via(__VA_ARGS__); } VIA("twice", ViaTwice, wrapped); - VIA("pipe", ViaPipe, wrapped); VIA("serialize", ViaSerialization, wrapped); VIA("2ndpic", ViaSecondPicture, wrapped); VIA("sp", ViaSingletonPictures, wrapped); diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 82962ff692..aca86968c9 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -6,7 +6,6 @@ */ #include "DMSrcSink.h" -#include "SamplePipeControllers.h" #include "SkAndroidCodec.h" #include "SkCodec.h" #include "SkCommonFlags.h" @@ -1060,16 +1059,6 @@ Error ViaUpright::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkSt /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -Error ViaPipe::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const { - auto size = src.size(); - return draw_to_canvas(fSink, bitmap, stream, log, size, [&](SkCanvas* canvas) { - PipeController controller(canvas, &SkImageDecoder::DecodeMemory); - SkGPipeWriter pipe; - const uint32_t kFlags = 0; - return src.draw(pipe.startRecording(&controller, kFlags, size.width(), size.height())); - }); -} - Error ViaRemote::draw(const Src& src, SkBitmap* bitmap, SkWStream* stream, SkString* log) const { return draw_to_canvas(fSink, bitmap, stream, log, src.size(), [&](SkCanvas* target) { SkAutoTDelete decoder(SkRemote::NewDecoder(target)); diff --git a/dm/DMSrcSink.h b/dm/DMSrcSink.h index 5e053b1155..4251808d6d 100644 --- a/dm/DMSrcSink.h +++ b/dm/DMSrcSink.h @@ -15,7 +15,6 @@ #include "SkBitmapRegionDecoder.h" #include "SkCanvas.h" #include "SkData.h" -#include "SkGPipe.h" #include "SkPicture.h" #include "gm.h" @@ -316,12 +315,6 @@ private: const SkMatrix fMatrix; }; -class ViaPipe : public Via { -public: - explicit ViaPipe(Sink* sink) : Via(sink) {} - Error draw(const Src&, SkBitmap*, SkWStream*, SkString*) const override; -}; - class ViaRemote : public Via { public: ViaRemote(bool cache, Sink* sink) : Via(sink), fCache(cache) {} diff --git a/gyp/FileReaderApp.gyp b/gyp/FileReaderApp.gyp index f0d0bbbe46..36c9eae462 100644 --- a/gyp/FileReaderApp.gyp +++ b/gyp/FileReaderApp.gyp @@ -10,13 +10,11 @@ 'mac_bundle' : 1, 'include_dirs' : [ - '../include/pipe', '../experimental/FileReaderApp', '../experimental/SimpleCocoaApp', ], 'sources': [ '../experimental/FileReaderApp/ReaderView.cpp', - '../src/pipe/SkGPipeRead.cpp', ], 'sources!': [ '../src/utils/mac/SkOSWindow_Mac.cpp', diff --git a/gyp/SampleApp.gyp b/gyp/SampleApp.gyp index 3b4ae851ba..7409b76f20 100644 --- a/gyp/SampleApp.gyp +++ b/gyp/SampleApp.gyp @@ -17,7 +17,6 @@ '../src/lazy', '../gm', # needed to pull gm.h '../samplecode', # To pull SampleApp.h and SampleCode.h - '../src/pipe/utils', # For TiledPipeController '../src/utils/debugger', '../tools', '../experimental', @@ -135,10 +134,6 @@ '../experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp', '../experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.h', - # TiledPipeController - '../src/pipe/utils/SamplePipeControllers.h', - '../src/pipe/utils/SamplePipeControllers.cpp', - # Lua '../src/utils/SkLuaCanvas.cpp', '../src/utils/SkLua.cpp', diff --git a/gyp/core.gyp b/gyp/core.gyp index 2569a9478f..13b8217fb1 100644 --- a/gyp/core.gyp +++ b/gyp/core.gyp @@ -21,7 +21,6 @@ '../include/config', '../include/core', '../include/pathops', - '../include/pipe', '../include/ports', '../include/private', '../include/utils', @@ -108,7 +107,6 @@ '../include/config', '../include/core', '../include/pathops', - '../include/pipe', ], 'conditions': [ [ 'skia_os == "mac"', { diff --git a/gyp/core.gypi b/gyp/core.gypi index a4e64e3fa7..e86e82197c 100644 --- a/gyp/core.gypi +++ b/gyp/core.gypi @@ -312,9 +312,6 @@ # '<(skia_src_path)/image/SkSurface_Gpu.cpp', '<(skia_src_path)/image/SkSurface_Raster.cpp', - '<(skia_src_path)/pipe/SkGPipeRead.cpp', - '<(skia_src_path)/pipe/SkGPipeWrite.cpp', - '<(skia_include_path)/core/SkBBHFactory.h', '<(skia_include_path)/core/SkBitmap.h', '<(skia_include_path)/core/SkBitmapDevice.h', diff --git a/gyp/dm.gypi b/gyp/dm.gypi index 96bd385037..8ad3e68773 100644 --- a/gyp/dm.gypi +++ b/gyp/dm.gypi @@ -12,7 +12,6 @@ '../src/effects', '../src/images', '../src/lazy', - '../src/pipe/utils/', '../src/utils', '../src/utils/debugger', '../tests', @@ -42,7 +41,6 @@ '../dm/DMJsonWriter.cpp', '../gm/gm.cpp', - '../src/pipe/utils/SamplePipeControllers.cpp', '../src/utils/debugger/SkDebugCanvas.cpp', '../src/utils/debugger/SkDrawCommand.cpp', '../src/utils/debugger/SkObjectParser.cpp', diff --git a/gyp/pathops_skpclip.gyp b/gyp/pathops_skpclip.gyp index 3bc5bf6c06..354caf39aa 100755 --- a/gyp/pathops_skpclip.gyp +++ b/gyp/pathops_skpclip.gyp @@ -17,7 +17,6 @@ '../src/effects', '../src/lazy', '../src/pathops', - '../src/pipe/utils', '../src/utils', ], 'dependencies': [ diff --git a/gyp/tests.gypi b/gyp/tests.gypi index 1fd87addf9..10bfdb4413 100644 --- a/gyp/tests.gypi +++ b/gyp/tests.gypi @@ -15,7 +15,6 @@ '../src/pathops', '../src/pdf', '../src/ports', - '../src/pipe/utils', '../src/utils', '../src/utils/debugger', ], @@ -58,7 +57,6 @@ '../src/utils/debugger/SkDebugCanvas.cpp', '../src/utils/debugger/SkObjectParser.h', '../src/utils/debugger/SkObjectParser.cpp', - '../src/pipe/utils/SamplePipeControllers.cpp', ], 'sources!': [ '../tests/SkpSkGrTest.cpp', diff --git a/gyp/tools.gyp b/gyp/tools.gyp index 1e7eabbecf..b585e16541 100644 --- a/gyp/tools.gyp +++ b/gyp/tools.gyp @@ -431,7 +431,6 @@ '<(skia_include_path)/gpu', '<(skia_include_path)/images', '<(skia_include_path)/pathops', - '<(skia_include_path)/pipe', '<(skia_include_path)/ports', '<(skia_include_path)/svg/parser', '<(skia_include_path)/utils', diff --git a/gyp/utils.gyp b/gyp/utils.gyp index eb225e62a2..2384307045 100644 --- a/gyp/utils.gyp +++ b/gyp/utils.gyp @@ -22,7 +22,6 @@ '../include/gpu', '../include/images', '../include/pathops', - '../include/pipe', '../include/private', '../include/utils', '../include/utils/mac', diff --git a/include/pipe/SkGPipe.h b/include/pipe/SkGPipe.h deleted file mode 100644 index 9446b8159f..0000000000 --- a/include/pipe/SkGPipe.h +++ /dev/null @@ -1,174 +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 SkGPipe_DEFINED -#define SkGPipe_DEFINED - -#include "SkFlattenable.h" -#include "SkPicture.h" -#include "SkWriter32.h" - -class SkCanvas; - -// XLib.h might have defined Status already (ugh) -#ifdef Status - #undef Status -#endif - -class SkGPipeReader { -public: - SkGPipeReader(); - SkGPipeReader(SkCanvas* target); - ~SkGPipeReader(); - - enum Status { - kDone_Status, //!< no more data expected from reader - kEOF_Status, //!< need more data from reader - kError_Status, //!< encountered error - kReadAtom_Status//!< finished reading an atom - }; - - enum PlaybackFlags { - kReadAtom_PlaybackFlag = 0x1, //!< playback a single command from the stream - kSilent_PlaybackFlag = 0x2, //!< playback without drawing - }; - - void setCanvas(SkCanvas*); - - /** - * Set a function for decoding bitmaps that have encoded data. - */ - void setBitmapDecoder(SkPicture::InstallPixelRefProc proc) { fProc = proc; } - - // data must be 4-byte aligned - // length must be a multiple of 4 - Status playback(const void* data, size_t length, uint32_t playbackFlags = 0, - size_t* bytesRead = NULL); -private: - SkCanvas* fCanvas; - class SkGPipeState* fState; - SkPicture::InstallPixelRefProc fProc; -}; - -/////////////////////////////////////////////////////////////////////////////// - -class SkGPipeCanvas; - -class SkGPipeController { -public: - SkGPipeController() : fCanvas(NULL) {} - virtual ~SkGPipeController(); - - /** - * Called periodically by the writer, to get a working buffer of RAM to - * write into. The actual size of the block is also returned, and must be - * actual >= minRequest. If NULL is returned, then actual is ignored and - * writing will stop. - * - * The returned block must be 4-byte aligned, and actual must be a - * multiple of 4. - * minRequest will always be a multiple of 4. - */ - virtual void* requestBlock(size_t minRequest, size_t* actual) = 0; - - /** - * This is called each time some atomic portion of the data has been - * written to the block (most recently returned by requestBlock()). - * If bytes == 0, then the writer has finished. - * - * bytes will always be a multiple of 4. - */ - virtual void notifyWritten(size_t bytes) = 0; - virtual int numberOfReaders() const { return 1; } - - /** - * Release resource references that are held in internal caches. - * This must only be called after the pipe has been completely flushed. - */ - void purgeCaches(); - -private: - friend class SkGPipeWriter; - void setCanvas(SkGPipeCanvas*); - - SkGPipeCanvas* fCanvas; -}; - -class SkGPipeWriter { -public: - SkGPipeWriter(); - ~SkGPipeWriter(); - - bool isRecording() const { return SkToBool(fCanvas); } - - enum Flags { - /** - * Tells the writer that the reader will be in a different process, so - * (for example) we cannot put function pointers in the stream. - */ - kCrossProcess_Flag = 1 << 0, - - /** - * Only meaningful if kCrossProcess_Flag is set. Tells the writer that - * in spite of being cross process, it will have shared address space - * with the reader, so the two can share large objects (like SkBitmaps). - */ - kSharedAddressSpace_Flag = 1 << 1, - - /** - * Tells the writer that there will be multiple threads reading the stream - * simultaneously. - */ - kSimultaneousReaders_Flag = 1 << 2, - }; - - SkCanvas* startRecording(SkGPipeController*, uint32_t flags = 0, - uint32_t width = kDefaultRecordingCanvasSize, - uint32_t height = kDefaultRecordingCanvasSize); - - // called in destructor, but can be called sooner once you know there - // should be no more drawing calls made into the recording canvas. - void endRecording(); - - /** - * Tells the writer to commit all recorded draw commands to the - * controller immediately. - * @param detachCurrentBlock Set to true to request that the next draw - * command be recorded in a new block. - */ - void flushRecording(bool detachCurrentBlock); - - /** - * Return the amount of bytes being used for recording. Note that this - * does not include the amount of storage written to the stream, which is - * controlled by the SkGPipeController. - * Currently only returns the amount used for SkBitmaps, since they are - * potentially unbounded (if the client is not calling playback). - */ - size_t storageAllocatedForRecording() const; - - /** - * Attempt to reduce the storage allocated for recording by evicting - * cache resources. - * @param bytesToFree minimum number of bytes that should be attempted to - * be freed. - * @return number of bytes actually freed. - */ - size_t freeMemoryIfPossible(size_t bytesToFree); - -private: - enum { - kDefaultRecordingCanvasSize = 32767, - }; - - SkGPipeCanvas* fCanvas; - SkWriter32 fWriter; -}; - -#endif diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index c7a37e786c..199d18e416 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -10,14 +10,12 @@ #include "OverView.h" #include "Resources.h" #include "SampleCode.h" -#include "SamplePipeControllers.h" #include "SkAnimTimer.h" #include "SkCanvas.h" #include "SkCommandLineFlags.h" #include "SkData.h" #include "SkDevice.h" #include "SkDocument.h" -#include "SkGPipe.h" #include "SkGraphics.h" #include "SkImageEncoder.h" #include "SkOSFile.h" @@ -71,17 +69,6 @@ public: }; #endif // SAMPLE_PDF_FILE_VIEWER -#define PIPE_FILEx -#ifdef PIPE_FILE -#define FILE_PATH "/path/to/drawing.data" -#endif - -#define PIPE_NETx -#ifdef PIPE_NET -#include "SkSockets.h" -SkTCPServer gServer; -#endif - #if SK_COMMAND_BUFFER #define DEFAULT_TO_COMMAND_BUFFER 1 #elif SK_ANGLE @@ -835,12 +822,6 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev static SkTaskGroup::Enabler enabled(-1); gSampleWindow = this; -#ifdef PIPE_FILE - //Clear existing file or create file if it doesn't exist - FILE* f = fopen(FILE_PATH, "wb"); - fclose(f); -#endif - fDeviceType = kRaster_DeviceType; #if SK_SUPPORT_GPU if (FLAGS_gpu) { @@ -864,7 +845,6 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev fRotate = false; fPerspAnim = false; fRequestGrabImage = false; - fPipeState = SkOSMenu::kOffState; fTilingMode = kNo_Tiling; fMeasureFPS = false; fLCDState = SkOSMenu::kMixedState; @@ -927,10 +907,6 @@ SampleWindow::SampleWindow(void* hwnd, int argc, char** argv, DeviceManager* dev nullptr); fAppMenu->assignKeyEquivalentToItem(itemID, 'h'); - fUsePipeMenuItemID = fAppMenu->appendTriState("Pipe", "Pipe" , sinkID, - fPipeState); - fAppMenu->assignKeyEquivalentToItem(fUsePipeMenuItemID, 'P'); - itemID =fAppMenu->appendList("Tiling", "Tiling", sinkID, fTilingMode, gTilingInfo[kNo_Tiling].label, gTilingInfo[kAbs_128x128_Tiling].label, @@ -1624,16 +1600,6 @@ bool SampleWindow::onEvent(const SkEvent& evt) { this->setDeviceType((DeviceType)selected); return true; } - if (SkOSMenu::FindTriState(evt, "Pipe", &fPipeState)) { -#ifdef PIPE_NET - if (!fPipeState != SkOSMenu::kOnState) - gServer.disconnectAll(); -#endif - (void)SampleView::SetUsePipe(curr_view(this), fPipeState); - this->updateTitle(); - this->inval(nullptr); - return true; - } if (SkOSMenu::FindSwitchState(evt, "Slide Show", nullptr)) { this->toggleSlideshow(); return true; @@ -2018,12 +1984,6 @@ void SampleWindow::loadView(SkView* view) { //repopulate the slide menu when a view is loaded fSlideMenu->reset(); - (void)SampleView::SetUsePipe(view, fPipeState); - if (SampleView::IsSampleView(view)) { - SampleView* sampleView = (SampleView*)view; - sampleView->requestMenu(fSlideMenu); - sampleView->onTileSizeChanged(this->tileSize()); - } this->onUpdateMenu(fSlideMenu); this->updateTitle(); } @@ -2103,22 +2063,6 @@ void SampleWindow::updateTitle() { title.appendf(" %8.4f ms", fMeasureFPS_Time / (float)FPS_REPEAT_COUNT); } - SkView* view = curr_view(this); - if (SampleView::IsSampleView(view)) { - switch (fPipeState) { - case SkOSMenu::kOnState: - title.prepend(" "); - break; - case SkOSMenu::kMixedState: - title.prepend(" "); - break; - - default: - break; - } - title.prepend("! "); - } - #if SK_SUPPORT_GPU if (IsGpuDeviceType(fDeviceType) && fDevManager && @@ -2181,7 +2125,6 @@ void SampleWindow::onSizeChange() { static const char is_sample_view_tag[] = "sample-is-sample-view"; static const char repeat_count_tag[] = "sample-set-repeat-count"; -static const char set_use_pipe_tag[] = "sample-set-use-pipe"; bool SampleView::IsSampleView(SkView* view) { SkEvent evt(is_sample_view_tag); @@ -2194,24 +2137,11 @@ bool SampleView::SetRepeatDraw(SkView* view, int count) { return view->doEvent(evt); } -bool SampleView::SetUsePipe(SkView* view, SkOSMenu::TriState state) { - SkEvent evt; - evt.setS32(set_use_pipe_tag, state); - return view->doEvent(evt); -} - bool SampleView::onEvent(const SkEvent& evt) { if (evt.isType(repeat_count_tag)) { fRepeatCount = evt.getFast32(); return true; } - - int32_t pipeHolder; - if (evt.findS32(set_use_pipe_tag, &pipeHolder)) { - fPipeState = static_cast(pipeHolder); - return true; - } - return this->INHERITED::onEvent(evt); } @@ -2222,102 +2152,6 @@ bool SampleView::onQuery(SkEvent* evt) { return this->INHERITED::onQuery(evt); } - -class SimplePC : public SkGPipeController { -public: - SimplePC(SkCanvas* target); - ~SimplePC(); - - virtual void* requestBlock(size_t minRequest, size_t* actual); - virtual void notifyWritten(size_t bytes); - -private: - SkGPipeReader fReader; - void* fBlock; - size_t fBlockSize; - size_t fBytesWritten; - int fAtomsWritten; - SkGPipeReader::Status fStatus; - - size_t fTotalWritten; -}; - -SimplePC::SimplePC(SkCanvas* target) : fReader(target) { - fBlock = nullptr; - fBlockSize = fBytesWritten = 0; - fStatus = SkGPipeReader::kDone_Status; - fTotalWritten = 0; - fAtomsWritten = 0; - fReader.setBitmapDecoder(&SkImageDecoder::DecodeMemory); -} - -SimplePC::~SimplePC() { -// SkASSERT(SkGPipeReader::kDone_Status == fStatus); - if (fTotalWritten) { - SkDebugf("--- %d bytes %d atoms, status %d\n", fTotalWritten, - fAtomsWritten, fStatus); -#ifdef PIPE_FILE - //File is open in append mode - FILE* f = fopen(FILE_PATH, "ab"); - SkASSERT(f != nullptr); - fwrite((const char*)fBlock + fBytesWritten, 1, bytes, f); - fclose(f); -#endif -#ifdef PIPE_NET - if (fAtomsWritten > 1 && fTotalWritten > 4) { //ignore done - gServer.acceptConnections(); - gServer.writePacket(fBlock, fTotalWritten); - } -#endif - } - sk_free(fBlock); -} - -void* SimplePC::requestBlock(size_t minRequest, size_t* actual) { - sk_free(fBlock); - - fBlockSize = minRequest * 4; - fBlock = sk_malloc_throw(fBlockSize); - fBytesWritten = 0; - *actual = fBlockSize; - return fBlock; -} - -void SimplePC::notifyWritten(size_t bytes) { - SkASSERT(fBytesWritten + bytes <= fBlockSize); - fStatus = fReader.playback((const char*)fBlock + fBytesWritten, bytes); - SkASSERT(SkGPipeReader::kError_Status != fStatus); - fBytesWritten += bytes; - fTotalWritten += bytes; - - fAtomsWritten += 1; -} - -void SampleView::draw(SkCanvas* canvas) { - if (SkOSMenu::kOffState == fPipeState) { - this->INHERITED::draw(canvas); - } else { - SkGPipeWriter writer; - SimplePC controller(canvas); - SkBitmap bitmap = capture_bitmap(canvas); - TiledPipeController tc(bitmap, &SkImageDecoder::DecodeMemory, &canvas->getTotalMatrix()); - SkGPipeController* pc; - if (SkOSMenu::kMixedState == fPipeState) { - pc = &tc; - } else { - pc = &controller; - } - uint32_t flags = SkGPipeWriter::kCrossProcess_Flag; - - canvas = writer.startRecording(pc, flags); - //Must draw before controller goes out of scope and sends data - this->INHERITED::draw(canvas); - //explicitly end recording to ensure writer is flushed before the memory - //is freed in the deconstructor of the controller - writer.endRecording(); - } -} - void SampleView::onDraw(SkCanvas* canvas) { if (!fHaveCalledOnceBeforeDraw) { fHaveCalledOnceBeforeDraw = true; diff --git a/samplecode/SampleApp.h b/samplecode/SampleApp.h index 210abc0af3..44085b5ac1 100644 --- a/samplecode/SampleApp.h +++ b/samplecode/SampleApp.h @@ -191,12 +191,6 @@ private: bool fMagnify; int fTilingMode; - - SkOSMenu::TriState fPipeState; // Mixed uses a tiled pipe - // On uses a normal pipe - // Off uses no pipe - int fUsePipeMenuItemID; - // The following are for the 'fatbits' drawing // Latest position of the mouse. int fMouseX, fMouseY; diff --git a/samplecode/SampleCode.h b/samplecode/SampleCode.h index 6818c445f3..e4ccfb2af6 100644 --- a/samplecode/SampleCode.h +++ b/samplecode/SampleCode.h @@ -137,7 +137,6 @@ protected: // overrides virtual bool onEvent(const SkEvent& evt); virtual bool onQuery(SkEvent* evt); - virtual void draw(SkCanvas*); virtual void onDraw(SkCanvas*); SkOSMenu::TriState fPipeState; diff --git a/src/pipe/SkGPipePriv.h b/src/pipe/SkGPipePriv.h deleted file mode 100644 index 1820a4941a..0000000000 --- a/src/pipe/SkGPipePriv.h +++ /dev/null @@ -1,313 +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 SkGPipePriv_DEFINED -#define SkGPipePriv_DEFINED - -#include "SkTypes.h" - -#define UNIMPLEMENTED - -// these must be contiguous, 0...N-1 -enum PaintFlats { - kColorFilter_PaintFlat, - kDrawLooper_PaintFlat, - kImageFilter_PaintFlat, - kMaskFilter_PaintFlat, - kPathEffect_PaintFlat, - kRasterizer_PaintFlat, - kShader_PaintFlat, - kXfermode_PaintFlat, - - kLast_PaintFlat = kXfermode_PaintFlat -}; -#define kCount_PaintFlats (kLast_PaintFlat + 1) - -enum DrawOps { - kSkip_DrawOp, // skip an addition N bytes (N == data) - - // these match Canvas apis - kClipPath_DrawOp, - kClipRegion_DrawOp, - kClipRect_DrawOp, - kClipRRect_DrawOp, - kConcat_DrawOp, - kDrawAtlas_DrawOp, - kDrawBitmap_DrawOp, - kDrawBitmapNine_DrawOp, - kDrawBitmapRect_DrawOp, - kDrawDRRect_DrawOp, - kDrawImage_DrawOp, - kDrawImageRect_DrawOp, - kDrawImageNine_DrawOp, - kDrawOval_DrawOp, - kDrawPaint_DrawOp, - kDrawPatch_DrawOp, - kDrawPath_DrawOp, - kDrawPicture_DrawOp, - kDrawPoints_DrawOp, - kDrawPosText_DrawOp, - kDrawPosTextH_DrawOp, - kDrawRect_DrawOp, - kDrawRRect_DrawOp, - kDrawText_DrawOp, - kDrawTextBlob_DrawOp, - kDrawTextOnPath_DrawOp, - kDrawVertices_DrawOp, - kRestore_DrawOp, - kRotate_DrawOp, - kSave_DrawOp, - kSaveLayer_DrawOp, - kScale_DrawOp, - kSetMatrix_DrawOp, - kSkew_DrawOp, - kTranslate_DrawOp, - - kPaintOp_DrawOp, - kSetTypeface_DrawOp, - kSetAnnotation_DrawOp, - - kDef_Typeface_DrawOp, - kDef_Flattenable_DrawOp, - kDef_Bitmap_DrawOp, - kDef_Factory_DrawOp, - - // these are signals to playback, not drawing verbs - kReportFlags_DrawOp, - kShareBitmapHeap_DrawOp, - kShareImageHeap_DrawOp, - kDone_DrawOp, -}; - -/** - * DrawOp packs into a 32bit int as follows - * - * DrawOp:8 - Flags:4 - Data:20 - * - * Flags and Data are called out separately, so we can reuse Data between - * different Ops that might have different Flags. e.g. Data might be a Paint - * index for both drawRect (no flags) and saveLayer (does have flags). - * - * All Ops that take a SkPaint use their Data field to store the index to - * the paint (previously defined with kPaintOp_DrawOp). - */ - -#define DRAWOPS_OP_BITS 8 -#define DRAWOPS_FLAG_BITS 4 -#define DRAWOPS_DATA_BITS 20 - -#define DRAWOPS_OP_MASK ((1 << DRAWOPS_OP_BITS) - 1) -#define DRAWOPS_FLAG_MASK ((1 << DRAWOPS_FLAG_BITS) - 1) -#define DRAWOPS_DATA_MASK ((1 << DRAWOPS_DATA_BITS) - 1) - -static inline unsigned DrawOp_unpackOp(uint32_t op32) { - return (op32 >> (DRAWOPS_FLAG_BITS + DRAWOPS_DATA_BITS)); -} - -static inline unsigned DrawOp_unpackFlags(uint32_t op32) { - return (op32 >> DRAWOPS_DATA_BITS) & DRAWOPS_FLAG_MASK; -} - -static inline unsigned DrawOp_unpackData(uint32_t op32) { - return op32 & DRAWOPS_DATA_MASK; -} - -static inline uint32_t DrawOp_packOpFlagData(DrawOps op, unsigned flags, unsigned data) { - SkASSERT(0 == (op & ~DRAWOPS_OP_MASK)); - SkASSERT(0 == (flags & ~DRAWOPS_FLAG_MASK)); - SkASSERT(0 == (data & ~DRAWOPS_DATA_MASK)); - - return (op << (DRAWOPS_FLAG_BITS + DRAWOPS_DATA_BITS)) | - (flags << DRAWOPS_DATA_BITS) | - data; -} - -/** DrawOp specific flag bits - */ - -enum { - kSaveLayer_HasBounds_DrawOpFlag = 1 << 0, - kSaveLayer_HasPaint_DrawOpFlag = 1 << 1, -}; -enum { - kDrawTextOnPath_HasMatrix_DrawOpFlag = 1 << 0 -}; -enum { - kDrawVertices_HasTexs_DrawOpFlag = 1 << 0, - kDrawVertices_HasColors_DrawOpFlag = 1 << 1, - kDrawVertices_HasIndices_DrawOpFlag = 1 << 2, - kDrawVertices_HasXfermode_DrawOpFlag = 1 << 3, -}; -enum { - kDrawAtlas_HasPaint_DrawOpFlag = 1 << 0, - kDrawAtlas_HasColors_DrawOpFlag = 1 << 1, - kDrawAtlas_HasCull_DrawOpFlag = 1 << 2, -}; -// These are shared between drawbitmap and drawimage -enum { - kDrawBitmap_HasPaint_DrawOpFlag = 1 << 0, - // Specific to drawBitmapRect, but needs to be different from HasPaint, - // which is used for all drawBitmap calls, so include it here. - kDrawBitmap_HasSrcRect_DrawOpFlag = 1 << 1, - // SkCanvas::DrawBitmapRectFlags::kBleed_DrawBitmapRectFlag is - // converted into and out of this flag to save space - kDrawBitmap_Bleed_DrawOpFlag = 1 << 2, -}; -enum { - kClip_HasAntiAlias_DrawOpFlag = 1 << 0, -}; -/////////////////////////////////////////////////////////////////////////////// - -class BitmapInfo : SkNoncopyable { -public: - BitmapInfo(SkBitmap* bitmap, uint32_t genID, int toBeDrawnCount) - : fBitmap(bitmap) - , fGenID(genID) - , fBytesAllocated(0) - , fMoreRecentlyUsed(nullptr) - , fLessRecentlyUsed(nullptr) - , fToBeDrawnCount(toBeDrawnCount) - {} - - ~BitmapInfo() { - SkASSERT(0 == fToBeDrawnCount); - delete fBitmap; - } - - void addDraws(int drawsToAdd) { - if (0 == fToBeDrawnCount) { - // The readers will only ever decrement the count, so once the - // count is zero, the writer will be the only one modifying it, - // so it does not need to be an atomic operation. - fToBeDrawnCount = drawsToAdd; - } else { - sk_atomic_add(&fToBeDrawnCount, drawsToAdd); - } - } - - void decDraws() { - sk_atomic_dec(&fToBeDrawnCount); - } - - int drawCount() const { - return fToBeDrawnCount; - } - - SkBitmap* fBitmap; - // Store the generation ID of the original bitmap, since copying does - // not copy this field, so fBitmap's generation ID will not be useful - // for comparing. - // FIXME: Is it reasonable to make copying a bitmap/pixelref copy the - // generation ID? - uint32_t fGenID; - // Keep track of the bytes allocated for this bitmap. When replacing the - // bitmap or removing this BitmapInfo we know how much memory has been - // reclaimed. - size_t fBytesAllocated; - // TODO: Generalize the LRU caching mechanism - BitmapInfo* fMoreRecentlyUsed; - BitmapInfo* fLessRecentlyUsed; -private: - int fToBeDrawnCount; -}; - -static inline bool shouldFlattenBitmaps(uint32_t flags) { - return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag - && !(flags & SkGPipeWriter::kSharedAddressSpace_Flag)); -} - -class SkImageHeap : public SkRefCnt { -public: - SkImageHeap(); - virtual ~SkImageHeap(); - - size_t bytesInCache() const { return fBytesInCache; } - void reset(); - // slot must be "valid" -- 0 is never valid - const SkImage* get(int32_t slot) const; - // returns 0 if not found, else returns slot - int32_t find(const SkImage*) const; - // returns non-zero value for where the image was stored - int32_t insert(const SkImage*); - -private: - SkTDArray fArray; - size_t fBytesInCache; -}; - -/////////////////////////////////////////////////////////////////////////////// - -enum PaintOps { - kReset_PaintOp, // no arg - - kFlags_PaintOp, // arg inline - kColor_PaintOp, // arg 32 - kFilterLevel_PaintOp, // arg inline - kStyle_PaintOp, // arg inline - kJoin_PaintOp, // arg inline - kCap_PaintOp, // arg inline - kWidth_PaintOp, // arg scalar - kMiter_PaintOp, // arg scalar - - kEncoding_PaintOp, // arg inline - text - kHinting_PaintOp, // arg inline - text - kAlign_PaintOp, // arg inline - text - kTextSize_PaintOp, // arg scalar - text - kTextScaleX_PaintOp,// arg scalar - text - kTextSkewX_PaintOp, // arg scalar - text - kTypeface_PaintOp, // arg inline (index) - text - - kFlatIndex_PaintOp, // flags=paintflat, data=index -}; - -#define PAINTOPS_OP_BITS 8 -#define PAINTOPS_FLAG_BITS 4 -#define PAINTOPS_DATA_BITS 20 - -#define PAINTOPS_OP_MASK ((1 << PAINTOPS_OP_BITS) - 1) -#define PAINTOPS_FLAG_MASK ((1 << PAINTOPS_FLAG_BITS) - 1) -#define PAINTOPS_DATA_MASK ((1 << PAINTOPS_DATA_BITS) - 1) - -static inline unsigned PaintOp_unpackOp(uint32_t op32) { - return (op32 >> (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS)); -} - -static inline unsigned PaintOp_unpackFlags(uint32_t op32) { - return (op32 >> PAINTOPS_DATA_BITS) & PAINTOPS_FLAG_MASK; -} - -static inline unsigned PaintOp_unpackData(uint32_t op32) { - return op32 & PAINTOPS_DATA_MASK; -} - -static inline uint32_t PaintOp_packOp(PaintOps op) { - SkASSERT(0 == (op & ~PAINTOPS_OP_MASK)); - - return op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS); -} - -static inline uint32_t PaintOp_packOpData(PaintOps op, unsigned data) { - SkASSERT(0 == (op & ~PAINTOPS_OP_MASK)); - SkASSERT(0 == (data & ~PAINTOPS_DATA_MASK)); - - return (op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS)) | data; -} - -static inline uint32_t PaintOp_packOpFlagData(PaintOps op, unsigned flags, unsigned data) { - SkASSERT(0 == (op & ~PAINTOPS_OP_MASK)); - SkASSERT(0 == (flags & ~PAINTOPS_FLAG_MASK)); - SkASSERT(0 == (data & ~PAINTOPS_DATA_MASK)); - - return (op << (PAINTOPS_FLAG_BITS + PAINTOPS_DATA_BITS)) | - (flags << PAINTOPS_DATA_BITS) | - data; -} - -#endif diff --git a/src/pipe/SkGPipeRead.cpp b/src/pipe/SkGPipeRead.cpp deleted file mode 100644 index fa746bf2e9..0000000000 --- a/src/pipe/SkGPipeRead.cpp +++ /dev/null @@ -1,1009 +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 "SkBitmapHeap.h" -#include "SkCanvas.h" -#include "SkPaint.h" -#include "SkGPipe.h" -#include "SkGPipePriv.h" -#include "SkReader32.h" -#include "SkStream.h" - -#include "SkAnnotation.h" -#include "SkColorFilter.h" -#include "SkDrawLooper.h" -#include "SkImageFilter.h" -#include "SkMaskFilter.h" -#include "SkPatchUtils.h" -#include "SkPathEffect.h" -#include "SkRasterizer.h" -#include "SkReadBuffer.h" -#include "SkRRect.h" -#include "SkRSXform.h" -#include "SkShader.h" -#include "SkTextBlob.h" -#include "SkTypeface.h" -#include "SkXfermode.h" - -static SkFlattenable::Type paintflat_to_flattype(PaintFlats pf) { - static const uint8_t gEffectTypesInPaintFlatsOrder[] = { - SkFlattenable::kSkColorFilter_Type, - SkFlattenable::kSkDrawLooper_Type, - SkFlattenable::kSkImageFilter_Type, - SkFlattenable::kSkMaskFilter_Type, - SkFlattenable::kSkPathEffect_Type, - SkFlattenable::kSkRasterizer_Type, - SkFlattenable::kSkShader_Type, - SkFlattenable::kSkXfermode_Type, - }; - - SkASSERT((size_t)pf < SK_ARRAY_COUNT(gEffectTypesInPaintFlatsOrder)); - return (SkFlattenable::Type)gEffectTypesInPaintFlatsOrder[pf]; -} - -static void set_paintflat(SkPaint* paint, SkFlattenable* obj, unsigned paintFlat) { - SkASSERT(paintFlat < kCount_PaintFlats); - switch (paintFlat) { - case kColorFilter_PaintFlat: - paint->setColorFilter((SkColorFilter*)obj); - break; - case kDrawLooper_PaintFlat: - paint->setLooper((SkDrawLooper*)obj); - break; - case kMaskFilter_PaintFlat: - paint->setMaskFilter((SkMaskFilter*)obj); - break; - case kPathEffect_PaintFlat: - paint->setPathEffect((SkPathEffect*)obj); - break; - case kRasterizer_PaintFlat: - paint->setRasterizer((SkRasterizer*)obj); - break; - case kShader_PaintFlat: - paint->setShader((SkShader*)obj); - break; - case kImageFilter_PaintFlat: - paint->setImageFilter((SkImageFilter*)obj); - break; - case kXfermode_PaintFlat: - paint->setXfermode((SkXfermode*)obj); - break; - default: - SkDEBUGFAIL("never gets here"); - } -} - -template class SkRefCntTDArray : public SkTDArray { -public: - ~SkRefCntTDArray() { this->unrefAll(); } -}; - -static inline uint32_t set_clear_mask(uint32_t bits, bool cond, uint32_t mask) { - return cond ? bits | mask : bits & ~mask; -} - -class SkGPipeState : public SkBitmapHeapReader { -public: - SkGPipeState(); - ~SkGPipeState(); - - void setSilent(bool silent) { - fSilent = silent; - } - - bool shouldDraw() { - return !fSilent; - } - - void setFlags(unsigned flags) { - if (fFlags != flags) { - fFlags = flags; - this->updateReader(); - } - } - - unsigned getFlags() const { - return fFlags; - } - - void setReader(SkReadBuffer* reader) { - fReader = reader; - this->updateReader(); - } - - const SkPaint& paint() const { return fPaint; } - SkPaint* editPaint() { return &fPaint; } - - SkFlattenable* getFlat(unsigned index) const { - if (0 == index) { - return nullptr; - } - return fFlatArray[index - 1]; - } - - void defFlattenable(PaintFlats pf, int index) { - index--; - SkFlattenable* obj = fReader->readFlattenable(paintflat_to_flattype(pf)); - if (fFlatArray.count() == index) { - *fFlatArray.append() = obj; - } else { - SkSafeUnref(fFlatArray[index]); - fFlatArray[index] = obj; - } - } - - void defFactory(const char* name) { - SkFlattenable::Factory factory = SkFlattenable::NameToFactory(name); - if (factory) { - SkASSERT(fFactoryArray.find(factory) < 0); - *fFactoryArray.append() = factory; - } - } - - /** - * Add a bitmap to the array of bitmaps, or replace an existing one. - * This is only used when in cross process mode without a shared heap. - */ - void addBitmap(int index) { - SkASSERT(shouldFlattenBitmaps(fFlags)); - SkBitmap* bm; - if(fBitmaps.count() == index) { - bm = new SkBitmap; - *fBitmaps.append() = bm; - } else { - bm = fBitmaps[index]; - } - fReader->readBitmap(bm); - } - - /** - * Override of SkBitmapHeapReader, so that SkReadBuffer can use - * these SkBitmaps for bitmap shaders. Used only in cross process mode - * without a shared heap. - */ - SkBitmap* getBitmap(int32_t index) const override { - SkASSERT(shouldFlattenBitmaps(fFlags)); - return fBitmaps[index]; - } - - /** - * Needed to be a non-abstract subclass of SkBitmapHeapReader. - */ - void releaseRef(int32_t) override {} - - void setSharedHeap(SkBitmapHeap* heap) { - SkASSERT(!shouldFlattenBitmaps(fFlags) || nullptr == heap); - SkRefCnt_SafeAssign(fSharedHeap, heap); - this->updateReader(); - } - - void setImageHeap(SkImageHeap* heap) { - fImageHeap.reset(SkRef(heap)); - } - - /** - * Access the shared heap. Only used in the case when bitmaps are not - * flattened. - */ - SkBitmapHeap* getSharedHeap() const { - SkASSERT(!shouldFlattenBitmaps(fFlags)); - return fSharedHeap; - } - - void addTypeface() { - size_t size = fReader->read32(); - const void* data = fReader->skip(SkAlign4(size)); - SkMemoryStream stream(data, size, false); - *fTypefaces.append() = SkTypeface::Deserialize(&stream); - } - - SkTypeface* getTypeface(unsigned id) const { - return id ? fTypefaces[id - 1] : nullptr; - } - - const SkImage* getImage(int32_t slot) const { - return fImageHeap->get(slot); - } - -private: - void updateReader() { - if (nullptr == fReader) { - return; - } - bool crossProcess = SkToBool(fFlags & SkGPipeWriter::kCrossProcess_Flag); - fReader->setFlags(set_clear_mask(fReader->getFlags(), crossProcess, - SkReadBuffer::kCrossProcess_Flag)); - if (crossProcess) { - fReader->setFactoryArray(&fFactoryArray); - } else { - fReader->setFactoryArray(nullptr); - } - - if (shouldFlattenBitmaps(fFlags)) { - fReader->setBitmapStorage(this); - } else { - fReader->setBitmapStorage(fSharedHeap); - } - } - SkReadBuffer* fReader; - SkPaint fPaint; - SkTDArray fFlatArray; - SkTDArray fTypefaces; - SkTDArray fFactoryArray; - SkTDArray fBitmaps; - bool fSilent; - // Only used when sharing bitmaps with the writer. - SkBitmapHeap* fSharedHeap; - SkAutoTUnref fImageHeap; - unsigned fFlags; -}; - -/////////////////////////////////////////////////////////////////////////////// - -template const T* skip(SkReader32* reader, size_t count = 1) { - size_t size = sizeof(T) * count; - SkASSERT(SkAlign4(size) == size); - return reinterpret_cast(reader->skip(size)); -} - -template const T* skipAlign(SkReader32* reader, size_t count = 1) { - size_t size = SkAlign4(sizeof(T) * count); - return reinterpret_cast(reader->skip(size)); -} - -/////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////// - -static void clipPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkPath path; - reader->readPath(&path); - bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag); - canvas->clipPath(path, (SkRegion::Op)DrawOp_unpackData(op32), doAA); -} - -static void clipRegion_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkRegion rgn; - reader->readRegion(&rgn); - canvas->clipRegion(rgn, (SkRegion::Op)DrawOp_unpackData(op32)); -} - -static void clipRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - const SkRect* rect = skip(reader); - bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag); - canvas->clipRect(*rect, (SkRegion::Op)DrawOp_unpackData(op32), doAA); -} - -static void clipRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkRRect rrect; - reader->readRRect(&rrect); - bool doAA = SkToBool(DrawOp_unpackFlags(op32) & kClip_HasAntiAlias_DrawOpFlag); - canvas->clipRRect(rrect, (SkRegion::Op)DrawOp_unpackData(op32), doAA); -} - -/////////////////////////////////////////////////////////////////////////////// - -static void setMatrix_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkMatrix matrix; - reader->readMatrix(&matrix); - canvas->setMatrix(matrix); -} - -static void concat_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkMatrix matrix; - reader->readMatrix(&matrix); - canvas->concat(matrix); -} - -static void scale_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - const SkScalar* param = skip(reader, 2); - canvas->scale(param[0], param[1]); -} - -static void skew_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - const SkScalar* param = skip(reader, 2); - canvas->skew(param[0], param[1]); -} - -static void rotate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - canvas->rotate(reader->readScalar()); -} - -static void translate_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - const SkScalar* param = skip(reader, 2); - canvas->translate(param[0], param[1]); -} - -/////////////////////////////////////////////////////////////////////////////// - -static void save_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - canvas->save(); -} - -static void saveLayer_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - unsigned flags = DrawOp_unpackFlags(op32); - SkCanvas::SaveLayerFlags saveLayerFlags = DrawOp_unpackData(op32); - - const SkRect* bounds = nullptr; - if (flags & kSaveLayer_HasBounds_DrawOpFlag) { - bounds = skip(reader); - } - const SkPaint* paint = nullptr; - if (flags & kSaveLayer_HasPaint_DrawOpFlag) { - paint = &state->paint(); - } - canvas->saveLayer(SkCanvas::SaveLayerRec(bounds, paint, saveLayerFlags)); -} - -static void restore_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - canvas->restore(); -} - -/////////////////////////////////////////////////////////////////////////////// - -static void drawPaint_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - if (state->shouldDraw()) { - canvas->drawPaint(state->paint()); - } -} - -static void drawPoints_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkCanvas::PointMode mode = (SkCanvas::PointMode)DrawOp_unpackFlags(op32); - size_t count = reader->readU32(); - const SkPoint* pts = skip(reader, count); - if (state->shouldDraw()) { - canvas->drawPoints(mode, count, pts, state->paint()); - } -} - -static void drawOval_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - const SkRect* rect = skip(reader); - if (state->shouldDraw()) { - canvas->drawOval(*rect, state->paint()); - } -} - -static void drawRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - const SkRect* rect = skip(reader); - if (state->shouldDraw()) { - canvas->drawRect(*rect, state->paint()); - } -} - -static void drawRRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkRRect rrect; - reader->readRRect(&rrect); - if (state->shouldDraw()) { - canvas->drawRRect(rrect, state->paint()); - } -} - -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 drawPatch_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - - unsigned flags = DrawOp_unpackFlags(op32); - - const SkPoint* cubics = skip(reader, SkPatchUtils::kNumCtrlPts); - - const SkColor* colors = nullptr; - if (flags & kDrawVertices_HasColors_DrawOpFlag) { - colors = skip(reader, SkPatchUtils::kNumCorners); - } - const SkPoint* texCoords = nullptr; - if (flags & kDrawVertices_HasTexs_DrawOpFlag) { - texCoords = skip(reader, SkPatchUtils::kNumCorners); - } - SkAutoTUnref xfer; - if (flags & kDrawVertices_HasXfermode_DrawOpFlag) { - int mode = reader->readInt(); - if (mode < 0 || mode > SkXfermode::kLastMode) { - mode = SkXfermode::kModulate_Mode; - } - xfer.reset(SkXfermode::Create((SkXfermode::Mode)mode)); - } - if (state->shouldDraw()) { - canvas->drawPatch(cubics, colors, texCoords, xfer, state->paint()); - } -} - -static void drawPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkPath path; - reader->readPath(&path); - if (state->shouldDraw()) { - canvas->drawPath(path, state->paint()); - } -} - -static void drawVertices_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - unsigned flags = DrawOp_unpackFlags(op32); - - SkCanvas::VertexMode vmode = (SkCanvas::VertexMode)reader->readU32(); - int vertexCount = reader->readU32(); - const SkPoint* verts = skip(reader, vertexCount); - - const SkPoint* texs = nullptr; - if (flags & kDrawVertices_HasTexs_DrawOpFlag) { - texs = skip(reader, vertexCount); - } - - const SkColor* colors = nullptr; - if (flags & kDrawVertices_HasColors_DrawOpFlag) { - colors = skip(reader, vertexCount); - } - - SkAutoTUnref xfer; - if (flags & kDrawVertices_HasXfermode_DrawOpFlag) { - SkXfermode::Mode mode = (SkXfermode::Mode)reader->readU32(); - xfer.reset(SkXfermode::Create(mode)); - } - - int indexCount = 0; - const uint16_t* indices = nullptr; - if (flags & kDrawVertices_HasIndices_DrawOpFlag) { - indexCount = reader->readU32(); - indices = skipAlign(reader, indexCount); - } - if (state->shouldDraw()) { - canvas->drawVertices(vmode, vertexCount, verts, texs, colors, xfer, - indices, indexCount, state->paint()); - } -} - -static void drawAtlas_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { - unsigned flags = DrawOp_unpackFlags(op32); - - const SkPaint* paint = nullptr; - if (flags & kDrawAtlas_HasPaint_DrawOpFlag) { - paint = &state->paint(); - } - const int slot = reader->readU32(); - const SkImage* atlas = state->getImage(slot); - const int count = reader->readU32(); - SkXfermode::Mode mode = (SkXfermode::Mode)reader->readU32(); - const SkRSXform* xform = skip(reader, count); - const SkRect* tex = skip(reader, count); - const SkColor* colors = nullptr; - if (flags & kDrawAtlas_HasColors_DrawOpFlag) { - colors = skip(reader, count); - } - const SkRect* cull = nullptr; - if (flags & kDrawAtlas_HasCull_DrawOpFlag) { - cull = skip(reader, 1); - } - - if (state->shouldDraw()) { - canvas->drawAtlas(atlas, xform, tex, colors, count, mode, cull, paint); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -static void drawText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - size_t len = reader->readU32(); - const void* text = reader->skip(SkAlign4(len)); - const SkScalar* xy = skip(reader, 2); - if (state->shouldDraw()) { - canvas->drawText(text, len, xy[0], xy[1], state->paint()); - } -} - -static void drawPosText_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - size_t len = reader->readU32(); - const void* text = reader->skip(SkAlign4(len)); - size_t posCount = reader->readU32(); // compute by our writer - const SkPoint* pos = skip(reader, posCount); - if (state->shouldDraw()) { - canvas->drawPosText(text, len, pos, state->paint()); - } -} - -static void drawPosTextH_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - size_t len = reader->readU32(); - const void* text = reader->skip(SkAlign4(len)); - size_t posCount = reader->readU32(); // compute by our writer - const SkScalar* xpos = skip(reader, posCount); - SkScalar constY = reader->readScalar(); - if (state->shouldDraw()) { - canvas->drawPosTextH(text, len, xpos, constY, state->paint()); - } -} - -static void drawTextOnPath_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - size_t len = reader->readU32(); - const void* text = reader->skip(SkAlign4(len)); - - SkPath path; - reader->readPath(&path); - - SkMatrix matrixStorage; - const SkMatrix* matrix = nullptr; - if (DrawOp_unpackFlags(op32) & kDrawTextOnPath_HasMatrix_DrawOpFlag) { - reader->readMatrix(&matrixStorage); - matrix = &matrixStorage; - } - if (state->shouldDraw()) { - canvas->drawTextOnPath(text, len, path, matrix, state->paint()); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -class BitmapHolder : SkNoncopyable { -public: - BitmapHolder(SkReader32* reader, uint32_t op32, SkGPipeState* state); - ~BitmapHolder() { - if (fHeapEntry != nullptr) { - fHeapEntry->releaseRef(); - } - } - const SkBitmap* getBitmap() { - return fBitmap; - } -private: - SkBitmapHeapEntry* fHeapEntry; - const SkBitmap* fBitmap; - SkBitmap fBitmapStorage; -}; - -BitmapHolder::BitmapHolder(SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - const unsigned flags = state->getFlags(); - const unsigned index = DrawOp_unpackData(op32); - if (shouldFlattenBitmaps(flags)) { - fHeapEntry = nullptr; - fBitmap = state->getBitmap(index); - } else { - SkBitmapHeapEntry* entry = state->getSharedHeap()->getEntry(index); - if (SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag)) { - // Make a shallow copy for thread safety. Each thread will point to the same SkPixelRef, - // which is thread safe. - fBitmapStorage = *entry->getBitmap(); - fBitmap = &fBitmapStorage; - // Release the ref on the bitmap now, since we made our own copy. - entry->releaseRef(); - fHeapEntry = nullptr; - } else { - SkASSERT(!shouldFlattenBitmaps(flags)); - SkASSERT(!SkToBool(flags & SkGPipeWriter::kSimultaneousReaders_Flag)); - fHeapEntry = entry; - fBitmap = fHeapEntry->getBitmap(); - } - } -} - -static void drawBitmap_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - BitmapHolder holder(reader, op32, state); - bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag); - SkScalar left = reader->readScalar(); - SkScalar top = reader->readScalar(); - const SkBitmap* bitmap = holder.getBitmap(); - if (state->shouldDraw()) { - canvas->drawBitmap(*bitmap, left, top, hasPaint ? &state->paint() : nullptr); - } -} - -static void drawBitmapNine_rp(SkCanvas* canvas, SkReader32* reader, - uint32_t op32, SkGPipeState* state) { - BitmapHolder holder(reader, op32, state); - bool hasPaint = SkToBool(DrawOp_unpackFlags(op32) & kDrawBitmap_HasPaint_DrawOpFlag); - const SkIRect* center = skip(reader); - const SkRect* dst = skip(reader); - const SkBitmap* bitmap = holder.getBitmap(); - if (state->shouldDraw()) { - canvas->drawBitmapNine(*bitmap, *center, *dst, - hasPaint ? &state->paint() : nullptr); - } -} - -static void drawBitmapRect_rp(SkCanvas* canvas, SkReader32* reader, - uint32_t op32, SkGPipeState* state) { - BitmapHolder holder(reader, op32, state); - unsigned flags = DrawOp_unpackFlags(op32); - bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag); - bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag); - const SkRect* src; - if (hasSrc) { - src = skip(reader); - } else { - src = nullptr; - } - SkCanvas::SrcRectConstraint constraint = SkCanvas::kStrict_SrcRectConstraint; - if (flags & kDrawBitmap_Bleed_DrawOpFlag) { - constraint = SkCanvas::kFast_SrcRectConstraint; - } - const SkRect* dst = skip(reader); - const SkBitmap* bitmap = holder.getBitmap(); - if (state->shouldDraw()) { - canvas->legacy_drawBitmapRect(*bitmap, src, *dst, hasPaint ? &state->paint() : nullptr, constraint); - } -} - -static void drawImage_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, SkGPipeState* state) { - unsigned slot = DrawOp_unpackData(op32); - unsigned flags = DrawOp_unpackFlags(op32); - bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag); - SkScalar x = reader->readScalar(); - SkScalar y = reader->readScalar(); - const SkImage* image = state->getImage(slot); - if (state->shouldDraw()) { - canvas->drawImage(image, x, y, hasPaint ? &state->paint() : nullptr); - } -} - -static void drawImageRect_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - unsigned slot = DrawOp_unpackData(op32); - unsigned flags = DrawOp_unpackFlags(op32); - bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag); - bool hasSrc = SkToBool(flags & kDrawBitmap_HasSrcRect_DrawOpFlag); - const SkRect* src = nullptr; - if (hasSrc) { - src = skip(reader); - } - const SkRect* dst = skip(reader); - SkCanvas::SrcRectConstraint constraint = (SkCanvas::SrcRectConstraint)reader->readInt(); - - const SkImage* image = state->getImage(slot); - if (state->shouldDraw()) { - canvas->legacy_drawImageRect(image, src, *dst, hasPaint ? &state->paint() : nullptr, constraint); - } -} - -static void drawImageNine_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - unsigned slot = DrawOp_unpackData(op32); - unsigned flags = DrawOp_unpackFlags(op32); - bool hasPaint = SkToBool(flags & kDrawBitmap_HasPaint_DrawOpFlag); - const SkIRect* center = skip(reader); - const SkRect* dst = skip(reader); - const SkImage* image = state->getImage(slot); - if (state->shouldDraw()) { - canvas->drawImageNine(image, *center, *dst, hasPaint ? &state->paint() : nullptr); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -static void drawPicture_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - UNIMPLEMENTED -} - -static void drawTextBlob_rp(SkCanvas* canvas, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkScalar x = reader->readScalar(); - SkScalar y = reader->readScalar(); - - int typefaceCount = reader->readU32(); - SkAutoSTMalloc<16, SkTypeface*> typefaceArray(typefaceCount); - if (state->getFlags() & SkGPipeWriter::kCrossProcess_Flag) { - for (int i = 0; i < typefaceCount; ++i) { - typefaceArray[i] = state->getTypeface(reader->readU32()); - } - } else { - reader->read(typefaceArray.get(), typefaceCount * sizeof(SkTypeface*)); - } - - size_t blobSize = reader->readU32(); - const void* data = reader->skip(SkAlign4(blobSize)); - - if (state->shouldDraw()) { - SkReadBuffer blobBuffer(data, blobSize); - blobBuffer.setTypefaceArray(typefaceArray.get(), typefaceCount); - SkAutoTUnref blob(SkTextBlob::CreateFromBuffer(blobBuffer)); - SkASSERT(blob.get()); - - canvas->drawTextBlob(blob, x, y, state->paint()); - } -} -/////////////////////////////////////////////////////////////////////////////// - -static void paintOp_rp(SkCanvas*, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - size_t offset = reader->offset(); - size_t stop = offset + PaintOp_unpackData(op32); - SkPaint* p = state->editPaint(); - - do { - uint32_t p32 = reader->readU32(); - unsigned op = PaintOp_unpackOp(p32); - unsigned data = PaintOp_unpackData(p32); - -// SkDebugf(" read %08X op=%d flags=%d data=%d\n", p32, op, done, data); - - switch (op) { - case kReset_PaintOp: p->reset(); break; - case kFlags_PaintOp: p->setFlags(data); break; - case kColor_PaintOp: p->setColor(reader->readU32()); break; - case kFilterLevel_PaintOp: p->setFilterQuality((SkFilterQuality)data); break; - case kStyle_PaintOp: p->setStyle((SkPaint::Style)data); break; - case kJoin_PaintOp: p->setStrokeJoin((SkPaint::Join)data); break; - case kCap_PaintOp: p->setStrokeCap((SkPaint::Cap)data); break; - case kWidth_PaintOp: p->setStrokeWidth(reader->readScalar()); break; - case kMiter_PaintOp: p->setStrokeMiter(reader->readScalar()); break; - case kEncoding_PaintOp: - p->setTextEncoding((SkPaint::TextEncoding)data); - break; - case kHinting_PaintOp: p->setHinting((SkPaint::Hinting)data); break; - case kAlign_PaintOp: p->setTextAlign((SkPaint::Align)data); break; - case kTextSize_PaintOp: p->setTextSize(reader->readScalar()); break; - case kTextScaleX_PaintOp: p->setTextScaleX(reader->readScalar()); break; - case kTextSkewX_PaintOp: p->setTextSkewX(reader->readScalar()); break; - - case kFlatIndex_PaintOp: { - PaintFlats pf = (PaintFlats)PaintOp_unpackFlags(p32); - unsigned index = data; - set_paintflat(p, state->getFlat(index), pf); - break; - } - - case kTypeface_PaintOp: - SkASSERT(SkToBool(state->getFlags() & - SkGPipeWriter::kCrossProcess_Flag)); - p->setTypeface(state->getTypeface(data)); - break; - default: SkDEBUGFAIL("bad paintop"); return; - } - SkASSERT(reader->offset() <= stop); - } while (reader->offset() < stop); -} - -static void typeface_rp(SkCanvas*, SkReader32* reader, uint32_t, - SkGPipeState* state) { - SkASSERT(!SkToBool(state->getFlags() & SkGPipeWriter::kCrossProcess_Flag)); - SkPaint* p = state->editPaint(); - p->setTypeface(static_cast(reader->readPtr())); -} - -static void annotation_rp(SkCanvas*, SkReader32* reader, uint32_t op32, - SkGPipeState* state) { - SkPaint* p = state->editPaint(); - - const size_t size = DrawOp_unpackData(op32); - if (size > 0) { - SkReadBuffer buffer(reader->skip(size), size); - p->setAnnotation(SkAnnotation::Create(buffer))->unref(); - SkASSERT(buffer.offset() == size); - } else { - p->setAnnotation(nullptr); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -static void def_Typeface_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState* state) { - state->addTypeface(); -} - -static void def_PaintFlat_rp(SkCanvas*, SkReader32*, uint32_t op32, - SkGPipeState* state) { - PaintFlats pf = (PaintFlats)DrawOp_unpackFlags(op32); - unsigned index = DrawOp_unpackData(op32); - state->defFlattenable(pf, index); -} - -static void def_Bitmap_rp(SkCanvas*, SkReader32*, uint32_t op32, - SkGPipeState* state) { - unsigned index = DrawOp_unpackData(op32); - state->addBitmap(index); -} - -static void def_Factory_rp(SkCanvas*, SkReader32* reader, uint32_t, - SkGPipeState* state) { - state->defFactory(reader->readString()); -} - -/////////////////////////////////////////////////////////////////////////////// - -static void skip_rp(SkCanvas*, SkReader32* reader, uint32_t op32, SkGPipeState*) { - size_t bytes = DrawOp_unpackData(op32); - (void)reader->skip(bytes); -} - -static void reportFlags_rp(SkCanvas*, SkReader32*, uint32_t op32, - SkGPipeState* state) { - unsigned flags = DrawOp_unpackFlags(op32); - state->setFlags(flags); -} - -static void shareBitmapHeap_rp(SkCanvas*, SkReader32* reader, uint32_t, - SkGPipeState* state) { - state->setSharedHeap(static_cast(reader->readPtr())); -} - -static void shareImageHeap_rp(SkCanvas*, SkReader32* reader, uint32_t, SkGPipeState* state) { - state->setImageHeap(static_cast(reader->readPtr())); -} - -static void done_rp(SkCanvas*, SkReader32*, uint32_t, SkGPipeState*) {} - -typedef void (*ReadProc)(SkCanvas*, SkReader32*, uint32_t op32, SkGPipeState*); - -static const ReadProc gReadTable[] = { - skip_rp, - clipPath_rp, - clipRegion_rp, - clipRect_rp, - clipRRect_rp, - concat_rp, - drawAtlas_rp, - drawBitmap_rp, - drawBitmapNine_rp, - drawBitmapRect_rp, - drawDRRect_rp, - drawImage_rp, - drawImageRect_rp, - drawImageNine_rp, - drawOval_rp, - drawPaint_rp, - drawPatch_rp, - drawPath_rp, - drawPicture_rp, - drawPoints_rp, - drawPosText_rp, - drawPosTextH_rp, - drawRect_rp, - drawRRect_rp, - drawText_rp, - drawTextBlob_rp, - drawTextOnPath_rp, - drawVertices_rp, - restore_rp, - rotate_rp, - save_rp, - saveLayer_rp, - scale_rp, - setMatrix_rp, - skew_rp, - translate_rp, - - paintOp_rp, - typeface_rp, - annotation_rp, - - def_Typeface_rp, - def_PaintFlat_rp, - def_Bitmap_rp, - def_Factory_rp, - - reportFlags_rp, - shareBitmapHeap_rp, - shareImageHeap_rp, - done_rp -}; - -/////////////////////////////////////////////////////////////////////////////// - -SkGPipeState::SkGPipeState() - : fReader(0) - , fSilent(false) - , fSharedHeap(nullptr) - , fFlags(0) { - -} - -SkGPipeState::~SkGPipeState() { - fTypefaces.safeUnrefAll(); - fFlatArray.safeUnrefAll(); - fBitmaps.deleteAll(); - SkSafeUnref(fSharedHeap); -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkGPipe.h" - -SkGPipeReader::SkGPipeReader() { - fCanvas = nullptr; - fState = nullptr; - fProc = nullptr; -} - -SkGPipeReader::SkGPipeReader(SkCanvas* target) { - fCanvas = nullptr; - this->setCanvas(target); - fState = nullptr; - fProc = nullptr; -} - -void SkGPipeReader::setCanvas(SkCanvas *target) { - SkRefCnt_SafeAssign(fCanvas, target); -} - -SkGPipeReader::~SkGPipeReader() { - SkSafeUnref(fCanvas); - delete fState; -} - -SkGPipeReader::Status SkGPipeReader::playback(const void* data, size_t length, - uint32_t playbackFlags, size_t* bytesRead) { - if (nullptr == fCanvas) { - return kError_Status; - } - - if (nullptr == fState) { - fState = new SkGPipeState; - } - - fState->setSilent(playbackFlags & kSilent_PlaybackFlag); - - SkASSERT(SK_ARRAY_COUNT(gReadTable) == (kDone_DrawOp + 1)); - - const ReadProc* table = gReadTable; - SkReadBuffer reader(data, length); - reader.setBitmapDecoder(fProc); - SkCanvas* canvas = fCanvas; - Status status = kEOF_Status; - - fState->setReader(&reader); - while (!reader.eof()) { - uint32_t op32 = reader.readUInt(); - unsigned op = DrawOp_unpackOp(op32); - // SkDEBUGCODE(DrawOps drawOp = (DrawOps)op;) - - if (op >= SK_ARRAY_COUNT(gReadTable)) { - SkDebugf("---- bad op during GPipeState::playback\n"); - status = kError_Status; - break; - } - if (kDone_DrawOp == op) { - status = kDone_Status; - break; - } - table[op](canvas, reader.getReader32(), op32, fState); - if ((playbackFlags & kReadAtom_PlaybackFlag) && - (table[op] != paintOp_rp && - table[op] != def_Typeface_rp && - table[op] != def_PaintFlat_rp && - table[op] != def_Bitmap_rp - )) { - status = kReadAtom_Status; - break; - } - } - - if (bytesRead) { - *bytesRead = reader.offset(); - } - return status; -} diff --git a/src/pipe/SkGPipeWrite.cpp b/src/pipe/SkGPipeWrite.cpp deleted file mode 100644 index 5147cd688d..0000000000 --- a/src/pipe/SkGPipeWrite.cpp +++ /dev/null @@ -1,1483 +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 "SkAnnotation.h" -#include "SkBitmapHeap.h" -#include "SkCanvas.h" -#include "SkColorFilter.h" -#include "SkData.h" -#include "SkDrawLooper.h" -#include "SkGPipe.h" -#include "SkGPipePriv.h" -#include "SkImageFilter.h" -#include "SkMaskFilter.h" -#include "SkRSXform.h" -#include "SkWriteBuffer.h" -#include "SkPaint.h" -#include "SkPatchUtils.h" -#include "SkPathEffect.h" -#include "SkPictureFlat.h" -#include "SkPtrRecorder.h" -#include "SkRasterizer.h" -#include "SkRRect.h" -#include "SkShader.h" -#include "SkStream.h" -#include "SkTextBlob.h" -#include "SkTSearch.h" -#include "SkTypeface.h" -#include "SkWriter32.h" - -enum { - kSizeOfFlatRRect = sizeof(SkRect) + 4 * sizeof(SkVector) -}; - -static bool is_cross_process(uint32_t flags) { - return SkToBool(flags & SkGPipeWriter::kCrossProcess_Flag); -} - -static SkFlattenable* get_paintflat(const SkPaint& paint, unsigned paintFlat) { - SkASSERT(paintFlat < kCount_PaintFlats); - switch (paintFlat) { - case kColorFilter_PaintFlat: return paint.getColorFilter(); - case kDrawLooper_PaintFlat: return paint.getLooper(); - case kMaskFilter_PaintFlat: return paint.getMaskFilter(); - case kPathEffect_PaintFlat: return paint.getPathEffect(); - case kRasterizer_PaintFlat: return paint.getRasterizer(); - case kShader_PaintFlat: return paint.getShader(); - case kImageFilter_PaintFlat: return paint.getImageFilter(); - case kXfermode_PaintFlat: return paint.getXfermode(); - } - SkDEBUGFAIL("never gets here"); - return nullptr; -} - -static size_t writeTypeface(SkWriter32* writer, SkTypeface* typeface) { - SkASSERT(typeface); - SkDynamicMemoryWStream stream; - typeface->serialize(&stream); - size_t size = stream.getOffset(); - if (writer) { - writer->write32(SkToU32(size)); - SkAutoDataUnref data(stream.copyToData()); - writer->writePad(data->data(), size); - } - return 4 + SkAlign4(size); -} - -/////////////////////////////////////////////////////////////////////////////// - -class FlattenableHeap : public SkFlatController { -public: - FlattenableHeap(int numFlatsToKeep, SkNamedFactorySet* fset, bool isCrossProcess) - : INHERITED(isCrossProcess ? SkWriteBuffer::kCrossProcess_Flag : 0) - , fNumFlatsToKeep(numFlatsToKeep) { - SkASSERT((isCrossProcess && fset != nullptr) || (!isCrossProcess && nullptr == fset)); - if (isCrossProcess) { - this->setNamedFactorySet(fset); - } - } - - ~FlattenableHeap() { - fPointers.freeAll(); - } - - void* allocThrow(size_t bytes) override; - - void unalloc(void* ptr) override; - - void setBitmapStorage(SkBitmapHeap* heap) { - this->setBitmapHeap(heap); - } - - const SkFlatData* flatToReplace() const; - - // Mark an SkFlatData as one that should not be returned by flatToReplace. - // Takes the result of SkFlatData::index() as its parameter. - void markFlatForKeeping(int index) { - *fFlatsThatMustBeKept.append() = index; - } - - void markAllFlatsSafeToDelete() { - fFlatsThatMustBeKept.reset(); - } - -private: - // Keep track of the indices (i.e. the result of SkFlatData::index()) of - // flats that must be kept, since they are on the current paint. - SkTDArray fFlatsThatMustBeKept; - SkTDArray fPointers; - const int fNumFlatsToKeep; - - typedef SkFlatController INHERITED; -}; - -void FlattenableHeap::unalloc(void* ptr) { - int indexToRemove = fPointers.rfind(ptr); - if (indexToRemove >= 0) { - sk_free(ptr); - fPointers.remove(indexToRemove); - } -} - -void* FlattenableHeap::allocThrow(size_t bytes) { - void* ptr = sk_malloc_throw(bytes); - *fPointers.append() = ptr; - return ptr; -} - -const SkFlatData* FlattenableHeap::flatToReplace() const { - // First, determine whether we should replace one. - if (fPointers.count() > fNumFlatsToKeep) { - // Look through the flattenable heap. - // TODO: Return the LRU flat. - for (int i = 0; i < fPointers.count(); i++) { - SkFlatData* potential = (SkFlatData*)fPointers[i]; - // Make sure that it is not one that must be kept. - bool mustKeep = false; - for (int j = 0; j < fFlatsThatMustBeKept.count(); j++) { - if (potential->index() == fFlatsThatMustBeKept[j]) { - mustKeep = true; - break; - } - } - if (!mustKeep) { - return potential; - } - } - } - return nullptr; -} - -/////////////////////////////////////////////////////////////////////////////// - -struct SkFlattenableTraits { - static void Flatten(SkWriteBuffer& buffer, const SkFlattenable& flattenable) { - buffer.writeFlattenable(&flattenable); - } - // No need to define unflatten if we never call it. -}; -typedef SkFlatDictionary FlatDictionary; - -/////////////////////////////////////////////////////////////////////////////// - -/** - * If SkBitmaps are to be flattened to send to the reader, this class is - * provided to the SkBitmapHeap to tell the SkGPipeCanvas to do so. - */ -class BitmapShuttle : public SkBitmapHeap::ExternalStorage { -public: - BitmapShuttle(SkGPipeCanvas*); - - ~BitmapShuttle(); - - bool insert(const SkBitmap& bitmap, int32_t slot) override; - - /** - * Remove the SkGPipeCanvas used for insertion. After this, calls to - * insert will crash. - */ - void removeCanvas(); - -private: - SkGPipeCanvas* fCanvas; -}; - -/////////////////////////////////////////////////////////////////////////////// - -class SkGPipeCanvas : public SkCanvas { -public: - SkGPipeCanvas(SkGPipeController*, SkWriter32*, uint32_t flags, - uint32_t width, uint32_t height); - virtual ~SkGPipeCanvas(); - - /** - * Called when nothing else is to be written to the stream. Any repeated - * calls are ignored. - * - * @param notifyReaders Whether to send a message to the reader(s) that - * the writer is through sending commands. Should generally be true, - * unless there is an error which prevents further messages from - * being sent. - */ - void finish(bool notifyReaders) { - if (fDone) { - return; - } - if (notifyReaders && this->needOpBytes()) { - this->writeOp(kDone_DrawOp); - this->doNotify(); - } - if (shouldFlattenBitmaps(fFlags)) { - // The following circular references exist: - // fFlattenableHeap -> fWriteBuffer -> fBitmapStorage -> fExternalStorage -> fCanvas - // fBitmapHeap -> fExternalStorage -> fCanvas - // fFlattenableHeap -> fBitmapStorage -> fExternalStorage -> fCanvas - - // Break them all by destroying the final link to this SkGPipeCanvas. - fBitmapShuttle->removeCanvas(); - } - fDone = true; - } - - void flushRecording(bool detachCurrentBlock); - size_t freeMemoryIfPossible(size_t bytesToFree); - - size_t storageAllocatedForRecording() { - size_t bytesAllocated = 0; - if (nullptr != fBitmapHeap) { - bytesAllocated += fBitmapHeap->bytesAllocated(); - } - if (nullptr != fImageHeap) { - bytesAllocated += fImageHeap->bytesInCache(); - } - return bytesAllocated; - } - - /** - * Flatten an SkBitmap to send to the reader, where it will be referenced - * according to slot. - */ - bool shuttleBitmap(const SkBitmap&, int32_t slot); - - void resetImageHeap(); - -protected: - void willSave() override; - SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override; - void willRestore() override; - - void didConcat(const SkMatrix&) override; - void didSetMatrix(const SkMatrix&) override; - - void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; - void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, - const SkPaint&) override; - void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], - const SkPaint&) override; - void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], - SkScalar constY, const SkPaint&) override; - void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, - const SkMatrix* matrix, const SkPaint&) override; - void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, - const SkPaint& paint) override; - void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], - const SkPoint texCoords[4], SkXfermode* xmode, - const SkPaint& paint) override; - void onDrawPaint(const SkPaint&) override; - void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; - void onDrawRect(const SkRect&, const SkPaint&) override; - void onDrawOval(const SkRect&, const SkPaint&) override; - void onDrawRRect(const SkRRect&, const SkPaint&) override; - void onDrawPath(const SkPath&, const SkPaint&) override; - void onDrawBitmap(const SkBitmap&, SkScalar left, SkScalar top, const SkPaint*) override; - void onDrawBitmapRect(const SkBitmap&, const SkRect* src, const SkRect& dst, const SkPaint*, - SrcRectConstraint) override; - void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override; - void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, - const SkPaint*, SrcRectConstraint) override; - void onDrawImageNine(const SkImage*, const SkIRect& center, const SkRect& dst, - const SkPaint*) override; - void onDrawBitmapNine(const SkBitmap&, const SkIRect& center, const SkRect& dst, - const SkPaint*) override; - void onDrawVertices(VertexMode vmode, int vertexCount, - const SkPoint vertices[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xmode, - const uint16_t indices[], int indexCount, - const SkPaint&) override; - void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], - int count, SkXfermode::Mode, const SkRect* cull, const SkPaint*) override; - void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) override; - void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) override; - void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) override; - void onClipRegion(const SkRegion&, SkRegion::Op) override; - - void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; - -private: - void recordTranslate(const SkMatrix&); - void recordScale(const SkMatrix&); - void recordConcat(const SkMatrix&); - - SkNamedFactorySet* fFactorySet; - SkBitmapHeap* fBitmapHeap; - SkImageHeap* fImageHeap; - SkGPipeController* fController; - SkWriter32& fWriter; - size_t fBlockSize; // amount allocated for writer - size_t fBytesNotified; - bool fDone; - const uint32_t fFlags; - - SkRefCntSet fTypefaceSet; - - uint32_t getTypefaceID(SkTypeface*); - - inline void writeOp(DrawOps op, unsigned flags, unsigned data) { - fWriter.write32(DrawOp_packOpFlagData(op, flags, data)); - } - - inline void writeOp(DrawOps op) { - fWriter.write32(DrawOp_packOpFlagData(op, 0, 0)); - } - - bool needOpBytes(size_t size = 0); - - inline void doNotify() { - if (!fDone) { - size_t bytes = fWriter.bytesWritten() - fBytesNotified; - if (bytes > 0) { - fController->notifyWritten(bytes); - fBytesNotified += bytes; - } - } - } - - typedef SkAutoSTMalloc<128, uint8_t> TypefaceBuffer; - size_t getInProcessTypefaces(const SkRefCntSet& typefaceSet, TypefaceBuffer*); - size_t getCrossProcessTypefaces(const SkRefCntSet& typefaceSet, TypefaceBuffer*); - - // Should be called after any calls to an SkFlatDictionary::findAndReplace - // if a new SkFlatData was added when in cross process mode - void flattenFactoryNames(); - - FlattenableHeap fFlattenableHeap; - FlatDictionary fFlatDictionary; - SkAutoTUnref fBitmapShuttle; - int fCurrFlatIndex[kCount_PaintFlats]; - - int flattenToIndex(SkFlattenable* obj, PaintFlats); - - // Common code used by drawBitmap*. Behaves differently depending on the - // type of SkBitmapHeap being used, which is determined by the flags used. - bool commonDrawBitmap(const SkBitmap&, DrawOps, unsigned flags, size_t bytes, const SkPaint*); - bool commonDrawImage(const SkImage*, DrawOps, unsigned flags, size_t bytes, const SkPaint*); - - SkPaint fPaint; - void writePaint(const SkPaint&); - - class AutoPipeNotify { - public: - AutoPipeNotify(SkGPipeCanvas* canvas) : fCanvas(canvas) {} - ~AutoPipeNotify() { fCanvas->doNotify(); } - private: - SkGPipeCanvas* fCanvas; - }; - friend class AutoPipeNotify; - - typedef SkCanvas INHERITED; -}; - -void SkGPipeCanvas::flattenFactoryNames() { - const char* name; - while ((name = fFactorySet->getNextAddedFactoryName()) != nullptr) { - size_t len = strlen(name); - if (this->needOpBytes(SkWriter32::WriteStringSize(name, len))) { - this->writeOp(kDef_Factory_DrawOp); - fWriter.writeString(name, len); - } - } -} - -bool SkGPipeCanvas::shuttleBitmap(const SkBitmap& bm, int32_t slot) { - SkASSERT(shouldFlattenBitmaps(fFlags)); - SkWriteBuffer buffer; - buffer.setNamedFactoryRecorder(fFactorySet); - buffer.writeBitmap(bm); - this->flattenFactoryNames(); - size_t size = buffer.bytesWritten(); - if (this->needOpBytes(size)) { - this->writeOp(kDef_Bitmap_DrawOp, 0, slot); - void* dst = static_cast(fWriter.reserve(size)); - buffer.writeToMemory(dst); - return true; - } - return false; -} - -// return 0 for nullptr (or unflattenable obj), or index-base-1 -// return ~(index-base-1) if an old flattenable was replaced -int SkGPipeCanvas::flattenToIndex(SkFlattenable* obj, PaintFlats paintflat) { - SkASSERT(!fDone && fBitmapHeap != nullptr); - if (nullptr == obj) { - return 0; - } - - fBitmapHeap->deferAddingOwners(); - bool added, replaced; - const SkFlatData* flat = fFlatDictionary.findAndReplace(*obj, fFlattenableHeap.flatToReplace(), - &added, &replaced); - fBitmapHeap->endAddingOwnersDeferral(added); - int index = flat->index(); - if (added) { - if (is_cross_process(fFlags)) { - this->flattenFactoryNames(); - } - size_t flatSize = flat->flatSize(); - if (this->needOpBytes(flatSize)) { - this->writeOp(kDef_Flattenable_DrawOp, paintflat, index); - fWriter.write(flat->data(), flatSize); - } - } - if (replaced) { - index = ~index; - } - return index; -} - -/////////////////////////////////////////////////////////////////////////////// - -#define MIN_BLOCK_SIZE (16 * 1024) -#define BITMAPS_TO_KEEP 5 -#define FLATTENABLES_TO_KEEP 10 - -SkGPipeCanvas::SkGPipeCanvas(SkGPipeController* controller, - SkWriter32* writer, - uint32_t flags, - uint32_t width, - uint32_t height) - : SkCanvas(width, height) - , fFactorySet(is_cross_process(flags) ? new SkNamedFactorySet : nullptr) - , fWriter(*writer) - , fFlags(flags) - , fFlattenableHeap(FLATTENABLES_TO_KEEP, fFactorySet, is_cross_process(flags)) - , fFlatDictionary(&fFlattenableHeap) { - fController = controller; - fDone = false; - fBlockSize = 0; // need first block from controller - fBytesNotified = 0; - sk_bzero(fCurrFlatIndex, sizeof(fCurrFlatIndex)); - - // Tell the reader the appropriate flags to use. - if (this->needOpBytes()) { - this->writeOp(kReportFlags_DrawOp, fFlags, 0); - } - - if (shouldFlattenBitmaps(flags)) { - fBitmapShuttle.reset(new BitmapShuttle(this)); - fBitmapHeap = new SkBitmapHeap(fBitmapShuttle.get(), BITMAPS_TO_KEEP); - } else { - fBitmapHeap = new SkBitmapHeap(BITMAPS_TO_KEEP, controller->numberOfReaders()); - if (this->needOpBytes(sizeof(void*))) { - this->writeOp(kShareBitmapHeap_DrawOp); - fWriter.writePtr(static_cast(fBitmapHeap)); - } - } - fFlattenableHeap.setBitmapStorage(fBitmapHeap); - - fImageHeap = new SkImageHeap; - if (this->needOpBytes(sizeof(void*))) { - this->writeOp(kShareImageHeap_DrawOp); - fWriter.writePtr(static_cast(fImageHeap)); - } - - this->doNotify(); -} - -SkGPipeCanvas::~SkGPipeCanvas() { - this->finish(true); - SkSafeUnref(fFactorySet); - SkSafeUnref(fBitmapHeap); - SkSafeUnref(fImageHeap); -} - -bool SkGPipeCanvas::needOpBytes(size_t needed) { - if (fDone) { - return false; - } - - needed += 4; // size of DrawOp atom - needed = SkAlign4(needed); - if (fWriter.bytesWritten() + needed > fBlockSize) { - // Before we wipe out any data that has already been written, read it out. - this->doNotify(); - - // If we're going to allocate a new block, allocate enough to make it worthwhile. - needed = SkTMax(MIN_BLOCK_SIZE, needed); - - void* block = fController->requestBlock(needed, &fBlockSize); - if (nullptr == block) { - // Do not notify the readers, which would call this function again. - this->finish(false); - return false; - } - SkASSERT(SkIsAlign4(fBlockSize)); - fWriter.reset(block, fBlockSize); - fBytesNotified = 0; - } - return true; -} - -uint32_t SkGPipeCanvas::getTypefaceID(SkTypeface* face) { - uint32_t id = 0; // 0 means default/null typeface - if (face) { - id = fTypefaceSet.find(face); - if (0 == id) { - id = fTypefaceSet.add(face); - size_t size = writeTypeface(nullptr, face); - if (this->needOpBytes(size)) { - this->writeOp(kDef_Typeface_DrawOp); - writeTypeface(&fWriter, face); - } - } - } - return id; -} - -/////////////////////////////////////////////////////////////////////////////// - -#define NOTIFY_SETUP(canvas) \ - AutoPipeNotify apn(canvas) - -void SkGPipeCanvas::willSave() { - NOTIFY_SETUP(this); - if (this->needOpBytes()) { - this->writeOp(kSave_DrawOp); - } - - this->INHERITED::willSave(); -} - -SkCanvas::SaveLayerStrategy SkGPipeCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) { - NOTIFY_SETUP(this); - size_t size = 0; - unsigned opFlags = 0; - - if (rec.fBounds) { - opFlags |= kSaveLayer_HasBounds_DrawOpFlag; - size += sizeof(SkRect); - } - if (rec.fPaint) { - opFlags |= kSaveLayer_HasPaint_DrawOpFlag; - this->writePaint(*rec.fPaint); - } - - if (this->needOpBytes(size)) { - this->writeOp(kSaveLayer_DrawOp, opFlags, rec.fSaveLayerFlags); - if (rec.fBounds) { - fWriter.writeRect(*rec.fBounds); - } - } - - (void)this->INHERITED::getSaveLayerStrategy(rec); - // we don't create a layer - return kNoLayer_SaveLayerStrategy; -} - -void SkGPipeCanvas::willRestore() { - NOTIFY_SETUP(this); - if (this->needOpBytes()) { - this->writeOp(kRestore_DrawOp); - } - - this->INHERITED::willRestore(); -} - -void SkGPipeCanvas::recordTranslate(const SkMatrix& m) { - if (this->needOpBytes(2 * sizeof(SkScalar))) { - this->writeOp(kTranslate_DrawOp); - fWriter.writeScalar(m.getTranslateX()); - fWriter.writeScalar(m.getTranslateY()); - } -} - -void SkGPipeCanvas::recordScale(const SkMatrix& m) { - if (this->needOpBytes(2 * sizeof(SkScalar))) { - this->writeOp(kScale_DrawOp); - fWriter.writeScalar(m.getScaleX()); - fWriter.writeScalar(m.getScaleY()); - } -} - -void SkGPipeCanvas::recordConcat(const SkMatrix& m) { - if (this->needOpBytes(m.writeToMemory(nullptr))) { - this->writeOp(kConcat_DrawOp); - fWriter.writeMatrix(m); - } -} - -void SkGPipeCanvas::didConcat(const SkMatrix& matrix) { - if (!matrix.isIdentity()) { - NOTIFY_SETUP(this); - switch (matrix.getType()) { - case SkMatrix::kTranslate_Mask: - this->recordTranslate(matrix); - break; - case SkMatrix::kScale_Mask: - this->recordScale(matrix); - break; - default: - this->recordConcat(matrix); - break; - } - } - - this->INHERITED::didConcat(matrix); -} - -void SkGPipeCanvas::didSetMatrix(const SkMatrix& matrix) { - NOTIFY_SETUP(this); - if (this->needOpBytes(matrix.writeToMemory(nullptr))) { - this->writeOp(kSetMatrix_DrawOp); - fWriter.writeMatrix(matrix); - } - this->INHERITED::didSetMatrix(matrix); -} - -void SkGPipeCanvas::onClipRect(const SkRect& rect, SkRegion::Op rgnOp, - ClipEdgeStyle edgeStyle) { - NOTIFY_SETUP(this); - if (this->needOpBytes(sizeof(SkRect))) { - unsigned flags = 0; - if (kSoft_ClipEdgeStyle == edgeStyle) { - flags = kClip_HasAntiAlias_DrawOpFlag; - } - this->writeOp(kClipRect_DrawOp, flags, rgnOp); - fWriter.writeRect(rect); - } - this->INHERITED::onClipRect(rect, rgnOp, edgeStyle); -} - -void SkGPipeCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op rgnOp, - ClipEdgeStyle edgeStyle) { - NOTIFY_SETUP(this); - if (this->needOpBytes(kSizeOfFlatRRect)) { - unsigned flags = 0; - if (kSoft_ClipEdgeStyle == edgeStyle) { - flags = kClip_HasAntiAlias_DrawOpFlag; - } - this->writeOp(kClipRRect_DrawOp, flags, rgnOp); - fWriter.writeRRect(rrect); - } - this->INHERITED::onClipRRect(rrect, rgnOp, edgeStyle); -} - -void SkGPipeCanvas::onClipPath(const SkPath& path, SkRegion::Op rgnOp, - ClipEdgeStyle edgeStyle) { - NOTIFY_SETUP(this); - if (this->needOpBytes(path.writeToMemory(nullptr))) { - 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 - this->INHERITED::onClipRect(path.getBounds(), rgnOp, edgeStyle); -} - -void SkGPipeCanvas::onClipRegion(const SkRegion& region, SkRegion::Op rgnOp) { - NOTIFY_SETUP(this); - if (this->needOpBytes(region.writeToMemory(nullptr))) { - this->writeOp(kClipRegion_DrawOp, 0, rgnOp); - fWriter.writeRegion(region); - } - this->INHERITED::onClipRegion(region, rgnOp); -} - -/////////////////////////////////////////////////////////////////////////////// - -void SkGPipeCanvas::onDrawPaint(const SkPaint& paint) { - NOTIFY_SETUP(this); - this->writePaint(paint); - if (this->needOpBytes()) { - this->writeOp(kDrawPaint_DrawOp); - } -} - -void SkGPipeCanvas::onDrawPoints(PointMode mode, size_t count, - const SkPoint pts[], const SkPaint& paint) { - if (count) { - NOTIFY_SETUP(this); - this->writePaint(paint); - if (this->needOpBytes(4 + count * sizeof(SkPoint))) { - this->writeOp(kDrawPoints_DrawOp, mode, 0); - fWriter.write32(SkToU32(count)); - fWriter.write(pts, count * sizeof(SkPoint)); - } - } -} - -void SkGPipeCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) { - NOTIFY_SETUP(this); - this->writePaint(paint); - if (this->needOpBytes(sizeof(SkRect))) { - this->writeOp(kDrawOval_DrawOp); - fWriter.writeRect(rect); - } -} - -void SkGPipeCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) { - NOTIFY_SETUP(this); - this->writePaint(paint); - if (this->needOpBytes(sizeof(SkRect))) { - this->writeOp(kDrawRect_DrawOp); - fWriter.writeRect(rect); - } -} - -void SkGPipeCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) { - NOTIFY_SETUP(this); - this->writePaint(paint); - if (this->needOpBytes(kSizeOfFlatRRect)) { - this->writeOp(kDrawRRect_DrawOp); - fWriter.writeRRect(rrect); - } -} - -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::onDrawPath(const SkPath& path, const SkPaint& paint) { - NOTIFY_SETUP(this); - this->writePaint(paint); - if (this->needOpBytes(path.writeToMemory(nullptr))) { - this->writeOp(kDrawPath_DrawOp); - fWriter.writePath(path); - } -} - -bool SkGPipeCanvas::commonDrawBitmap(const SkBitmap& bm, DrawOps op, - unsigned flags, - size_t opBytesNeeded, - const SkPaint* paint) { - if (fDone) { - return false; - } - - if (paint != nullptr) { - flags |= kDrawBitmap_HasPaint_DrawOpFlag; - this->writePaint(*paint); - } - // This needs to run first so its calls to needOpBytes() and its writes - // don't interlace with the needOpBytes() and write below. - SkASSERT(fBitmapHeap != nullptr); - int32_t bitmapIndex = fBitmapHeap->insert(bm); - if (SkBitmapHeap::INVALID_SLOT == bitmapIndex) { - return false; - } - - if (this->needOpBytes(opBytesNeeded)) { - this->writeOp(op, flags, bitmapIndex); - return true; - } - return false; -} - -void SkGPipeCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar left, SkScalar top, - const SkPaint* paint) { - NOTIFY_SETUP(this); - size_t opBytesNeeded = sizeof(SkScalar) * 2; - - if (this->commonDrawBitmap(bm, kDrawBitmap_DrawOp, 0, opBytesNeeded, paint)) { - fWriter.writeScalar(left); - fWriter.writeScalar(top); - } -} - -void SkGPipeCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst, - const SkPaint* paint, SrcRectConstraint constraint) { - NOTIFY_SETUP(this); - size_t opBytesNeeded = sizeof(SkRect); - bool hasSrc = src != nullptr; - unsigned flags; - if (hasSrc) { - flags = kDrawBitmap_HasSrcRect_DrawOpFlag; - opBytesNeeded += sizeof(int32_t) * 4; - } else { - flags = 0; - } - if (kFast_SrcRectConstraint == constraint) { - flags |= kDrawBitmap_Bleed_DrawOpFlag; - } - - if (this->commonDrawBitmap(bm, kDrawBitmapRect_DrawOp, flags, opBytesNeeded, paint)) { - if (hasSrc) { - fWriter.writeRect(*src); - } - fWriter.writeRect(dst); - } -} - -void SkGPipeCanvas::onDrawBitmapNine(const SkBitmap& bm, const SkIRect& center, - const SkRect& dst, const SkPaint* paint) { - NOTIFY_SETUP(this); - size_t opBytesNeeded = sizeof(int32_t) * 4 + sizeof(SkRect); - - if (this->commonDrawBitmap(bm, kDrawBitmapNine_DrawOp, 0, opBytesNeeded, paint)) { - fWriter.write32(center.fLeft); - fWriter.write32(center.fTop); - fWriter.write32(center.fRight); - fWriter.write32(center.fBottom); - fWriter.writeRect(dst); - } -} - -bool SkGPipeCanvas::commonDrawImage(const SkImage* image, DrawOps op, unsigned flags, - size_t opBytesNeeded, const SkPaint* paint) { - if (fDone) { - return false; - } - - if (paint != nullptr) { - flags |= kDrawBitmap_HasPaint_DrawOpFlag; - this->writePaint(*paint); - } - // This needs to run first so its calls to needOpBytes() and its writes - // don't interlace with the needOpBytes() and write below. - int32_t slot = fImageHeap->insert(image); - SkASSERT(slot != 0); - if (this->needOpBytes(opBytesNeeded)) { - this->writeOp(op, flags, slot); - return true; - } - return false; -} - -void SkGPipeCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, - const SkPaint* paint) { - NOTIFY_SETUP(this); - if (this->commonDrawImage(image, kDrawImage_DrawOp, 0, sizeof(SkScalar) * 2, paint)) { - fWriter.writeScalar(x); - fWriter.writeScalar(y); - } -} - -void SkGPipeCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const SkRect& dst, - const SkPaint* paint, SrcRectConstraint constraint) { - NOTIFY_SETUP(this); - unsigned flags = 0; - size_t opBytesNeeded = sizeof(SkRect); // dst - if (src) { - flags |= kDrawBitmap_HasSrcRect_DrawOpFlag; - opBytesNeeded += sizeof(SkRect); // src - } - if (this->commonDrawImage(image, kDrawImageRect_DrawOp, flags, opBytesNeeded, paint)) { - if (src) { - fWriter.writeRect(*src); - } - fWriter.writeRect(dst); - fWriter.writeInt(constraint); - } -} - -void SkGPipeCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, const SkRect& dst, - const SkPaint* paint) { - NOTIFY_SETUP(this); - size_t opBytesNeeded = sizeof(SkIRect) + sizeof(SkRect); // center + dst - if (this->commonDrawImage(image, kDrawImageNine_DrawOp, 0, opBytesNeeded, paint)) { - fWriter.writeIRect(center); - fWriter.writeRect(dst); - } -} - -void SkGPipeCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, - const SkPaint& paint) { - if (byteLength) { - NOTIFY_SETUP(this); - this->writePaint(paint); - if (this->needOpBytes(4 + SkAlign4(byteLength) + 2 * sizeof(SkScalar))) { - this->writeOp(kDrawText_DrawOp); - fWriter.write32(SkToU32(byteLength)); - fWriter.writePad(text, byteLength); - fWriter.writeScalar(x); - fWriter.writeScalar(y); - } - } -} - -void SkGPipeCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], - const SkPaint& paint) { - if (byteLength) { - NOTIFY_SETUP(this); - this->writePaint(paint); - int count = paint.textToGlyphs(text, byteLength, nullptr); - if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkPoint))) { - this->writeOp(kDrawPosText_DrawOp); - fWriter.write32(SkToU32(byteLength)); - fWriter.writePad(text, byteLength); - fWriter.write32(count); - fWriter.write(pos, count * sizeof(SkPoint)); - } - } -} - -void SkGPipeCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], - SkScalar constY, const SkPaint& paint) { - if (byteLength) { - NOTIFY_SETUP(this); - this->writePaint(paint); - int count = paint.textToGlyphs(text, byteLength, nullptr); - if (this->needOpBytes(4 + SkAlign4(byteLength) + 4 + count * sizeof(SkScalar) + 4)) { - this->writeOp(kDrawPosTextH_DrawOp); - fWriter.write32(SkToU32(byteLength)); - fWriter.writePad(text, byteLength); - fWriter.write32(count); - fWriter.write(xpos, count * sizeof(SkScalar)); - fWriter.writeScalar(constY); - } - } -} - -void SkGPipeCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, - const SkMatrix* matrix, const SkPaint& paint) { - if (byteLength) { - NOTIFY_SETUP(this); - unsigned flags = 0; - size_t size = 4 + SkAlign4(byteLength) + path.writeToMemory(nullptr); - if (matrix) { - flags |= kDrawTextOnPath_HasMatrix_DrawOpFlag; - size += matrix->writeToMemory(nullptr); - } - this->writePaint(paint); - if (this->needOpBytes(size)) { - this->writeOp(kDrawTextOnPath_DrawOp, flags, 0); - - fWriter.write32(SkToU32(byteLength)); - fWriter.writePad(text, byteLength); - - fWriter.writePath(path); - if (matrix) { - fWriter.writeMatrix(*matrix); - } - } - } -} - -size_t SkGPipeCanvas::getInProcessTypefaces(const SkRefCntSet& typefaceSet, - TypefaceBuffer* buffer) { - // When in-process, we simply write out the typeface pointers. - size_t size = typefaceSet.count() * sizeof(SkTypeface*); - buffer->reset(size); - typefaceSet.copyToArray(reinterpret_cast(buffer->get())); - - return size; -} - -size_t SkGPipeCanvas::getCrossProcessTypefaces(const SkRefCntSet& typefaceSet, - TypefaceBuffer* buffer) { - // For cross-process we use typeface IDs. - size_t size = typefaceSet.count() * sizeof(uint32_t); - buffer->reset(size); - - uint32_t* idBuffer = reinterpret_cast(buffer->get()); - SkRefCntSet::Iter iter(typefaceSet); - int i = 0; - - for (void* setPtr = iter.next(); setPtr; setPtr = iter.next()) { - idBuffer[i++] = this->getTypefaceID(reinterpret_cast(setPtr)); - } - - SkASSERT(i == typefaceSet.count()); - - return size; -} - -void SkGPipeCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, - const SkPaint& paint) { - NOTIFY_SETUP(this); - this->writePaint(paint); - - // FIXME: this is inefficient but avoids duplicating the blob serialization logic. - SkRefCntSet typefaceSet; - SkWriteBuffer blobBuffer; - blobBuffer.setTypefaceRecorder(&typefaceSet); - blob->flatten(blobBuffer); - - // Unlike most draw ops (which only use one paint/typeface), text blobs may reference - // an arbitrary number of typefaces. Since the one-paint-per-op model is not applicable, - // we need to serialize these explicitly. - TypefaceBuffer typefaceBuffer; - size_t typefaceSize = is_cross_process(fFlags) - ? this->getCrossProcessTypefaces(typefaceSet, &typefaceBuffer) - : this->getInProcessTypefaces(typefaceSet, &typefaceBuffer); - - // blob byte count + typeface count + x + y + blob data + an index (cross-process) - // or pointer (in-process) for each typeface - size_t size = 2 * sizeof(uint32_t) - + 2 * sizeof(SkScalar) - + blobBuffer.bytesWritten() - + typefaceSize; - - if (this->needOpBytes(size)) { - this->writeOp(kDrawTextBlob_DrawOp); - SkDEBUGCODE(size_t initialOffset = fWriter.bytesWritten();) - - fWriter.writeScalar(x); - fWriter.writeScalar(y); - - fWriter.write32(typefaceSet.count()); - fWriter.write(typefaceBuffer.get(), typefaceSize); - - fWriter.write32(SkToU32(blobBuffer.bytesWritten())); - uint32_t* pad = fWriter.reservePad(blobBuffer.bytesWritten()); - blobBuffer.writeToMemory(pad); - - SkASSERT(initialOffset + size == fWriter.bytesWritten()); - } -} - -void SkGPipeCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, - const SkPaint* paint) { - // we want to playback the picture into individual draw calls - // - // todo: do we always have to unroll? If the pipe is not cross-process, seems like - // we could just ref the picture and move on...? - // - this->INHERITED::onDrawPicture(picture, matrix, paint); -} - -void SkGPipeCanvas::onDrawVertices(VertexMode vmode, int vertexCount, - const SkPoint vertices[], const SkPoint texs[], - const SkColor colors[], SkXfermode* xfer, - const uint16_t indices[], int indexCount, - const SkPaint& paint) { - if (0 == vertexCount) { - return; - } - - NOTIFY_SETUP(this); - this->writePaint(paint); - - unsigned flags = 0; // packs with the op, so needs no extra space - - size_t size = 0; - size += 4; // vmode - size += 4; // vertex count - size += vertexCount * sizeof(SkPoint); // vertices - - if (texs) { - flags |= kDrawVertices_HasTexs_DrawOpFlag; - size += vertexCount * sizeof(SkPoint); - } - if (colors) { - flags |= kDrawVertices_HasColors_DrawOpFlag; - size += vertexCount * sizeof(SkColor); - } - if (xfer && !SkXfermode::IsMode(xfer, SkXfermode::kModulate_Mode)) { - flags |= kDrawVertices_HasXfermode_DrawOpFlag; - size += sizeof(int32_t); // SkXfermode::Mode - } - if (indices && indexCount > 0) { - flags |= kDrawVertices_HasIndices_DrawOpFlag; - size += 4; // index count - size += SkAlign4(indexCount * sizeof(uint16_t)); // indices - } - - if (this->needOpBytes(size)) { - this->writeOp(kDrawVertices_DrawOp, flags, 0); - fWriter.write32(vmode); - fWriter.write32(vertexCount); - fWriter.write(vertices, vertexCount * sizeof(SkPoint)); - if (flags & kDrawVertices_HasTexs_DrawOpFlag) { - fWriter.write(texs, vertexCount * sizeof(SkPoint)); - } - if (flags & kDrawVertices_HasColors_DrawOpFlag) { - fWriter.write(colors, vertexCount * sizeof(SkColor)); - } - if (flags & kDrawVertices_HasXfermode_DrawOpFlag) { - SkXfermode::Mode mode = SkXfermode::kModulate_Mode; - SkAssertResult(xfer->asMode(&mode)); - fWriter.write32(mode); - } - if (flags & kDrawVertices_HasIndices_DrawOpFlag) { - fWriter.write32(indexCount); - fWriter.writePad(indices, indexCount * sizeof(uint16_t)); - } - } -} - -void SkGPipeCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRect tex[], - const SkColor colors[], int count, SkXfermode::Mode mode, - const SkRect* cull, const SkPaint* paint) { - NOTIFY_SETUP(this); - unsigned flags = 0; // packs with the op, so needs no extra space - - if (paint) { - flags |= kDrawAtlas_HasPaint_DrawOpFlag; - this->writePaint(*paint); - } - - size_t size = 4; // image-slot - size += 4; // count - size += 4; // mode - size += count * sizeof(SkRSXform); // xform - size += count * sizeof(SkRect); // tex - if (colors) { - flags |= kDrawAtlas_HasColors_DrawOpFlag; - size += count * sizeof(SkColor); // colors - } - if (cull) { - flags |= kDrawAtlas_HasCull_DrawOpFlag; - size += sizeof(SkRect); // cull - } - - if (this->needOpBytes(size)) { - this->writeOp(kDrawAtlas_DrawOp, flags, 0); - int32_t slot = fImageHeap->insert(atlas); - fWriter.write32(slot); - fWriter.write32(count); - fWriter.write32(mode); - fWriter.write(xform, count * sizeof(SkRSXform)); - fWriter.write(tex, count * sizeof(SkRect)); - if (colors) { - fWriter.write(colors, count * sizeof(SkColor)); - } - if (cull) { - fWriter.writeRect(*cull); - } - } -} - -void SkGPipeCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], - const SkPoint texCoords[4], SkXfermode* xmode, - const SkPaint& paint) { - NOTIFY_SETUP(this); - - size_t size = SkPatchUtils::kNumCtrlPts * sizeof(SkPoint); - unsigned flags = 0; - if (colors) { - flags |= kDrawVertices_HasColors_DrawOpFlag; - size += SkPatchUtils::kNumCorners * sizeof(SkColor); - } - if (texCoords) { - flags |= kDrawVertices_HasTexs_DrawOpFlag; - size += SkPatchUtils::kNumCorners * sizeof(SkPoint); - } - if (xmode) { - SkXfermode::Mode mode; - if (xmode->asMode(&mode) && SkXfermode::kModulate_Mode != mode) { - flags |= kDrawVertices_HasXfermode_DrawOpFlag; - size += sizeof(int32_t); - } - } - - this->writePaint(paint); - if (this->needOpBytes(size)) { - this->writeOp(kDrawPatch_DrawOp, flags, 0); - - fWriter.write(cubics, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint)); - - if (colors) { - fWriter.write(colors, SkPatchUtils::kNumCorners * sizeof(SkColor)); - } - - if (texCoords) { - fWriter.write(texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint)); - } - - if (flags & kDrawVertices_HasXfermode_DrawOpFlag) { - SkXfermode::Mode mode = SkXfermode::kModulate_Mode; - SkAssertResult(xmode->asMode(&mode)); - fWriter.write32(mode); - } - } -} - -void SkGPipeCanvas::flushRecording(bool detachCurrentBlock) { - this->doNotify(); - if (detachCurrentBlock) { - // force a new block to be requested for the next recorded command - fBlockSize = 0; - } -} - -void SkGPipeCanvas::resetImageHeap() { - if (fImageHeap) { - fImageHeap->reset(); - } -} - -size_t SkGPipeCanvas::freeMemoryIfPossible(size_t bytesToFree) { - return (nullptr == fBitmapHeap) ? 0 : fBitmapHeap->freeMemoryIfPossible(bytesToFree); -} - -/////////////////////////////////////////////////////////////////////////////// - -template uint32_t castToU32(T value) { - union { - T fSrc; - uint32_t fDst; - } data; - data.fSrc = value; - return data.fDst; -} - -void SkGPipeCanvas::writePaint(const SkPaint& paint) { - if (fDone) { - return; - } - SkPaint& base = fPaint; - uint32_t storage[32]; - uint32_t* ptr = storage; - - if (base.getFlags() != paint.getFlags()) { - *ptr++ = PaintOp_packOpData(kFlags_PaintOp, paint.getFlags()); - base.setFlags(paint.getFlags()); - } - if (base.getColor() != paint.getColor()) { - *ptr++ = PaintOp_packOp(kColor_PaintOp); - *ptr++ = paint.getColor(); - base.setColor(paint.getColor()); - } - if (base.getFilterQuality() != paint.getFilterQuality()) { - *ptr++ = PaintOp_packOpData(kFilterLevel_PaintOp, paint.getFilterQuality()); - base.setFilterQuality(paint.getFilterQuality()); - } - if (base.getStyle() != paint.getStyle()) { - *ptr++ = PaintOp_packOpData(kStyle_PaintOp, paint.getStyle()); - base.setStyle(paint.getStyle()); - } - if (base.getStrokeJoin() != paint.getStrokeJoin()) { - *ptr++ = PaintOp_packOpData(kJoin_PaintOp, paint.getStrokeJoin()); - base.setStrokeJoin(paint.getStrokeJoin()); - } - if (base.getStrokeCap() != paint.getStrokeCap()) { - *ptr++ = PaintOp_packOpData(kCap_PaintOp, paint.getStrokeCap()); - base.setStrokeCap(paint.getStrokeCap()); - } - if (base.getStrokeWidth() != paint.getStrokeWidth()) { - *ptr++ = PaintOp_packOp(kWidth_PaintOp); - *ptr++ = castToU32(paint.getStrokeWidth()); - base.setStrokeWidth(paint.getStrokeWidth()); - } - if (base.getStrokeMiter() != paint.getStrokeMiter()) { - *ptr++ = PaintOp_packOp(kMiter_PaintOp); - *ptr++ = castToU32(paint.getStrokeMiter()); - base.setStrokeMiter(paint.getStrokeMiter()); - } - if (base.getTextEncoding() != paint.getTextEncoding()) { - *ptr++ = PaintOp_packOpData(kEncoding_PaintOp, paint.getTextEncoding()); - base.setTextEncoding(paint.getTextEncoding()); - } - if (base.getHinting() != paint.getHinting()) { - *ptr++ = PaintOp_packOpData(kHinting_PaintOp, paint.getHinting()); - base.setHinting(paint.getHinting()); - } - if (base.getTextAlign() != paint.getTextAlign()) { - *ptr++ = PaintOp_packOpData(kAlign_PaintOp, paint.getTextAlign()); - base.setTextAlign(paint.getTextAlign()); - } - if (base.getTextSize() != paint.getTextSize()) { - *ptr++ = PaintOp_packOp(kTextSize_PaintOp); - *ptr++ = castToU32(paint.getTextSize()); - base.setTextSize(paint.getTextSize()); - } - if (base.getTextScaleX() != paint.getTextScaleX()) { - *ptr++ = PaintOp_packOp(kTextScaleX_PaintOp); - *ptr++ = castToU32(paint.getTextScaleX()); - base.setTextScaleX(paint.getTextScaleX()); - } - if (base.getTextSkewX() != paint.getTextSkewX()) { - *ptr++ = PaintOp_packOp(kTextSkewX_PaintOp); - *ptr++ = castToU32(paint.getTextSkewX()); - base.setTextSkewX(paint.getTextSkewX()); - } - - if (!SkTypeface::Equal(base.getTypeface(), paint.getTypeface())) { - if (is_cross_process(fFlags)) { - uint32_t id = this->getTypefaceID(paint.getTypeface()); - *ptr++ = PaintOp_packOpData(kTypeface_PaintOp, id); - } else if (this->needOpBytes(sizeof(void*))) { - // Add to the set for ref counting. - fTypefaceSet.add(paint.getTypeface()); - // It is safe to write the typeface to the stream before the rest - // of the paint unless we ever send a kReset_PaintOp, which we - // currently never do. - this->writeOp(kSetTypeface_DrawOp); - fWriter.writePtr(paint.getTypeface()); - } - base.setTypeface(paint.getTypeface()); - } - - // This is a new paint, so all old flats can be safely purged, if necessary. - fFlattenableHeap.markAllFlatsSafeToDelete(); - for (int i = 0; i < kCount_PaintFlats; i++) { - int index = this->flattenToIndex(get_paintflat(paint, i), (PaintFlats)i); - bool replaced = index < 0; - if (replaced) { - index = ~index; - } - // Store the index of any flat that needs to be kept. 0 means no flat. - if (index > 0) { - fFlattenableHeap.markFlatForKeeping(index); - } - SkASSERT(index >= 0 && index <= fFlatDictionary.count()); - if (index != fCurrFlatIndex[i] || replaced) { - *ptr++ = PaintOp_packOpFlagData(kFlatIndex_PaintOp, i, index); - fCurrFlatIndex[i] = index; - } - } - - size_t size = (char*)ptr - (char*)storage; - if (size && this->needOpBytes(size)) { - this->writeOp(kPaintOp_DrawOp, 0, SkToU32(size)); - fWriter.write(storage, size); - for (size_t i = 0; i < size/4; i++) { -// SkDebugf("[%d] %08X\n", i, storage[i]); - } - } - - // - // Do these after we've written kPaintOp_DrawOp - - if (base.getAnnotation() != paint.getAnnotation()) { - if (nullptr == paint.getAnnotation()) { - if (this->needOpBytes()) { - this->writeOp(kSetAnnotation_DrawOp, 0, 0); - } - } else { - SkWriteBuffer buffer; - paint.getAnnotation()->writeToBuffer(buffer); - const size_t size = buffer.bytesWritten(); - if (this->needOpBytes(size)) { - this->writeOp(kSetAnnotation_DrawOp, 0, SkToU32(size)); - buffer.writeToMemory(fWriter.reserve(size)); - } - } - base.setAnnotation(paint.getAnnotation()); - } -} - -/////////////////////////////////////////////////////////////////////////////// - -#include "SkGPipe.h" - -SkGPipeController::~SkGPipeController() { - SkSafeUnref(fCanvas); -} - -void SkGPipeController::setCanvas(SkGPipeCanvas* canvas) { - SkRefCnt_SafeAssign(fCanvas, canvas); -} - -void SkGPipeController::purgeCaches() -{ - fCanvas->resetImageHeap(); - // Other caches are self-purging with a small MRU pool - // We could purge them as well, but it is not clear whether - // that would be a win. -} - -/////////////////////////////////////////////////////////////////////////////// - -SkGPipeWriter::SkGPipeWriter() -: fWriter(0) { - fCanvas = nullptr; -} - -SkGPipeWriter::~SkGPipeWriter() { - this->endRecording(); -} - -SkCanvas* SkGPipeWriter::startRecording(SkGPipeController* controller, uint32_t flags, - uint32_t width, uint32_t height) { - if (nullptr == fCanvas) { - fWriter.reset(nullptr, 0); - fCanvas = new SkGPipeCanvas(controller, &fWriter, flags, width, height); - } - controller->setCanvas(fCanvas); - return fCanvas; -} - -void SkGPipeWriter::endRecording() { - if (fCanvas) { - fCanvas->finish(true); - fCanvas->unref(); - fCanvas = nullptr; - } -} - -void SkGPipeWriter::flushRecording(bool detachCurrentBlock) { - if (fCanvas) { - fCanvas->flushRecording(detachCurrentBlock); - } -} - -size_t SkGPipeWriter::freeMemoryIfPossible(size_t bytesToFree) { - if (fCanvas) { - return fCanvas->freeMemoryIfPossible(bytesToFree); - } - return 0; -} - -size_t SkGPipeWriter::storageAllocatedForRecording() const { - return nullptr == fCanvas ? 0 : fCanvas->storageAllocatedForRecording(); -} - -/////////////////////////////////////////////////////////////////////////////// - -BitmapShuttle::BitmapShuttle(SkGPipeCanvas* canvas) { - SkASSERT(canvas != nullptr); - fCanvas = canvas; - fCanvas->ref(); -} - -BitmapShuttle::~BitmapShuttle() { - this->removeCanvas(); -} - -bool BitmapShuttle::insert(const SkBitmap& bitmap, int32_t slot) { - SkASSERT(fCanvas != nullptr); - return fCanvas->shuttleBitmap(bitmap, slot); -} - -void BitmapShuttle::removeCanvas() { - if (nullptr == fCanvas) { - return; - } - fCanvas->unref(); - fCanvas = nullptr; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// - -SkImageHeap::SkImageHeap() : fBytesInCache (0) {} - -SkImageHeap::~SkImageHeap() { - fArray.unrefAll(); -} - -void SkImageHeap::reset() { - fArray.unrefAll(); - fArray.rewind(); - fBytesInCache = 0; -} - -const SkImage* SkImageHeap::get(int32_t slot) const { - SkASSERT(slot > 0); - return fArray[slot - 1]; -} - -int32_t SkImageHeap::find(const SkImage* img) const { - int index = fArray.find(img); - if (index >= 0) { - return index + 1; // found - } - return 0; // not found -} - -int32_t SkImageHeap::insert(const SkImage* img) { - int32_t slot = this->find(img); - if (slot) { - return slot; - } - // TODO: SkImage does not expose bytes per pixel, 4 is just a best guess. - fBytesInCache += img->width() * img->height() * 4; - *fArray.append() = SkRef(img); - return fArray.count(); // slot is always index+1 -} - diff --git a/src/pipe/utils/SamplePipeControllers.cpp b/src/pipe/utils/SamplePipeControllers.cpp deleted file mode 100644 index fea9d6842b..0000000000 --- a/src/pipe/utils/SamplePipeControllers.cpp +++ /dev/null @@ -1,115 +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 "SamplePipeControllers.h" - -#include "SkCanvas.h" -#include "SkGPipe.h" -#include "SkMatrix.h" - -PipeController::PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc) -:fReader(target) { - fBlock = nullptr; - fBlockSize = fBytesWritten = 0; - fReader.setBitmapDecoder(proc); -} - -PipeController::~PipeController() { - sk_free(fBlock); -} - -void* PipeController::requestBlock(size_t minRequest, size_t *actual) { - sk_free(fBlock); - fBlockSize = minRequest; - fBlock = sk_malloc_throw(fBlockSize); - fBytesWritten = 0; - *actual = fBlockSize; - return fBlock; -} - -void PipeController::notifyWritten(size_t bytes) { - fStatus = fReader.playback(this->getData(), bytes); - SkASSERT(SkGPipeReader::kError_Status != fStatus); - fBytesWritten += bytes; -} - -//////////////////////////////////////////////////////////////////////////////// - -TiledPipeController::TiledPipeController(const SkBitmap& bitmap, - SkPicture::InstallPixelRefProc proc, - const SkMatrix* initial) -: INHERITED(nullptr, proc) { - int32_t top = 0; - int32_t bottom; - int32_t height = bitmap.height() / NumberOfTiles; - SkIRect rect; - for (int i = 0; i < NumberOfTiles; i++) { - bottom = i + 1 == NumberOfTiles ? bitmap.height() : top + height; - rect.setLTRB(0, top, bitmap.width(), bottom); - top = bottom; - - SkDEBUGCODE(bool extracted = )bitmap.extractSubset(&fBitmaps[i], rect); - SkASSERT(extracted); - SkCanvas* canvas = new SkCanvas(fBitmaps[i]); - if (initial != nullptr) { - canvas->setMatrix(*initial); - } - canvas->translate(SkIntToScalar(-rect.left()), - SkIntToScalar(-rect.top())); - if (0 == i) { - fReader.setCanvas(canvas); - } else { - fReaders[i - 1].setCanvas(canvas); - fReaders[i - 1].setBitmapDecoder(proc); - } - canvas->unref(); - } -} - -void TiledPipeController::notifyWritten(size_t bytes) { - for (int i = 0; i < NumberOfTiles - 1; i++) { - fReaders[i].playback(this->getData(), bytes); - } - this->INHERITED::notifyWritten(bytes); -} - -//////////////////////////////////////////////////////////////////////////////// - -ThreadSafePipeController::ThreadSafePipeController(int numberOfReaders) -: fAllocator(kMinBlockSize) -, fNumberOfReaders(numberOfReaders) { - fBlock = nullptr; - fBytesWritten = 0; -} - -void* ThreadSafePipeController::requestBlock(size_t minRequest, size_t *actual) { - if (fBlock) { - // Save the previous block for later - PipeBlock previousBloc(fBlock, fBytesWritten); - fBlockList.push(previousBloc); - } - int32_t blockSize = SkMax32(SkToS32(minRequest), kMinBlockSize); - fBlock = fAllocator.allocThrow(blockSize); - fBytesWritten = 0; - *actual = blockSize; - return fBlock; -} - -void ThreadSafePipeController::notifyWritten(size_t bytes) { - fBytesWritten += bytes; -} - -void ThreadSafePipeController::draw(SkCanvas* target) { - SkGPipeReader reader(target); - for (int currentBlock = 0; currentBlock < fBlockList.count(); currentBlock++ ) { - reader.playback(fBlockList[currentBlock].fBlock, fBlockList[currentBlock].fBytes); - } - - if (fBlock) { - reader.playback(fBlock, fBytesWritten); - } -} diff --git a/src/pipe/utils/SamplePipeControllers.h b/src/pipe/utils/SamplePipeControllers.h deleted file mode 100644 index b3f057fa8c..0000000000 --- a/src/pipe/utils/SamplePipeControllers.h +++ /dev/null @@ -1,87 +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 "SkChunkAlloc.h" -#include "SkGPipe.h" -#include "SkPicture.h" -#include "SkTDArray.h" - -class SkCanvas; -class SkMatrix; - -class PipeController : public SkGPipeController { -public: - PipeController(SkCanvas* target, SkPicture::InstallPixelRefProc proc = nullptr); - virtual ~PipeController(); - void* requestBlock(size_t minRequest, size_t* actual) override; - void notifyWritten(size_t bytes) override; -protected: - const void* getData() { return (const char*) fBlock + fBytesWritten; } - SkGPipeReader fReader; -private: - void* fBlock; - size_t fBlockSize; - size_t fBytesWritten; - SkGPipeReader::Status fStatus; -}; - -//////////////////////////////////////////////////////////////////////////////// - -class TiledPipeController : public PipeController { -public: - TiledPipeController(const SkBitmap&, SkPicture::InstallPixelRefProc proc = nullptr, - const SkMatrix* initialMatrix = nullptr); - virtual ~TiledPipeController() {}; - void notifyWritten(size_t bytes) override; - int numberOfReaders() const override { return NumberOfTiles; } -private: - enum { - NumberOfTiles = 10 - }; - SkGPipeReader fReaders[NumberOfTiles - 1]; - SkBitmap fBitmaps[NumberOfTiles]; - typedef PipeController INHERITED; -}; - -//////////////////////////////////////////////////////////////////////////////// - -/** - * Borrowed (and modified) from SkDeferredCanvas.cpp::DeferredPipeController. - * Allows playing back from multiple threads, but does not do the threading itself. - */ -class ThreadSafePipeController : public SkGPipeController { -public: - ThreadSafePipeController(int numberOfReaders); - void* requestBlock(size_t minRequest, size_t* actual) override; - void notifyWritten(size_t bytes) override; - int numberOfReaders() const override { return fNumberOfReaders; } - - /** - * Play the stored drawing commands to the specified canvas. If SkGPipeWriter::startRecording - * used the flag SkGPipeWriter::kSimultaneousReaders_Flag, this can be called from different - * threads simultaneously. - */ - void draw(SkCanvas*); -private: - enum { - kMinBlockSize = 4096 - }; - struct PipeBlock { - PipeBlock(void* block, size_t bytes) { fBlock = block, fBytes = bytes; } - // Stream of draw commands written by the SkGPipeWriter. Allocated by fAllocator, which will - // handle freeing it. - void* fBlock; - // Number of bytes that were written to fBlock. - size_t fBytes; - }; - void* fBlock; - size_t fBytesWritten; - SkChunkAlloc fAllocator; - SkTDArray fBlockList; - int fNumberOfReaders; -}; diff --git a/tests/PipeTest.cpp b/tests/PipeTest.cpp deleted file mode 100644 index 00a1a3f201..0000000000 --- a/tests/PipeTest.cpp +++ /dev/null @@ -1,56 +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 "SamplePipeControllers.h" -#include "SkBitmap.h" -#include "SkCanvas.h" -#include "SkGPipe.h" -#include "SkPaint.h" -#include "SkShader.h" -#include "Test.h" - -// Ensures that the pipe gracefully handles drawing an invalid bitmap. -static void testDrawingBadBitmap(SkCanvas* pipeCanvas) { - SkBitmap badBitmap; - badBitmap.setInfo(SkImageInfo::MakeUnknown(5, 5)); - pipeCanvas->drawBitmap(badBitmap, 0, 0); -} - -// Ensure that pipe gracefully handles attempting to draw after endRecording is called on the -// SkGPipeWriter. -static void testDrawingAfterEndRecording(SkCanvas* canvas) { - PipeController pc(canvas); - SkGPipeWriter writer; - SkCanvas* pipeCanvas = writer.startRecording(&pc, SkGPipeWriter::kCrossProcess_Flag); - writer.endRecording(); - - SkBitmap bm; - bm.allocN32Pixels(2, 2); - bm.eraseColor(SK_ColorTRANSPARENT); - - SkShader* shader = SkShader::CreateBitmapShader(bm, SkShader::kClamp_TileMode, - SkShader::kClamp_TileMode); - SkPaint paint; - paint.setShader(shader)->unref(); - pipeCanvas->drawPaint(paint); - - pipeCanvas->drawBitmap(bm, 0, 0); -} - -DEF_TEST(Pipe, reporter) { - SkBitmap bitmap; - bitmap.setInfo(SkImageInfo::MakeN32Premul(64, 64)); - SkCanvas canvas(bitmap); - - PipeController pipeController(&canvas); - SkGPipeWriter writer; - SkCanvas* pipeCanvas = writer.startRecording(&pipeController); - testDrawingBadBitmap(pipeCanvas); - writer.endRecording(); - - testDrawingAfterEndRecording(&canvas); -}