OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBlitter.h" | 8 #include "SkBlitter.h" |
9 #include "SkAntiRun.h" | 9 #include "SkAntiRun.h" |
10 #include "SkColor.h" | 10 #include "SkColor.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 SkBlitter::~SkBlitter() {} | 23 SkBlitter::~SkBlitter() {} |
24 | 24 |
25 bool SkBlitter::isNullBlitter() const { return false; } | 25 bool SkBlitter::isNullBlitter() const { return false; } |
26 | 26 |
27 bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) { | 27 bool SkBlitter::resetShaderContext(const SkShader::ContextRec&) { |
28 return true; | 28 return true; |
29 } | 29 } |
30 | 30 |
31 SkShader::Context* SkBlitter::getShaderContext() const { | 31 SkShader::Context* SkBlitter::getShaderContext() const { |
32 return NULL; | 32 return nullptr; |
33 } | 33 } |
34 | 34 |
35 const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { | 35 const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) { |
36 return NULL; | 36 return nullptr; |
37 } | 37 } |
38 | 38 |
39 void SkBlitter::blitH(int x, int y, int width) { | 39 void SkBlitter::blitH(int x, int y, int width) { |
40 SkDEBUGFAIL("unimplemented"); | 40 SkDEBUGFAIL("unimplemented"); |
41 } | 41 } |
42 | 42 |
43 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], | 43 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], |
44 const int16_t runs[]) { | 44 const int16_t runs[]) { |
45 SkDEBUGFAIL("unimplemented"); | 45 SkDEBUGFAIL("unimplemented"); |
46 } | 46 } |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], | 236 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], |
237 const int16_t runs[]) {} | 237 const int16_t runs[]) {} |
238 | 238 |
239 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} | 239 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {} |
240 | 240 |
241 void SkNullBlitter::blitRect(int x, int y, int width, int height) {} | 241 void SkNullBlitter::blitRect(int x, int y, int width, int height) {} |
242 | 242 |
243 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} | 243 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {} |
244 | 244 |
245 const SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { | 245 const SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) { |
246 return NULL; | 246 return nullptr; |
247 } | 247 } |
248 | 248 |
249 bool SkNullBlitter::isNullBlitter() const { return true; } | 249 bool SkNullBlitter::isNullBlitter() const { return true; } |
250 | 250 |
251 /////////////////////////////////////////////////////////////////////////////// | 251 /////////////////////////////////////////////////////////////////////////////// |
252 | 252 |
253 static int compute_anti_width(const int16_t runs[]) { | 253 static int compute_anti_width(const int16_t runs[]) { |
254 int width = 0; | 254 int width = 0; |
255 | 255 |
256 for (;;) { | 256 for (;;) { |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
546 /////////////////////////////////////////////////////////////////////////////// | 546 /////////////////////////////////////////////////////////////////////////////// |
547 | 547 |
548 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, | 548 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, |
549 const SkIRect* ir) { | 549 const SkIRect* ir) { |
550 if (clip) { | 550 if (clip) { |
551 const SkIRect& clipR = clip->getBounds(); | 551 const SkIRect& clipR = clip->getBounds(); |
552 | 552 |
553 if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) { | 553 if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) { |
554 blitter = &fNullBlitter; | 554 blitter = &fNullBlitter; |
555 } else if (clip->isRect()) { | 555 } else if (clip->isRect()) { |
556 if (ir == NULL || !clipR.contains(*ir)) { | 556 if (ir == nullptr || !clipR.contains(*ir)) { |
557 fRectBlitter.init(blitter, clipR); | 557 fRectBlitter.init(blitter, clipR); |
558 blitter = &fRectBlitter; | 558 blitter = &fRectBlitter; |
559 } | 559 } |
560 } else { | 560 } else { |
561 fRgnBlitter.init(blitter, clip); | 561 fRgnBlitter.init(blitter, clip); |
562 blitter = &fRgnBlitter; | 562 blitter = &fRgnBlitter; |
563 } | 563 } |
564 } | 564 } |
565 return blitter; | 565 return blitter; |
566 } | 566 } |
(...skipping 15 matching lines...) Expand all Loading... |
582 | 582 |
583 size_t contextSize() const override { | 583 size_t contextSize() const override { |
584 size_t size = sizeof(Sk3DShaderContext); | 584 size_t size = sizeof(Sk3DShaderContext); |
585 if (fProxy) { | 585 if (fProxy) { |
586 size += fProxy->contextSize(); | 586 size += fProxy->contextSize(); |
587 } | 587 } |
588 return size; | 588 return size; |
589 } | 589 } |
590 | 590 |
591 Context* onCreateContext(const ContextRec& rec, void* storage) const overrid
e { | 591 Context* onCreateContext(const ContextRec& rec, void* storage) const overrid
e { |
592 SkShader::Context* proxyContext = NULL; | 592 SkShader::Context* proxyContext = nullptr; |
593 if (fProxy) { | 593 if (fProxy) { |
594 char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderConte
xt); | 594 char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderConte
xt); |
595 proxyContext = fProxy->createContext(rec, proxyContextStorage); | 595 proxyContext = fProxy->createContext(rec, proxyContextStorage); |
596 if (!proxyContext) { | 596 if (!proxyContext) { |
597 return NULL; | 597 return nullptr; |
598 } | 598 } |
599 } | 599 } |
600 return new (storage) Sk3DShaderContext(*this, rec, proxyContext); | 600 return new (storage) Sk3DShaderContext(*this, rec, proxyContext); |
601 } | 601 } |
602 | 602 |
603 class Sk3DShaderContext : public SkShader::Context { | 603 class Sk3DShaderContext : public SkShader::Context { |
604 public: | 604 public: |
605 // Calls proxyContext's destructor but will NOT free its memory. | 605 // Calls proxyContext's destructor but will NOT free its memory. |
606 Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec, | 606 Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec, |
607 SkShader::Context* proxyContext) | 607 SkShader::Context* proxyContext) |
608 : INHERITED(shader, rec) | 608 : INHERITED(shader, rec) |
609 , fMask(NULL) | 609 , fMask(nullptr) |
610 , fProxyContext(proxyContext) | 610 , fProxyContext(proxyContext) |
611 { | 611 { |
612 if (!fProxyContext) { | 612 if (!fProxyContext) { |
613 fPMColor = SkPreMultiplyColor(rec.fPaint->getColor()); | 613 fPMColor = SkPreMultiplyColor(rec.fPaint->getColor()); |
614 } | 614 } |
615 } | 615 } |
616 | 616 |
617 virtual ~Sk3DShaderContext() { | 617 virtual ~Sk3DShaderContext() { |
618 if (fProxyContext) { | 618 if (fProxyContext) { |
619 fProxyContext->~Context(); | 619 fProxyContext->~Context(); |
620 } | 620 } |
621 } | 621 } |
622 | 622 |
623 void set3DMask(const SkMask* mask) override { fMask = mask; } | 623 void set3DMask(const SkMask* mask) override { fMask = mask; } |
624 | 624 |
625 void shadeSpan(int x, int y, SkPMColor span[], int count) override { | 625 void shadeSpan(int x, int y, SkPMColor span[], int count) override { |
626 if (fProxyContext) { | 626 if (fProxyContext) { |
627 fProxyContext->shadeSpan(x, y, span, count); | 627 fProxyContext->shadeSpan(x, y, span, count); |
628 } | 628 } |
629 | 629 |
630 if (fMask == NULL) { | 630 if (fMask == nullptr) { |
631 if (fProxyContext == NULL) { | 631 if (fProxyContext == nullptr) { |
632 sk_memset32(span, fPMColor, count); | 632 sk_memset32(span, fPMColor, count); |
633 } | 633 } |
634 return; | 634 return; |
635 } | 635 } |
636 | 636 |
637 SkASSERT(fMask->fBounds.contains(x, y)); | 637 SkASSERT(fMask->fBounds.contains(x, y)); |
638 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); | 638 SkASSERT(fMask->fBounds.contains(x + count - 1, y)); |
639 | 639 |
640 size_t size = fMask->computeImageSize(); | 640 size_t size = fMask->computeImageSize(); |
641 const uint8_t* alpha = fMask->getAddr8(x, y); | 641 const uint8_t* alpha = fMask->getAddr8(x, y); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 } | 754 } |
755 | 755 |
756 void blitMask(const SkMask& mask, const SkIRect& clip) override { | 756 void blitMask(const SkMask& mask, const SkIRect& clip) override { |
757 if (mask.fFormat == SkMask::k3D_Format) { | 757 if (mask.fFormat == SkMask::k3D_Format) { |
758 fShaderContext->set3DMask(&mask); | 758 fShaderContext->set3DMask(&mask); |
759 | 759 |
760 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; | 760 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format; |
761 fProxy->blitMask(mask, clip); | 761 fProxy->blitMask(mask, clip); |
762 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; | 762 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format; |
763 | 763 |
764 fShaderContext->set3DMask(NULL); | 764 fShaderContext->set3DMask(nullptr); |
765 } else { | 765 } else { |
766 fProxy->blitMask(mask, clip); | 766 fProxy->blitMask(mask, clip); |
767 } | 767 } |
768 } | 768 } |
769 | 769 |
770 private: | 770 private: |
771 // Both pointers are unowned. They will be deleted by SkSmallAllocator. | 771 // Both pointers are unowned. They will be deleted by SkSmallAllocator. |
772 SkBlitter* fProxy; | 772 SkBlitter* fProxy; |
773 SkShader::Context* fShaderContext; | 773 SkShader::Context* fShaderContext; |
774 }; | 774 }; |
775 | 775 |
776 /////////////////////////////////////////////////////////////////////////////// | 776 /////////////////////////////////////////////////////////////////////////////// |
777 | 777 |
778 #include "SkCoreBlitters.h" | 778 #include "SkCoreBlitters.h" |
779 | 779 |
780 SkBlitter* SkBlitter::Choose(const SkPixmap& device, | 780 SkBlitter* SkBlitter::Choose(const SkPixmap& device, |
781 const SkMatrix& matrix, | 781 const SkMatrix& matrix, |
782 const SkPaint& origPaint, | 782 const SkPaint& origPaint, |
783 SkTBlitterAllocator* allocator, | 783 SkTBlitterAllocator* allocator, |
784 bool drawCoverage) { | 784 bool drawCoverage) { |
785 SkASSERT(allocator != NULL); | 785 SkASSERT(allocator != nullptr); |
786 | 786 |
787 // which check, in case we're being called by a client with a dummy device | 787 // which check, in case we're being called by a client with a dummy device |
788 // (e.g. they have a bounder that always aborts the draw) | 788 // (e.g. they have a bounder that always aborts the draw) |
789 if (kUnknown_SkColorType == device.colorType() || | 789 if (kUnknown_SkColorType == device.colorType() || |
790 (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) { | 790 (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) { |
791 return allocator->createT<SkNullBlitter>(); | 791 return allocator->createT<SkNullBlitter>(); |
792 } | 792 } |
793 | 793 |
794 SkShader* shader = origPaint.getShader(); | 794 SkShader* shader = origPaint.getShader(); |
795 SkColorFilter* cf = origPaint.getColorFilter(); | 795 SkColorFilter* cf = origPaint.getColorFilter(); |
796 SkXfermode* mode = origPaint.getXfermode(); | 796 SkXfermode* mode = origPaint.getXfermode(); |
797 Sk3DShader* shader3D = NULL; | 797 Sk3DShader* shader3D = nullptr; |
798 | 798 |
799 SkTCopyOnFirstWrite<SkPaint> paint(origPaint); | 799 SkTCopyOnFirstWrite<SkPaint> paint(origPaint); |
800 | 800 |
801 if (origPaint.getMaskFilter() != NULL && | 801 if (origPaint.getMaskFilter() != nullptr && |
802 origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { | 802 origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) { |
803 shader3D = new Sk3DShader(shader); | 803 shader3D = new Sk3DShader(shader); |
804 // we know we haven't initialized lazyPaint yet, so just do it | 804 // we know we haven't initialized lazyPaint yet, so just do it |
805 paint.writable()->setShader(shader3D)->unref(); | 805 paint.writable()->setShader(shader3D)->unref(); |
806 shader = shader3D; | 806 shader = shader3D; |
807 } | 807 } |
808 | 808 |
809 if (mode) { | 809 if (mode) { |
810 bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType(); | 810 bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType(); |
811 switch (SkInterpretXfermode(*paint, deviceIsOpaque)) { | 811 switch (SkInterpretXfermode(*paint, deviceIsOpaque)) { |
812 case kSrcOver_SkXfermodeInterpretation: | 812 case kSrcOver_SkXfermodeInterpretation: |
813 mode = NULL; | 813 mode = nullptr; |
814 paint.writable()->setXfermode(NULL); | 814 paint.writable()->setXfermode(nullptr); |
815 break; | 815 break; |
816 case kSkipDrawing_SkXfermodeInterpretation:{ | 816 case kSkipDrawing_SkXfermodeInterpretation:{ |
817 return allocator->createT<SkNullBlitter>(); | 817 return allocator->createT<SkNullBlitter>(); |
818 } | 818 } |
819 default: | 819 default: |
820 break; | 820 break; |
821 } | 821 } |
822 } | 822 } |
823 | 823 |
824 /* | 824 /* |
825 * If the xfermode is CLEAR, then we can completely ignore the installed | 825 * If the xfermode is CLEAR, then we can completely ignore the installed |
826 * color/shader/colorfilter, and just pretend we're SRC + color==0. This | 826 * color/shader/colorfilter, and just pretend we're SRC + color==0. This |
827 * will fall into our optimizations for SRC mode. | 827 * will fall into our optimizations for SRC mode. |
828 */ | 828 */ |
829 if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) { | 829 if (SkXfermode::IsMode(mode, SkXfermode::kClear_Mode)) { |
830 SkPaint* p = paint.writable(); | 830 SkPaint* p = paint.writable(); |
831 shader = p->setShader(NULL); | 831 shader = p->setShader(nullptr); |
832 cf = p->setColorFilter(NULL); | 832 cf = p->setColorFilter(nullptr); |
833 mode = p->setXfermodeMode(SkXfermode::kSrc_Mode); | 833 mode = p->setXfermodeMode(SkXfermode::kSrc_Mode); |
834 p->setColor(0); | 834 p->setColor(0); |
835 } | 835 } |
836 | 836 |
837 if (NULL == shader) { | 837 if (nullptr == shader) { |
838 if (mode) { | 838 if (mode) { |
839 // xfermodes (and filters) require shaders for our current blitters | 839 // xfermodes (and filters) require shaders for our current blitters |
840 shader = new SkColorShader(paint->getColor()); | 840 shader = new SkColorShader(paint->getColor()); |
841 paint.writable()->setShader(shader)->unref(); | 841 paint.writable()->setShader(shader)->unref(); |
842 paint.writable()->setAlpha(0xFF); | 842 paint.writable()->setAlpha(0xFF); |
843 } else if (cf) { | 843 } else if (cf) { |
844 // if no shader && no xfermode, we just apply the colorfilter to | 844 // if no shader && no xfermode, we just apply the colorfilter to |
845 // our color and move on. | 845 // our color and move on. |
846 SkPaint* writablePaint = paint.writable(); | 846 SkPaint* writablePaint = paint.writable(); |
847 writablePaint->setColor(cf->filterColor(paint->getColor())); | 847 writablePaint->setColor(cf->filterColor(paint->getColor())); |
848 writablePaint->setColorFilter(NULL); | 848 writablePaint->setColorFilter(nullptr); |
849 cf = NULL; | 849 cf = nullptr; |
850 } | 850 } |
851 } | 851 } |
852 | 852 |
853 if (cf) { | 853 if (cf) { |
854 SkASSERT(shader); | 854 SkASSERT(shader); |
855 shader = new SkFilterShader(shader, cf); | 855 shader = new SkFilterShader(shader, cf); |
856 paint.writable()->setShader(shader)->unref(); | 856 paint.writable()->setShader(shader)->unref(); |
857 // blitters should ignore the presence/absence of a filter, since | 857 // blitters should ignore the presence/absence of a filter, since |
858 // if there is one, the shader will take care of it. | 858 // if there is one, the shader will take care of it. |
859 } | 859 } |
860 | 860 |
861 /* | 861 /* |
862 * We create a SkShader::Context object, and store it on the blitter. | 862 * We create a SkShader::Context object, and store it on the blitter. |
863 */ | 863 */ |
864 SkShader::Context* shaderContext = NULL; | 864 SkShader::Context* shaderContext = nullptr; |
865 if (shader) { | 865 if (shader) { |
866 SkShader::ContextRec rec(*paint, matrix, NULL); | 866 SkShader::ContextRec rec(*paint, matrix, nullptr); |
867 size_t contextSize = shader->contextSize(); | 867 size_t contextSize = shader->contextSize(); |
868 if (contextSize) { | 868 if (contextSize) { |
869 // Try to create the ShaderContext | 869 // Try to create the ShaderContext |
870 void* storage = allocator->reserveT<SkShader::Context>(contextSize); | 870 void* storage = allocator->reserveT<SkShader::Context>(contextSize); |
871 shaderContext = shader->createContext(rec, storage); | 871 shaderContext = shader->createContext(rec, storage); |
872 if (!shaderContext) { | 872 if (!shaderContext) { |
873 allocator->freeLast(); | 873 allocator->freeLast(); |
874 return allocator->createT<SkNullBlitter>(); | 874 return allocator->createT<SkNullBlitter>(); |
875 } | 875 } |
876 SkASSERT(shaderContext); | 876 SkASSERT(shaderContext); |
877 SkASSERT((void*) shaderContext == storage); | 877 SkASSERT((void*) shaderContext == storage); |
878 } else { | 878 } else { |
879 return allocator->createT<SkNullBlitter>(); | 879 return allocator->createT<SkNullBlitter>(); |
880 } | 880 } |
881 } | 881 } |
882 | 882 |
883 SkBlitter* blitter = NULL; | 883 SkBlitter* blitter = nullptr; |
884 switch (device.colorType()) { | 884 switch (device.colorType()) { |
885 case kAlpha_8_SkColorType: | 885 case kAlpha_8_SkColorType: |
886 if (drawCoverage) { | 886 if (drawCoverage) { |
887 SkASSERT(NULL == shader); | 887 SkASSERT(nullptr == shader); |
888 SkASSERT(NULL == paint->getXfermode()); | 888 SkASSERT(nullptr == paint->getXfermode()); |
889 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *pai
nt); | 889 blitter = allocator->createT<SkA8_Coverage_Blitter>(device, *pai
nt); |
890 } else if (shader) { | 890 } else if (shader) { |
891 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint
, shaderContext); | 891 blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint
, shaderContext); |
892 } else { | 892 } else { |
893 blitter = allocator->createT<SkA8_Blitter>(device, *paint); | 893 blitter = allocator->createT<SkA8_Blitter>(device, *paint); |
894 } | 894 } |
895 break; | 895 break; |
896 | 896 |
897 case kRGB_565_SkColorType: | 897 case kRGB_565_SkColorType: |
898 blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloca
tor); | 898 blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloca
tor); |
(...skipping 27 matching lines...) Expand all Loading... |
926 } | 926 } |
927 return blitter; | 927 return blitter; |
928 } | 928 } |
929 | 929 |
930 /////////////////////////////////////////////////////////////////////////////// | 930 /////////////////////////////////////////////////////////////////////////////// |
931 | 931 |
932 class SkZeroShaderContext : public SkShader::Context { | 932 class SkZeroShaderContext : public SkShader::Context { |
933 public: | 933 public: |
934 SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec) | 934 SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec) |
935 // Override rec with the identity matrix, so it is guaranteed to be inve
rtible. | 935 // Override rec with the identity matrix, so it is guaranteed to be inve
rtible. |
936 : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), NUL
L)) {} | 936 : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nul
lptr)) {} |
937 | 937 |
938 void shadeSpan(int x, int y, SkPMColor colors[], int count) override { | 938 void shadeSpan(int x, int y, SkPMColor colors[], int count) override { |
939 sk_bzero(colors, count * sizeof(SkPMColor)); | 939 sk_bzero(colors, count * sizeof(SkPMColor)); |
940 } | 940 } |
941 | 941 |
942 private: | 942 private: |
943 typedef SkShader::Context INHERITED; | 943 typedef SkShader::Context INHERITED; |
944 }; | 944 }; |
945 | 945 |
946 SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, | 946 SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, |
(...skipping 13 matching lines...) Expand all Loading... |
960 } | 960 } |
961 | 961 |
962 bool SkShaderBlitter::resetShaderContext(const SkShader::ContextRec& rec) { | 962 bool SkShaderBlitter::resetShaderContext(const SkShader::ContextRec& rec) { |
963 // Only destroy the old context if we have a new one. We need to ensure to h
ave a | 963 // Only destroy the old context if we have a new one. We need to ensure to h
ave a |
964 // live context in fShaderContext because the storage is owned by an SkSmall
Allocator | 964 // live context in fShaderContext because the storage is owned by an SkSmall
Allocator |
965 // outside of this class. | 965 // outside of this class. |
966 // The new context will be of the same size as the old one because we use th
e same | 966 // The new context will be of the same size as the old one because we use th
e same |
967 // shader to create it. It is therefore safe to re-use the storage. | 967 // shader to create it. It is therefore safe to re-use the storage. |
968 fShaderContext->~Context(); | 968 fShaderContext->~Context(); |
969 SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext); | 969 SkShader::Context* ctx = fShader->createContext(rec, (void*)fShaderContext); |
970 if (NULL == ctx) { | 970 if (nullptr == ctx) { |
971 // Need a valid context in fShaderContext's storage, so we can later (or
our caller) call | 971 // Need a valid context in fShaderContext's storage, so we can later (or
our caller) call |
972 // the in-place destructor. | 972 // the in-place destructor. |
973 new (fShaderContext) SkZeroShaderContext(*fShader, rec); | 973 new (fShaderContext) SkZeroShaderContext(*fShader, rec); |
974 return false; | 974 return false; |
975 } | 975 } |
976 return true; | 976 return true; |
977 } | 977 } |
OLD | NEW |