OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrClipMaskManager.h" | 9 #include "GrClipMaskManager.h" |
10 #include "GrAAConvexPathRenderer.h" | 10 #include "GrAAConvexPathRenderer.h" |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 GrTextureDesc desc; | 495 GrTextureDesc desc; |
496 desc.fFlags = kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit; | 496 desc.fFlags = kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit; |
497 desc.fWidth = width; | 497 desc.fWidth = width; |
498 desc.fHeight = height; | 498 desc.fHeight = height; |
499 desc.fConfig = kAlpha_8_GrPixelConfig; | 499 desc.fConfig = kAlpha_8_GrPixelConfig; |
500 | 500 |
501 temp->set(this->getContext(), desc); | 501 temp->set(this->getContext(), desc); |
502 } | 502 } |
503 | 503 |
504 //////////////////////////////////////////////////////////////////////////////// | 504 //////////////////////////////////////////////////////////////////////////////// |
505 // Handles caching & allocation (if needed) of a clip alpha-mask texture for bot
h the sw-upload | 505 // Return the texture currently in the cache if it exists. Otherwise, return NUL
L |
506 // or gpu-rendered cases. Returns true if there is no more work to be done (i.e.
, we got a cache | 506 GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID, |
507 // hit) | 507 const SkIRect& clipSpaceIBoun
ds) { |
508 bool GrClipMaskManager::getMaskTexture(int32_t elementsGenID, | |
509 const SkIRect& clipSpaceIBounds, | |
510 GrTexture** result, | |
511 bool willUpload) { | |
512 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds); | 508 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds); |
513 if (!cached) { | 509 if (!cached) { |
514 | 510 return NULL; |
515 // There isn't a suitable entry in the cache so we create a new texture
to store the mask. | |
516 // Since we are setting up the cache we know the last lookup was a miss.
Free up the | |
517 // currently cached mask so it can be reused. | |
518 fAACache.reset(); | |
519 | |
520 GrTextureDesc desc; | |
521 desc.fFlags = willUpload ? kNone_GrTextureFlags : kRenderTarget_GrTextur
eFlagBit; | |
522 desc.fWidth = clipSpaceIBounds.width(); | |
523 desc.fHeight = clipSpaceIBounds.height(); | |
524 desc.fConfig = kRGBA_8888_GrPixelConfig; | |
525 if (willUpload || this->getContext()->isConfigRenderable(kAlpha_8_GrPixe
lConfig, false)) { | |
526 // We would always like A8 but it isn't supported on all platforms | |
527 desc.fConfig = kAlpha_8_GrPixelConfig; | |
528 } | |
529 | |
530 fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds); | |
531 } | 511 } |
532 | 512 |
533 *result = fAACache.getLastMask(); | 513 return fAACache.getLastMask(); |
534 return cached; | |
535 } | 514 } |
536 | 515 |
537 //////////////////////////////////////////////////////////////////////////////// | 516 //////////////////////////////////////////////////////////////////////////////// |
| 517 // Allocate a texture in the texture cache. This function returns the texture |
| 518 // allocated (or NULL on error). |
| 519 GrTexture* GrClipMaskManager::allocMaskTexture(int32_t elementsGenID, |
| 520 const SkIRect& clipSpaceIBounds, |
| 521 bool willUpload) { |
| 522 // Since we are setting up the cache we should free up the |
| 523 // currently cached mask so it can be reused. |
| 524 fAACache.reset(); |
| 525 |
| 526 GrTextureDesc desc; |
| 527 desc.fFlags = willUpload ? kNone_GrTextureFlags : kRenderTarget_GrTextureFla
gBit; |
| 528 desc.fWidth = clipSpaceIBounds.width(); |
| 529 desc.fHeight = clipSpaceIBounds.height(); |
| 530 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 531 if (willUpload || this->getContext()->isConfigRenderable(kAlpha_8_GrPixelCon
fig, false)) { |
| 532 // We would always like A8 but it isn't supported on all platforms |
| 533 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 534 } |
| 535 |
| 536 fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds); |
| 537 return fAACache.getLastMask(); |
| 538 } |
| 539 |
| 540 //////////////////////////////////////////////////////////////////////////////// |
538 // Create a 8-bit clip mask in alpha | 541 // Create a 8-bit clip mask in alpha |
539 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 542 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, |
540 InitialState initialState, | 543 InitialState initialState, |
541 const ElementList& elements, | 544 const ElementList& elements, |
542 const SkIRect& clipSpaceIBound
s) { | 545 const SkIRect& clipSpaceIBound
s) { |
543 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 546 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
544 | 547 |
545 GrTexture* result; | 548 // First, check for cached texture |
546 if (this->getMaskTexture(elementsGenID, clipSpaceIBounds, &result, false)) { | 549 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun
ds); |
| 550 if (NULL != result) { |
547 fCurrClipMaskType = kAlpha_ClipMaskType; | 551 fCurrClipMaskType = kAlpha_ClipMaskType; |
548 return result; | 552 return result; |
549 } | 553 } |
550 | 554 |
| 555 // There's no texture in the cache. Let's try to allocate it then. |
| 556 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false); |
551 if (NULL == result) { | 557 if (NULL == result) { |
552 fAACache.reset(); | 558 fAACache.reset(); |
553 return NULL; | 559 return NULL; |
554 } | 560 } |
555 | 561 |
556 // The top-left of the mask corresponds to the top-left corner of the bounds
. | 562 // The top-left of the mask corresponds to the top-left corner of the bounds
. |
557 SkVector clipToMaskOffset = { | 563 SkVector clipToMaskOffset = { |
558 SkIntToScalar(-clipSpaceIBounds.fLeft), | 564 SkIntToScalar(-clipSpaceIBounds.fLeft), |
559 SkIntToScalar(-clipSpaceIBounds.fTop) | 565 SkIntToScalar(-clipSpaceIBounds.fTop) |
560 }; | 566 }; |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 } | 1038 } |
1033 } | 1039 } |
1034 | 1040 |
1035 //////////////////////////////////////////////////////////////////////////////// | 1041 //////////////////////////////////////////////////////////////////////////////// |
1036 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 1042 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, |
1037 GrReducedClip::InitialState
initialState, | 1043 GrReducedClip::InitialState
initialState, |
1038 const GrReducedClip::Elemen
tList& elements, | 1044 const GrReducedClip::Elemen
tList& elements, |
1039 const SkIRect& clipSpaceIBo
unds) { | 1045 const SkIRect& clipSpaceIBo
unds) { |
1040 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 1046 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
1041 | 1047 |
1042 GrTexture* result; | 1048 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun
ds); |
1043 if (this->getMaskTexture(elementsGenID, clipSpaceIBounds, &result, true)) { | 1049 if (NULL != result) { |
1044 return result; | 1050 return result; |
1045 } | 1051 } |
1046 | 1052 |
1047 if (NULL == result) { | |
1048 fAACache.reset(); | |
1049 return NULL; | |
1050 } | |
1051 | |
1052 // The mask texture may be larger than necessary. We round out the clip spac
e bounds and pin | 1053 // The mask texture may be larger than necessary. We round out the clip spac
e bounds and pin |
1053 // the top left corner of the resulting rect to the top left of the texture. | 1054 // the top left corner of the resulting rect to the top left of the texture. |
1054 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 1055 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
1055 | 1056 |
1056 GrSWMaskHelper helper(this->getContext()); | 1057 GrSWMaskHelper helper(this->getContext()); |
1057 | 1058 |
1058 SkMatrix matrix; | 1059 SkMatrix matrix; |
1059 matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft), | 1060 matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft), |
1060 SkIntToScalar(-clipSpaceIBounds.fTop)); | 1061 SkIntToScalar(-clipSpaceIBounds.fTop)); |
1061 helper.init(maskSpaceIBounds, &matrix); | 1062 helper.init(maskSpaceIBounds, &matrix); |
(...skipping 30 matching lines...) Expand all Loading... |
1092 // the geometry so they can just be drawn normally | 1093 // the geometry so they can just be drawn normally |
1093 if (Element::kRect_Type == element->getType()) { | 1094 if (Element::kRect_Type == element->getType()) { |
1094 helper.draw(element->getRect(), op, element->isAA(), 0xFF); | 1095 helper.draw(element->getRect(), op, element->isAA(), 0xFF); |
1095 } else { | 1096 } else { |
1096 SkPath path; | 1097 SkPath path; |
1097 element->asPath(&path); | 1098 element->asPath(&path); |
1098 helper.draw(path, stroke, op, element->isAA(), 0xFF); | 1099 helper.draw(path, stroke, op, element->isAA(), 0xFF); |
1099 } | 1100 } |
1100 } | 1101 } |
1101 | 1102 |
| 1103 // Allocate clip mask texture |
| 1104 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, true); |
| 1105 if (NULL == result) { |
| 1106 fAACache.reset(); |
| 1107 return NULL; |
| 1108 } |
1102 helper.toTexture(result); | 1109 helper.toTexture(result); |
1103 | 1110 |
1104 fCurrClipMaskType = kAlpha_ClipMaskType; | 1111 fCurrClipMaskType = kAlpha_ClipMaskType; |
1105 return result; | 1112 return result; |
1106 } | 1113 } |
1107 | 1114 |
1108 //////////////////////////////////////////////////////////////////////////////// | 1115 //////////////////////////////////////////////////////////////////////////////// |
1109 void GrClipMaskManager::releaseResources() { | 1116 void GrClipMaskManager::releaseResources() { |
1110 fAACache.releaseResources(); | 1117 fAACache.releaseResources(); |
1111 } | 1118 } |
(...skipping 20 matching lines...) Expand all Loading... |
1132 | 1139 |
1133 // TODO: dynamically attach a stencil buffer | 1140 // TODO: dynamically attach a stencil buffer |
1134 int stencilBits = 0; | 1141 int stencilBits = 0; |
1135 GrStencilBuffer* stencilBuffer = | 1142 GrStencilBuffer* stencilBuffer = |
1136 drawState.getRenderTarget()->getStencilBuffer(); | 1143 drawState.getRenderTarget()->getStencilBuffer(); |
1137 if (NULL != stencilBuffer) { | 1144 if (NULL != stencilBuffer) { |
1138 stencilBits = stencilBuffer->bits(); | 1145 stencilBits = stencilBuffer->bits(); |
1139 this->adjustStencilParams(settings, clipMode, stencilBits); | 1146 this->adjustStencilParams(settings, clipMode, stencilBits); |
1140 } | 1147 } |
1141 } | 1148 } |
OLD | NEW |