Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(64)

Side by Side Diff: core/fxge/skia/fx_skia_device.cpp

Issue 2064753002: add local caching for skia draws (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: address comments Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/fxge/include/fx_ge.h"
6
7 #if defined(_SKIA_SUPPORT_) 5 #if defined(_SKIA_SUPPORT_)
8 #include <algorithm> 6 #include <algorithm>
9 #include <vector> 7 #include <vector>
10 8
11 #include "core/fxcodec/include/fx_codec.h" 9 #include "core/fxcodec/include/fx_codec.h"
12 10
13 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h" 11 #include "core/fpdfapi/fpdf_page/cpdf_shadingpattern.h"
14 #include "core/fpdfapi/fpdf_page/pageint.h" 12 #include "core/fpdfapi/fpdf_page/pageint.h"
15 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
16 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h" 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h"
17 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h" 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream_acc.h"
18 #include "core/fxge/skia/fx_skia_device.h" 16 #include "core/fxge/skia/fx_skia_device.h"
19 17
20 #include "third_party/skia/include/core/SkCanvas.h" 18 #include "third_party/skia/include/core/SkCanvas.h"
21 #include "third_party/skia/include/core/SkColorFilter.h" 19 #include "third_party/skia/include/core/SkColorFilter.h"
22 #include "third_party/skia/include/core/SkColorPriv.h" 20 #include "third_party/skia/include/core/SkColorPriv.h"
23 #include "third_party/skia/include/core/SkPaint.h" 21 #include "third_party/skia/include/core/SkPaint.h"
24 #include "third_party/skia/include/core/SkPath.h" 22 #include "third_party/skia/include/core/SkPath.h"
25 #include "third_party/skia/include/core/SkPictureRecorder.h" 23 #include "third_party/skia/include/core/SkPictureRecorder.h"
26 #include "third_party/skia/include/core/SkStream.h" 24 #include "third_party/skia/include/core/SkStream.h"
27 #include "third_party/skia/include/core/SkTypeface.h" 25 #include "third_party/skia/include/core/SkTypeface.h"
28 #include "third_party/skia/include/effects/SkDashPathEffect.h" 26 #include "third_party/skia/include/effects/SkDashPathEffect.h"
29 #include "third_party/skia/include/effects/SkGradientShader.h" 27 #include "third_party/skia/include/effects/SkGradientShader.h"
30 #include "third_party/skia/include/pathops/SkPathOps.h" 28 #include "third_party/skia/include/pathops/SkPathOps.h"
31 29
30 #ifdef SK_DEBUG
31 #include "third_party/skia/include/core/SkClipStack.h"
32 #endif
33
32 namespace { 34 namespace {
33 35
34 #define SHOW_SKIA_PATH 0 // set to 1 to print the path contents 36 #define SHOW_SKIA_PATH 0 // set to 1 to print the path contents
35 #define DRAW_SKIA_CLIP 0 // set to 1 to draw a green rectangle around the clip 37 #define DRAW_SKIA_CLIP 0 // set to 1 to draw a green rectangle around the clip
36 38
37 void DebugShowSkiaPath(const SkPath& path) { 39 void DebugShowSkiaPath(const SkPath& path) {
38 #if SHOW_SKIA_PATH 40 #if SHOW_SKIA_PATH
39 char buffer[4096]; 41 char buffer[4096];
40 sk_bzero(buffer, sizeof(buffer)); 42 sk_bzero(buffer, sizeof(buffer));
41 SkMemoryWStream stream(buffer, sizeof(buffer)); 43 SkMemoryWStream stream(buffer, sizeof(buffer));
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 // rectPts[minBounds] and rectPts[maxBounds] and perpendicular to the 471 // rectPts[minBounds] and rectPts[maxBounds] and perpendicular to the
470 // gradient that goes through startEdgePt, endEdgePt. 472 // gradient that goes through startEdgePt, endEdgePt.
471 clip->moveTo(IntersectSides(rectPts[minBounds], slope, startEdgePt)); 473 clip->moveTo(IntersectSides(rectPts[minBounds], slope, startEdgePt));
472 clip->lineTo(IntersectSides(rectPts[minBounds], slope, endEdgePt)); 474 clip->lineTo(IntersectSides(rectPts[minBounds], slope, endEdgePt));
473 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, endEdgePt)); 475 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, endEdgePt));
474 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt)); 476 clip->lineTo(IntersectSides(rectPts[maxBounds], slope, startEdgePt));
475 } 477 }
476 478
477 } // namespace 479 } // namespace
478 480
481 // Encapsulate the state used for successive text and path draws so that
482 // they can be combined.
483 class SkiaState {
484 public:
485 enum class Clip {
486 kSave,
487 kPath,
488 };
489
490 // mark all cached state as uninitialized
491 SkiaState()
492 : m_pFont(nullptr),
493 m_pCache(nullptr),
494 m_fontSize(0),
495 m_fillColor(0),
496 m_strokeColor(0),
497 m_blendType(0),
498 m_commandIndex(0),
499 m_drawText(false),
500 m_drawPath(false),
501 m_fillPath(false),
502 m_debugDisable(false) {}
503
504 bool DrawPath(const CFX_PathData* pPathData,
505 const CFX_Matrix* pMatrix,
506 const CFX_GraphStateData* pDrawState,
507 uint32_t fill_color,
508 uint32_t stroke_color,
509 int fill_mode,
510 int blend_type,
511 CFX_SkiaDeviceDriver* pDriver) {
512 if (m_debugDisable)
513 return false;
514 if (m_commandIndex < m_commands.count())
515 FlushCommands(pDriver);
516 if (m_drawText)
517 FlushText(pDriver);
518 if (m_drawPath && DrawChanged(pMatrix, pDrawState, fill_color, stroke_color,
519 fill_mode, blend_type)) {
520 FlushPath(pDriver);
521 }
522 if (!m_drawPath) {
523 m_skPath.reset();
524 m_fillPath = (fill_mode & 3) && fill_color;
525 m_skPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE
526 ? SkPath::kEvenOdd_FillType
527 : SkPath::kWinding_FillType);
528 m_drawState = *pDrawState;
529 m_fillColor = fill_color;
530 m_strokeColor = stroke_color;
531 m_blendType = blend_type;
532 m_drawMatrix = *pMatrix;
533 }
534 SkPath skPath = BuildPath(pPathData);
535 SkPoint delta;
536 if (MatrixOffset(pMatrix, &delta))
537 skPath.offset(delta.fX, delta.fY);
538 m_skPath.addPath(skPath);
539 m_drawPath = true;
540 return true;
541 }
542
543 void FlushPath(CFX_SkiaDeviceDriver* pDriver) {
544 SkMatrix skMatrix = ToSkMatrix(m_drawMatrix);
545 SkPaint skPaint;
546 skPaint.setAntiAlias(true);
547 int stroke_alpha = FXARGB_A(m_strokeColor);
548 if (stroke_alpha)
549 pDriver->PaintStroke(&skPaint, &m_drawState, skMatrix);
550 SkCanvas* skCanvas = pDriver->SkiaCanvas();
551 skCanvas->save();
552 skCanvas->concat(skMatrix);
553 if (m_fillPath) {
554 SkPath strokePath;
555 const SkPath* fillPath = &m_skPath;
556 if (stroke_alpha) {
557 SkAlpha fillA = SkColorGetA(m_fillColor);
558 SkAlpha strokeA = SkColorGetA(m_strokeColor);
559 if (fillA && fillA < 0xFF && strokeA && strokeA < 0xFF) {
560 skPaint.getFillPath(m_skPath, &strokePath);
561 if (Op(m_skPath, strokePath, SkPathOp::kDifference_SkPathOp,
562 &strokePath)) {
563 fillPath = &strokePath;
564 }
565 }
566 }
567 skPaint.setStyle(SkPaint::kFill_Style);
568 skPaint.setColor(m_fillColor);
569 skCanvas->drawPath(*fillPath, skPaint);
570 }
571 if (stroke_alpha) {
572 DebugShowSkiaPath(m_skPath);
573 DebugShowCanvasMatrix(skCanvas);
574 skPaint.setStyle(SkPaint::kStroke_Style);
575 skPaint.setColor(m_strokeColor);
576 skCanvas->drawPath(m_skPath, skPaint);
577 }
578 skCanvas->restore();
579 m_drawPath = false;
580 }
581
582 bool DrawText(int nChars,
583 const FXTEXT_CHARPOS* pCharPos,
584 CFX_Font* pFont,
585 CFX_FontCache* pCache,
586 const CFX_Matrix* pMatrix,
587 FX_FLOAT font_size,
588 uint32_t color,
589 CFX_SkiaDeviceDriver* pDriver) {
590 if (m_debugDisable)
591 return false;
592 if (m_commandIndex < m_commands.count())
593 FlushCommands(pDriver);
594 if (m_drawPath)
595 FlushPath(pDriver);
596 if (m_drawText && FontChanged(pFont, pCache, pMatrix, font_size, color))
597 FlushText(pDriver);
598 if (!m_drawText) {
599 m_positions.setCount(0);
600 m_glyphs.setCount(0);
601 m_pFont = pFont;
602 m_pCache = pCache;
603 m_fontSize = font_size;
604 m_fillColor = color;
605 m_drawMatrix = *pMatrix;
606 }
607 int count = m_positions.count();
608 m_positions.setCount(nChars + count);
609 m_glyphs.setCount(nChars + count);
610 for (int index = 0; index < nChars; ++index) {
611 const FXTEXT_CHARPOS& cp = pCharPos[index];
612 m_positions[index + count] = {cp.m_OriginX, cp.m_OriginY};
613 m_glyphs[index + count] = (uint16_t)cp.m_GlyphIndex;
614 }
615 SkPoint delta;
616 if (MatrixOffset(pMatrix, &delta)) {
617 for (int index = 0; index < nChars; ++index)
618 m_positions[index + count].offset(delta.fX, -delta.fY);
619 }
620 m_drawText = true;
621 return true;
622 }
623
624 void FlushText(CFX_SkiaDeviceDriver* pDriver) {
625 SkMatrix skMatrix = ToFlippedSkMatrix(m_drawMatrix);
626 SkPaint skPaint;
627 skPaint.setAntiAlias(true);
628 skPaint.setColor(m_fillColor);
629 if (m_pFont->GetFace()) { // exclude placeholder test fonts
630 sk_sp<SkTypeface> typeface(SkSafeRef(m_pCache->GetDeviceCache(m_pFont)));
631 skPaint.setTypeface(typeface);
632 }
633 skPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
634 skPaint.setTextSize(m_fontSize);
635 skPaint.setSubpixelText(true);
636 SkCanvas* skCanvas = pDriver->SkiaCanvas();
637 skCanvas->save();
638 skCanvas->concat(skMatrix);
639 skCanvas->drawPosText(m_glyphs.begin(), m_glyphs.count() * 2,
640 m_positions.begin(), skPaint);
641 skCanvas->restore();
642 m_drawText = false;
643 }
644
645 bool SetClipFill(const CFX_PathData* pPathData,
646 const CFX_Matrix* pMatrix,
647 int fill_mode,
648 CFX_SkiaDeviceDriver* pDriver) {
649 if (m_debugDisable)
650 return false;
651 SkPath skClipPath = BuildPath(pPathData);
652 skClipPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE
653 ? SkPath::kEvenOdd_FillType
654 : SkPath::kWinding_FillType);
655 SkMatrix skMatrix = ToSkMatrix(*pMatrix);
656 skClipPath.transform(skMatrix);
657 return SetClip(skClipPath, pDriver);
658 }
659
660 bool SetClip(const SkPath& skClipPath, CFX_SkiaDeviceDriver* pDriver) {
661 if (m_commandIndex < m_commands.count()) {
662 if (m_commands[m_commandIndex] == Clip::kPath &&
663 m_clips[m_commandIndex] == skClipPath) {
664 ++m_commandIndex;
665 return true;
666 }
667 FlushCommands(pDriver);
668 }
669 Flush(pDriver);
670 m_commands.push(Clip::kPath);
671 ++m_commandIndex;
672 m_clips.push_back(skClipPath);
673 return false;
674 }
675
676 bool SetClipStroke(const CFX_PathData* pPathData,
677 const CFX_Matrix* pMatrix,
678 const CFX_GraphStateData* pGraphState,
679 CFX_SkiaDeviceDriver* pDriver) {
680 if (m_debugDisable)
681 return false;
682 SkPath skPath = BuildPath(pPathData);
683 SkMatrix skMatrix = ToSkMatrix(*pMatrix);
684 SkPaint skPaint;
685 pDriver->PaintStroke(&skPaint, pGraphState, skMatrix);
686 SkPath dst_path;
687 skPaint.getFillPath(skPath, &dst_path);
688 dst_path.transform(skMatrix);
689 return SetClip(dst_path, pDriver);
690 }
691
692 bool MatrixOffset(const CFX_Matrix* pMatrix, SkPoint* delta) {
693 delta->set(pMatrix->e - m_drawMatrix.e, pMatrix->f - m_drawMatrix.f);
694 if (!delta->fX && !delta->fY)
695 return true;
696 SkMatrix drawMatrix = ToSkMatrix(m_drawMatrix);
697 if (!(drawMatrix.getType() & ~SkMatrix::kTranslate_Mask))
698 return true;
699 SkMatrix invDrawMatrix;
700 if (!drawMatrix.invert(&invDrawMatrix))
701 return false;
702 SkMatrix invNewMatrix;
703 SkMatrix newMatrix = ToSkMatrix(*pMatrix);
704 if (!newMatrix.invert(&invNewMatrix))
705 return false;
706 delta->set(invDrawMatrix.getTranslateX() - invNewMatrix.getTranslateX(),
707 invDrawMatrix.getTranslateY() - invNewMatrix.getTranslateY());
708 return true;
709 }
710
711 void FlushCommands(CFX_SkiaDeviceDriver* pDriver) {
712 if (m_commandIndex == m_commands.count())
713 return;
714 if (m_commandIndex < m_commands.count())
715 pDriver->SkiaCanvas()->restore();
716 int index = m_commands.count() - 1;
717 if (m_commandIndex == index && m_commands[index] == Clip::kSave)
718 return;
719 for (; index > m_commandIndex; --index) {
720 if (m_commands[index] == Clip::kSave)
721 pDriver->SkiaCanvas()->restore();
722 }
723
724 if (m_commandIndex > 0)
725 pDriver->SkiaCanvas()->save();
726 while (index > 0 && m_commands[index] != Clip::kSave)
727 --index;
728 while (++index < m_commandIndex) {
729 SkASSERT(m_commands[index] == Clip::kPath);
730 pDriver->SkiaCanvas()->clipPath(m_clips[index], SkRegion::kIntersect_Op,
731 true);
732 }
733 m_commands.setCount(m_commandIndex);
734 m_clips.resize_back(m_commandIndex);
735 }
736
737 // returns true if caller should apply command to skia canvas
738 bool ClipSave(CFX_SkiaDeviceDriver* pDriver) {
739 if (m_debugDisable)
740 return false;
741 int count = m_commands.count();
742 if (m_commandIndex < count) {
743 if (m_commands[m_commandIndex] == Clip::kSave) {
744 ++m_commandIndex;
745 return true;
746 }
747 FlushCommands(pDriver);
748 }
749 Flush(pDriver);
750 m_commands.push(Clip::kSave);
751 ++m_commandIndex;
752 m_clips.push_back(m_skEmptyPath);
753 return false;
754 }
755
756 bool ClipRestore(CFX_SkiaDeviceDriver* pDriver) {
757 if (m_debugDisable)
758 return false;
759 while (m_commandIndex > 0) {
760 if (m_commands[--m_commandIndex] == Clip::kSave)
761 return true;
762 }
763 Flush(pDriver);
764 return false;
765 }
766
767 bool DrawChanged(const CFX_Matrix* pMatrix,
768 const CFX_GraphStateData* pState,
769 uint32_t fill_color,
770 uint32_t stroke_color,
771 int fill_mode,
772 int blend_type) {
773 return MatrixChanged(pMatrix, m_drawMatrix) ||
774 StateChanged(pState, m_drawState) || fill_color != m_fillColor ||
775 stroke_color != m_strokeColor ||
776 ((fill_mode & 3) == FXFILL_ALTERNATE) !=
777 (m_skPath.getFillType() == SkPath::kEvenOdd_FillType) ||
778 blend_type != m_blendType;
779 }
780
781 bool FontChanged(CFX_Font* pFont,
782 CFX_FontCache* pCache,
783 const CFX_Matrix* pMatrix,
784 FX_FLOAT font_size,
785 uint32_t color) {
786 return pFont != m_pFont || pCache != m_pCache ||
787 MatrixChanged(pMatrix, m_drawMatrix) || font_size != m_fontSize ||
788 color != m_fillColor;
789 }
790
791 bool MatrixChanged(const CFX_Matrix* pMatrix, const CFX_Matrix& refMatrix) {
792 return pMatrix->a != refMatrix.a || pMatrix->b != refMatrix.b ||
793 pMatrix->c != refMatrix.c || pMatrix->d != refMatrix.d;
794 }
795
796 bool StateChanged(const CFX_GraphStateData* pState,
797 const CFX_GraphStateData& refState) {
798 return pState->m_LineWidth != refState.m_LineWidth ||
799 pState->m_LineCap != refState.m_LineCap ||
800 pState->m_LineJoin != refState.m_LineJoin ||
801 pState->m_MiterLimit != refState.m_MiterLimit ||
802 DashChanged(pState, refState);
803 }
804
805 bool DashChanged(const CFX_GraphStateData* pState,
806 const CFX_GraphStateData& refState) {
807 if (!pState->m_DashArray && !refState.m_DashArray)
808 return false;
809 if (!pState->m_DashArray || !refState.m_DashArray)
810 return true;
811 if (pState->m_DashPhase != refState.m_DashPhase ||
812 pState->m_DashCount != refState.m_DashCount) {
813 return true;
814 }
815 for (int index = 0; index < pState->m_DashCount; ++index) {
816 if (pState->m_DashArray[index] != refState.m_DashArray[index])
817 return false;
818 }
819 return true;
820 }
821
822 void Flush(CFX_SkiaDeviceDriver* pDriver) {
823 if (m_drawPath)
824 FlushPath(pDriver);
825 if (m_drawText)
826 FlushText(pDriver);
827 }
828
829 #ifdef SK_DEBUG
830 void Dump(const CFX_SkiaDeviceDriver* pDriver) const {
831 SkDebugf("\n\nSkia Save Count %d:\n", pDriver->m_pCanvas->getSaveCount());
832 pDriver->m_pCanvas->getClipStack()->dump();
833 SkDebugf("Cache:\n");
834 for (int index = 0; index < m_commands.count(); ++index) {
835 SkDebugf("%s ", m_commandIndex == index ? "-->" : " ");
836 switch (m_commands[index]) {
837 case Clip::kSave:
838 SkDebugf("Save\n");
839 break;
840 case Clip::kPath:
841 m_clips[index].dump();
842 break;
843 default:
844 SkDebugf("unknown\n");
845 }
846 }
847 if (m_commandIndex == m_commands.count())
848 SkDebugf("-->\n");
849 }
850 #endif
851
852 private:
853 SkTArray<SkPath> m_clips; // stack of clips that may be reused
854 SkTDArray<Clip> m_commands; // stack of clip-related commands
855 SkTDArray<SkPoint> m_positions; // accumulator for text positions
856 SkTDArray<uint16_t> m_glyphs; // accumulator for text glyphs
857 SkPath m_skPath; // accumulator for path contours
858 SkPath m_skEmptyPath; // used as placehold in the clips array
859 CFX_Matrix m_drawMatrix;
860 CFX_GraphStateData m_clipState;
861 CFX_GraphStateData m_drawState;
862 CFX_Matrix m_clipMatrix;
863 CFX_Font* m_pFont;
864 CFX_FontCache* m_pCache;
865 FX_FLOAT m_fontSize;
866 uint32_t m_fillColor;
867 uint32_t m_strokeColor;
868 int m_blendType;
869 int m_commandIndex; // active position in clip command stack
870 bool m_drawText;
871 bool m_drawPath;
872 bool m_fillPath;
873 bool m_debugDisable; // turn off cache for debugging
874 };
875
479 // convert a stroking path to scanlines 876 // convert a stroking path to scanlines
480 void CFX_SkiaDeviceDriver::PaintStroke(SkPaint* spaint, 877 void CFX_SkiaDeviceDriver::PaintStroke(SkPaint* spaint,
481 const CFX_GraphStateData* pGraphState, 878 const CFX_GraphStateData* pGraphState,
482 const SkMatrix& matrix) { 879 const SkMatrix& matrix) {
483 SkPaint::Cap cap; 880 SkPaint::Cap cap;
484 switch (pGraphState->m_LineCap) { 881 switch (pGraphState->m_LineCap) {
485 case CFX_GraphStateData::LineCapRound: 882 case CFX_GraphStateData::LineCapRound:
486 cap = SkPaint::kRound_Cap; 883 cap = SkPaint::kRound_Cap;
487 break; 884 break;
488 case CFX_GraphStateData::LineCapSquare: 885 case CFX_GraphStateData::LineCapSquare:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 spaint->setStrokeJoin(join); 938 spaint->setStrokeJoin(join);
542 } 939 }
543 940
544 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap, 941 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(CFX_DIBitmap* pBitmap,
545 FX_BOOL bRgbByteOrder, 942 FX_BOOL bRgbByteOrder,
546 CFX_DIBitmap* pOriDevice, 943 CFX_DIBitmap* pOriDevice,
547 FX_BOOL bGroupKnockout) 944 FX_BOOL bGroupKnockout)
548 : m_pBitmap(pBitmap), 945 : m_pBitmap(pBitmap),
549 m_pOriDevice(pOriDevice), 946 m_pOriDevice(pOriDevice),
550 m_pRecorder(nullptr), 947 m_pRecorder(nullptr),
948 m_pCache(new SkiaState),
551 m_bRgbByteOrder(bRgbByteOrder), 949 m_bRgbByteOrder(bRgbByteOrder),
552 m_bGroupKnockout(bGroupKnockout) { 950 m_bGroupKnockout(bGroupKnockout) {
553 SkBitmap skBitmap; 951 SkBitmap skBitmap;
554 SkASSERT(pBitmap->GetBPP() == 8 || pBitmap->GetBPP() == 32); 952 SkASSERT(pBitmap->GetBPP() == 8 || pBitmap->GetBPP() == 32);
555 SkImageInfo imageInfo = SkImageInfo::Make( 953 SkImageInfo imageInfo = SkImageInfo::Make(
556 pBitmap->GetWidth(), pBitmap->GetHeight(), 954 pBitmap->GetWidth(), pBitmap->GetHeight(),
557 pBitmap->GetBPP() == 8 ? kAlpha_8_SkColorType : kN32_SkColorType, 955 pBitmap->GetBPP() == 8 ? kAlpha_8_SkColorType : kN32_SkColorType,
558 kOpaque_SkAlphaType); 956 kOpaque_SkAlphaType);
559 skBitmap.installPixels(imageInfo, pBitmap->GetBuffer(), pBitmap->GetPitch(), 957 skBitmap.installPixels(imageInfo, pBitmap->GetBuffer(), pBitmap->GetPitch(),
560 nullptr, /* to do : set color table */ 958 nullptr, /* to do : set color table */
561 nullptr, nullptr); 959 nullptr, nullptr);
562 m_pCanvas = new SkCanvas(skBitmap); 960 m_pCanvas = new SkCanvas(skBitmap);
563 if (m_bGroupKnockout) 961 if (m_bGroupKnockout)
564 SkDebugf(""); // FIXME(caryclark) suppress 'm_bGroupKnockout is unused' 962 SkDebugf(""); // FIXME(caryclark) suppress 'm_bGroupKnockout is unused'
565 } 963 }
566 964
567 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(int size_x, int size_y) 965 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(int size_x, int size_y)
568 : m_pBitmap(nullptr), 966 : m_pBitmap(nullptr),
569 m_pOriDevice(nullptr), 967 m_pOriDevice(nullptr),
570 m_pRecorder(new SkPictureRecorder), 968 m_pRecorder(new SkPictureRecorder),
969 m_pCache(new SkiaState),
571 m_bRgbByteOrder(FALSE), 970 m_bRgbByteOrder(FALSE),
572 m_bGroupKnockout(FALSE) { 971 m_bGroupKnockout(FALSE) {
573 m_pRecorder->beginRecording(SkIntToScalar(size_x), SkIntToScalar(size_y)); 972 m_pRecorder->beginRecording(SkIntToScalar(size_x), SkIntToScalar(size_y));
574 m_pCanvas = m_pRecorder->getRecordingCanvas(); 973 m_pCanvas = m_pRecorder->getRecordingCanvas();
575 } 974 }
576 975
577 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder) 976 CFX_SkiaDeviceDriver::CFX_SkiaDeviceDriver(SkPictureRecorder* recorder)
578 : m_pBitmap(nullptr), 977 : m_pBitmap(nullptr),
579 m_pOriDevice(nullptr), 978 m_pOriDevice(nullptr),
580 m_pRecorder(recorder), 979 m_pRecorder(recorder),
980 m_pCache(new SkiaState),
581 m_bRgbByteOrder(FALSE), 981 m_bRgbByteOrder(FALSE),
582 m_bGroupKnockout(FALSE) { 982 m_bGroupKnockout(FALSE) {
583 m_pCanvas = m_pRecorder->getRecordingCanvas(); 983 m_pCanvas = m_pRecorder->getRecordingCanvas();
584 } 984 }
585 985
586 CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() { 986 CFX_SkiaDeviceDriver::~CFX_SkiaDeviceDriver() {
987 Flush();
587 if (!m_pRecorder) 988 if (!m_pRecorder)
588 delete m_pCanvas; 989 delete m_pCanvas;
589 } 990 }
590 991
992 void CFX_SkiaDeviceDriver::Flush() {
993 m_pCache->Flush(this);
994 m_pCache->FlushCommands(this);
995 }
996
591 FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars, 997 FX_BOOL CFX_SkiaDeviceDriver::DrawDeviceText(int nChars,
592 const FXTEXT_CHARPOS* pCharPos, 998 const FXTEXT_CHARPOS* pCharPos,
593 CFX_Font* pFont, 999 CFX_Font* pFont,
594 CFX_FontCache* pCache, 1000 CFX_FontCache* pCache,
595 const CFX_Matrix* pObject2Device, 1001 const CFX_Matrix* pObject2Device,
596 FX_FLOAT font_size, 1002 FX_FLOAT font_size,
597 uint32_t color) { 1003 uint32_t color) {
1004 if (m_pCache->DrawText(nChars, pCharPos, pFont, pCache, pObject2Device,
1005 font_size, color, this)) {
1006 return TRUE;
1007 }
598 sk_sp<SkTypeface> typeface(SkSafeRef(pCache->GetDeviceCache(pFont))); 1008 sk_sp<SkTypeface> typeface(SkSafeRef(pCache->GetDeviceCache(pFont)));
599 SkPaint paint; 1009 SkPaint paint;
600 paint.setAntiAlias(true); 1010 paint.setAntiAlias(true);
601 paint.setColor(color); 1011 paint.setColor(color);
602 paint.setTypeface(typeface); 1012 paint.setTypeface(typeface);
603 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1013 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
604 paint.setTextSize(font_size); 1014 paint.setTextSize(font_size);
605 paint.setSubpixelText(true); 1015 paint.setSubpixelText(true);
606 m_pCanvas->save(); 1016 m_pCanvas->save();
607 SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device); 1017 SkMatrix skMatrix = ToFlippedSkMatrix(*pObject2Device);
(...skipping 27 matching lines...) Expand all
635 return 0; 1045 return 0;
636 case FXDC_RENDER_CAPS: 1046 case FXDC_RENDER_CAPS:
637 return FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE | 1047 return FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE |
638 FXRC_BLEND_MODE | FXRC_SOFT_CLIP | FXRC_ALPHA_OUTPUT | 1048 FXRC_BLEND_MODE | FXRC_SOFT_CLIP | FXRC_ALPHA_OUTPUT |
639 FXRC_FILLSTROKE_PATH | FXRC_SHADING; 1049 FXRC_FILLSTROKE_PATH | FXRC_SHADING;
640 } 1050 }
641 return 0; 1051 return 0;
642 } 1052 }
643 1053
644 void CFX_SkiaDeviceDriver::SaveState() { 1054 void CFX_SkiaDeviceDriver::SaveState() {
645 m_pCanvas->save(); 1055 if (!m_pCache->ClipSave(this))
1056 m_pCanvas->save();
646 } 1057 }
647 1058
648 void CFX_SkiaDeviceDriver::RestoreState(bool bKeepSaved) { 1059 void CFX_SkiaDeviceDriver::RestoreState(bool bKeepSaved) {
649 m_pCanvas->restore(); 1060 if (!m_pCache->ClipRestore(this))
1061 m_pCanvas->restore();
650 if (bKeepSaved) 1062 if (bKeepSaved)
651 m_pCanvas->save(); 1063 SaveState();
652 } 1064 }
653 1065
654 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill( 1066 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathFill(
655 const CFX_PathData* pPathData, // path info 1067 const CFX_PathData* pPathData, // path info
656 const CFX_Matrix* pObject2Device, // flips object's y-axis 1068 const CFX_Matrix* pObject2Device, // flips object's y-axis
657 int fill_mode // fill mode, WINDING or ALTERNATE 1069 int fill_mode // fill mode, WINDING or ALTERNATE
658 ) { 1070 ) {
1071 CFX_Matrix identity;
1072 const CFX_Matrix* deviceMatrix = pObject2Device ? pObject2Device : &identity;
1073 if (m_pCache->SetClipFill(pPathData, deviceMatrix, fill_mode, this))
1074 return TRUE;
659 if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) { 1075 if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) {
660 CFX_FloatRect rectf; 1076 CFX_FloatRect rectf;
661 if (pPathData->IsRect(pObject2Device, &rectf)) { 1077 if (pPathData->IsRect(deviceMatrix, &rectf)) {
662 rectf.Intersect( 1078 rectf.Intersect(
663 CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH), 1079 CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH),
664 (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT))); 1080 (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
665 // note that PDF's y-axis goes up; Skia's y-axis goes down 1081 // note that PDF's y-axis goes up; Skia's y-axis goes down
666 SkRect skClipRect = 1082 SkRect skClipRect =
667 SkRect::MakeLTRB(rectf.left, rectf.bottom, rectf.right, rectf.top); 1083 SkRect::MakeLTRB(rectf.left, rectf.bottom, rectf.right, rectf.top);
668 DebugDrawSkiaClipRect(m_pCanvas, skClipRect); 1084 DebugDrawSkiaClipRect(m_pCanvas, skClipRect);
669 m_pCanvas->clipRect(skClipRect); 1085 m_pCanvas->clipRect(skClipRect, SkRegion::kIntersect_Op, true);
670 return TRUE; 1086 return TRUE;
671 } 1087 }
672 } 1088 }
673 SkPath skClipPath = BuildPath(pPathData); 1089 SkPath skClipPath = BuildPath(pPathData);
674 skClipPath.setFillType((fill_mode & 3) == FXFILL_WINDING 1090 skClipPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE
675 ? SkPath::kWinding_FillType 1091 ? SkPath::kEvenOdd_FillType
676 : SkPath::kEvenOdd_FillType); 1092 : SkPath::kWinding_FillType);
677 SkMatrix skMatrix = ToSkMatrix(*pObject2Device); 1093 SkMatrix skMatrix = ToSkMatrix(*deviceMatrix);
678 skClipPath.transform(skMatrix); 1094 skClipPath.transform(skMatrix);
679 DebugShowSkiaPath(skClipPath); 1095 DebugShowSkiaPath(skClipPath);
680 DebugDrawSkiaClipPath(m_pCanvas, skClipPath); 1096 DebugDrawSkiaClipPath(m_pCanvas, skClipPath);
681 m_pCanvas->clipPath(skClipPath); 1097 m_pCanvas->clipPath(skClipPath, SkRegion::kIntersect_Op, true);
682 1098
683 return TRUE; 1099 return TRUE;
684 } 1100 }
685 1101
686 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke( 1102 FX_BOOL CFX_SkiaDeviceDriver::SetClip_PathStroke(
687 const CFX_PathData* pPathData, // path info 1103 const CFX_PathData* pPathData, // path info
688 const CFX_Matrix* pObject2Device, // optional transformation 1104 const CFX_Matrix* pObject2Device, // optional transformation
689 const CFX_GraphStateData* pGraphState // graphic state, for pen attributes 1105 const CFX_GraphStateData* pGraphState // graphic state, for pen attributes
690 ) { 1106 ) {
1107 if (m_pCache->SetClipStroke(pPathData, pObject2Device, pGraphState, this))
1108 return TRUE;
691 // build path data 1109 // build path data
692 SkPath skPath = BuildPath(pPathData); 1110 SkPath skPath = BuildPath(pPathData);
693 skPath.setFillType(SkPath::kWinding_FillType);
694
695 SkMatrix skMatrix = ToSkMatrix(*pObject2Device); 1111 SkMatrix skMatrix = ToSkMatrix(*pObject2Device);
696 SkPaint spaint; 1112 SkPaint skPaint;
697 PaintStroke(&spaint, pGraphState, skMatrix); 1113 PaintStroke(&skPaint, pGraphState, skMatrix);
698 SkPath dst_path; 1114 SkPath dst_path;
699 spaint.getFillPath(skPath, &dst_path); 1115 skPaint.getFillPath(skPath, &dst_path);
700 dst_path.transform(skMatrix); 1116 dst_path.transform(skMatrix);
701 DebugDrawSkiaClipPath(m_pCanvas, dst_path); 1117 DebugDrawSkiaClipPath(m_pCanvas, dst_path);
702 m_pCanvas->clipPath(dst_path); 1118 m_pCanvas->clipPath(dst_path, SkRegion::kIntersect_Op, true);
703 return TRUE; 1119 return TRUE;
704 } 1120 }
705 1121
706 FX_BOOL CFX_SkiaDeviceDriver::DrawPath( 1122 FX_BOOL CFX_SkiaDeviceDriver::DrawPath(
707 const CFX_PathData* pPathData, // path info 1123 const CFX_PathData* pPathData, // path info
708 const CFX_Matrix* pObject2Device, // optional transformation 1124 const CFX_Matrix* pObject2Device, // optional transformation
709 const CFX_GraphStateData* pGraphState, // graphic state, for pen attributes 1125 const CFX_GraphStateData* pGraphState, // graphic state, for pen attributes
710 uint32_t fill_color, // fill color 1126 uint32_t fill_color, // fill color
711 uint32_t stroke_color, // stroke color 1127 uint32_t stroke_color, // stroke color
712 int fill_mode, // fill mode, WINDING or ALTERNATE. 0 for not filled 1128 int fill_mode, // fill mode, WINDING or ALTERNATE. 0 for not filled
713 int blend_type) { 1129 int blend_type) {
1130 if (m_pCache->DrawPath(pPathData, pObject2Device, pGraphState, fill_color,
1131 stroke_color, fill_mode, blend_type, this)) {
1132 return TRUE;
1133 }
714 SkIRect rect; 1134 SkIRect rect;
715 rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH), 1135 rect.set(0, 0, GetDeviceCaps(FXDC_PIXEL_WIDTH),
716 GetDeviceCaps(FXDC_PIXEL_HEIGHT)); 1136 GetDeviceCaps(FXDC_PIXEL_HEIGHT));
717 SkMatrix skMatrix; 1137 SkMatrix skMatrix;
718 if (pObject2Device) 1138 if (pObject2Device)
719 skMatrix = ToSkMatrix(*pObject2Device); 1139 skMatrix = ToSkMatrix(*pObject2Device);
720 else 1140 else
721 skMatrix.setIdentity(); 1141 skMatrix.setIdentity();
722 SkPaint skPaint; 1142 SkPaint skPaint;
723 skPaint.setAntiAlias(true); 1143 skPaint.setAntiAlias(true);
724 int stroke_alpha = FXARGB_A(stroke_color); 1144 int stroke_alpha = FXARGB_A(stroke_color);
725 if (pGraphState && stroke_alpha) 1145 if (pGraphState && stroke_alpha)
726 PaintStroke(&skPaint, pGraphState, skMatrix); 1146 PaintStroke(&skPaint, pGraphState, skMatrix);
727 SkPath skPath = BuildPath(pPathData); 1147 SkPath skPath = BuildPath(pPathData);
728 m_pCanvas->save(); 1148 m_pCanvas->save();
729 m_pCanvas->concat(skMatrix); 1149 m_pCanvas->concat(skMatrix);
730 if ((fill_mode & 3) && fill_color) { 1150 if ((fill_mode & 3) && fill_color) {
731 skPath.setFillType((fill_mode & 3) == FXFILL_WINDING 1151 skPath.setFillType((fill_mode & 3) == FXFILL_ALTERNATE
732 ? SkPath::kWinding_FillType 1152 ? SkPath::kEvenOdd_FillType
733 : SkPath::kEvenOdd_FillType); 1153 : SkPath::kWinding_FillType);
734 SkPath strokePath; 1154 SkPath strokePath;
735 const SkPath* fillPath = &skPath; 1155 const SkPath* fillPath = &skPath;
736 if (pGraphState && stroke_alpha) { 1156 if (pGraphState && stroke_alpha) {
737 SkAlpha fillA = SkColorGetA(fill_color); 1157 SkAlpha fillA = SkColorGetA(fill_color);
738 SkAlpha strokeA = SkColorGetA(stroke_color); 1158 SkAlpha strokeA = SkColorGetA(stroke_color);
739 if (fillA && fillA < 0xFF && strokeA && strokeA < 0xFF) { 1159 if (fillA && fillA < 0xFF && strokeA && strokeA < 0xFF) {
740 skPaint.getFillPath(skPath, &strokePath); 1160 skPaint.getFillPath(skPath, &strokePath);
741 if (Op(skPath, strokePath, SkPathOp::kDifference_SkPathOp, 1161 if (Op(skPath, strokePath, SkPathOp::kDifference_SkPathOp,
742 &strokePath)) { 1162 &strokePath)) {
743 fillPath = &strokePath; 1163 fillPath = &strokePath;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 skClip.transform(skMatrix); 1322 skClip.transform(skMatrix);
903 } 1323 }
904 SkMatrix inverse; 1324 SkMatrix inverse;
905 if (!skMatrix.invert(&inverse)) 1325 if (!skMatrix.invert(&inverse))
906 return false; 1326 return false;
907 skPath.addRect(skRect); 1327 skPath.addRect(skRect);
908 skPath.transform(inverse); 1328 skPath.transform(inverse);
909 } 1329 }
910 m_pCanvas->save(); 1330 m_pCanvas->save();
911 if (!skClip.isEmpty()) 1331 if (!skClip.isEmpty())
912 m_pCanvas->clipPath(skClip); 1332 m_pCanvas->clipPath(skClip, SkRegion::kIntersect_Op, true);
913 m_pCanvas->concat(skMatrix); 1333 m_pCanvas->concat(skMatrix);
914 m_pCanvas->drawPath(skPath, paint); 1334 m_pCanvas->drawPath(skPath, paint);
915 m_pCanvas->restore(); 1335 m_pCanvas->restore();
916 return true; 1336 return true;
917 } 1337 }
918 1338
919 uint8_t* CFX_SkiaDeviceDriver::GetBuffer() const { 1339 uint8_t* CFX_SkiaDeviceDriver::GetBuffer() const {
920 return m_pBitmap->GetBuffer(); 1340 return m_pBitmap->GetBuffer();
921 } 1341 }
922 1342
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
993 uint32_t flags, 1413 uint32_t flags,
994 int blend_type) { 1414 int blend_type) {
995 if (!m_pBitmap->GetBuffer()) 1415 if (!m_pBitmap->GetBuffer())
996 return TRUE; 1416 return TRUE;
997 CFX_Matrix m(dest_width, 0, 0, -dest_height, dest_left, 1417 CFX_Matrix m(dest_width, 0, 0, -dest_height, dest_left,
998 dest_top + dest_height); 1418 dest_top + dest_height);
999 1419
1000 m_pCanvas->save(); 1420 m_pCanvas->save();
1001 SkRect skClipRect = SkRect::MakeLTRB(pClipRect->left, pClipRect->bottom, 1421 SkRect skClipRect = SkRect::MakeLTRB(pClipRect->left, pClipRect->bottom,
1002 pClipRect->right, pClipRect->top); 1422 pClipRect->right, pClipRect->top);
1003 m_pCanvas->clipRect(skClipRect); 1423 m_pCanvas->clipRect(skClipRect, SkRegion::kIntersect_Op, true);
1004 void* dummy; 1424 void* dummy;
1005 FX_BOOL result = StartDIBits(pSource, 0xFF, argb, &m, 0, dummy, blend_type); 1425 FX_BOOL result = StartDIBits(pSource, 0xFF, argb, &m, 0, dummy, blend_type);
1006 m_pCanvas->restore(); 1426 m_pCanvas->restore();
1007 1427
1008 return result; 1428 return result;
1009 } 1429 }
1010 1430
1011 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource, 1431 FX_BOOL CFX_SkiaDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
1012 int bitmap_alpha, 1432 int bitmap_alpha,
1013 uint32_t argb, 1433 uint32_t argb,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 SkImageInfo unpremultipliedInfo = 1538 SkImageInfo unpremultipliedInfo =
1119 SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType); 1539 SkImageInfo::Make(width, height, kN32_SkColorType, kUnpremul_SkAlphaType);
1120 SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes); 1540 SkPixmap unpremultiplied(unpremultipliedInfo, buffer, rowBytes);
1121 SkImageInfo premultipliedInfo = 1541 SkImageInfo premultipliedInfo =
1122 SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); 1542 SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType);
1123 SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes); 1543 SkPixmap premultiplied(premultipliedInfo, buffer, rowBytes);
1124 unpremultiplied.readPixels(premultiplied); 1544 unpremultiplied.readPixels(premultiplied);
1125 DebugVerifyBitmapIsPreMultiplied(buffer, width, height); 1545 DebugVerifyBitmapIsPreMultiplied(buffer, width, height);
1126 } 1546 }
1127 1547
1548 void CFX_SkiaDeviceDriver::Dump() const {
1549 #ifdef SK_DEBUG
1550 if (m_pCache)
1551 m_pCache->Dump(this);
1552 #endif
1553 }
1554
1128 CFX_FxgeDevice::CFX_FxgeDevice() { 1555 CFX_FxgeDevice::CFX_FxgeDevice() {
1129 m_bOwnedBitmap = FALSE; 1556 m_bOwnedBitmap = FALSE;
1130 } 1557 }
1131 1558
1132 SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) { 1559 SkPictureRecorder* CFX_FxgeDevice::CreateRecorder(int size_x, int size_y) {
1133 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y); 1560 CFX_SkiaDeviceDriver* skDriver = new CFX_SkiaDeviceDriver(size_x, size_y);
1134 SetDeviceDriver(skDriver); 1561 SetDeviceDriver(skDriver);
1135 return skDriver->GetRecorder(); 1562 return skDriver->GetRecorder();
1136 } 1563 }
1137 1564
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 CFX_FxgeDevice::~CFX_FxgeDevice() { 1601 CFX_FxgeDevice::~CFX_FxgeDevice() {
1175 if (m_bOwnedBitmap && GetBitmap()) 1602 if (m_bOwnedBitmap && GetBitmap())
1176 delete GetBitmap(); 1603 delete GetBitmap();
1177 } 1604 }
1178 1605
1179 void CFX_FxgeDevice::PreMultiply() { 1606 void CFX_FxgeDevice::PreMultiply() {
1180 (static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()))->PreMultiply(); 1607 (static_cast<CFX_SkiaDeviceDriver*>(GetDeviceDriver()))->PreMultiply();
1181 } 1608 }
1182 1609
1183 #endif 1610 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698