@@ -732,6 +732,39 @@ SkCodec::Result SkWuffsCodec::onIncrementalDecodeTwoPass() {
732732 SkMatrix translate = SkMatrix::MakeTrans (dirty_rect.min_incl_x , dirty_rect.min_incl_y );
733733 draw.drawBitmap (src, translate, nullptr , paint);
734734 }
735+
736+ if (result == SkCodec::kSuccess ) {
737+ // On success, we are done using the "two pass" pixel buffer for this
738+ // frame. We have the option of releasing its memory, but there is a
739+ // trade-off. If decoding a subsequent frame will also need "two pass"
740+ // decoding, it would have to re-allocate the buffer instead of just
741+ // re-using it. On the other hand, if there is no subsequent frame, and
742+ // the SkWuffsCodec object isn't deleted soon, then we are holding
743+ // megabytes of memory longer than we need to.
744+ //
745+ // For example, when the Chromium web browser decodes the <img> tags in
746+ // a HTML page, the SkCodec object can live until navigating away from
747+ // the page, which can be much longer than when the pixels are fully
748+ // decoded, especially for a still (non-animated) image. Even for
749+ // looping animations, caching the decoded frames (at the higher HTML
750+ // renderer layer) may mean that each frame is only decoded once (at
751+ // the lower SkCodec layer), in sequence.
752+ //
753+ // The heuristic we use here is to free the memory if we have decoded
754+ // the last frame of the animation (or, for still images, the only
755+ // frame). The output of the next decode request (if any) should be the
756+ // same either way, but the steady state memory use should hopefully be
757+ // lower than always keeping the fTwoPassPixbufPtr buffer up until the
758+ // SkWuffsCodec destructor runs.
759+ //
760+ // This only applies to "two pass" decoding. "One pass" decoding does
761+ // not allocate, free or otherwise use fTwoPassPixbufPtr.
762+ if (fFramesComplete && (static_cast <size_t >(options ().fFrameIndex ) == fFrames .size () - 1 )) {
763+ fTwoPassPixbufPtr .reset (nullptr );
764+ fTwoPassPixbufLen = 0 ;
765+ }
766+ }
767+
735768 return result;
736769}
737770
0 commit comments