Chromium Code Reviews| 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. | |
|
robertphillips
2014/06/10 21:13:52
Don't think we need this "NULL == result" check
krajcevski
2014/06/10 21:23:23
Done.
| |
| 551 if (NULL == result) { | 556 if (NULL == result) { |
| 552 fAACache.reset(); | 557 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false); |
| 553 return NULL; | 558 if (NULL == result) { |
| 559 fAACache.reset(); | |
| 560 return NULL; | |
| 561 } | |
| 554 } | 562 } |
| 555 | 563 |
| 556 // The top-left of the mask corresponds to the top-left corner of the bounds . | 564 // The top-left of the mask corresponds to the top-left corner of the bounds . |
| 557 SkVector clipToMaskOffset = { | 565 SkVector clipToMaskOffset = { |
| 558 SkIntToScalar(-clipSpaceIBounds.fLeft), | 566 SkIntToScalar(-clipSpaceIBounds.fLeft), |
| 559 SkIntToScalar(-clipSpaceIBounds.fTop) | 567 SkIntToScalar(-clipSpaceIBounds.fTop) |
| 560 }; | 568 }; |
| 561 // The texture may be larger than necessary, this rect represents the part o f the texture | 569 // The texture may be larger than necessary, this rect represents the part o f the texture |
| 562 // we populate with a rasterization of the clip. | 570 // we populate with a rasterization of the clip. |
| 563 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); | 571 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1032 } | 1040 } |
| 1033 } | 1041 } |
| 1034 | 1042 |
| 1035 //////////////////////////////////////////////////////////////////////////////// | 1043 //////////////////////////////////////////////////////////////////////////////// |
| 1036 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, | 1044 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, |
| 1037 GrReducedClip::InitialState initialState, | 1045 GrReducedClip::InitialState initialState, |
| 1038 const GrReducedClip::Elemen tList& elements, | 1046 const GrReducedClip::Elemen tList& elements, |
| 1039 const SkIRect& clipSpaceIBo unds) { | 1047 const SkIRect& clipSpaceIBo unds) { |
| 1040 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 1048 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
| 1041 | 1049 |
| 1042 GrTexture* result; | 1050 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun ds); |
| 1043 if (this->getMaskTexture(elementsGenID, clipSpaceIBounds, &result, true)) { | 1051 if (NULL != result) { |
| 1044 return result; | 1052 return result; |
| 1045 } | 1053 } |
| 1046 | 1054 |
| 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 | 1055 // 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. | 1056 // 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()); | 1057 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); |
| 1055 | 1058 |
| 1056 GrSWMaskHelper helper(this->getContext()); | 1059 GrSWMaskHelper helper(this->getContext()); |
| 1057 | 1060 |
| 1058 SkMatrix matrix; | 1061 SkMatrix matrix; |
| 1059 matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft), | 1062 matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft), |
| 1060 SkIntToScalar(-clipSpaceIBounds.fTop)); | 1063 SkIntToScalar(-clipSpaceIBounds.fTop)); |
| 1061 helper.init(maskSpaceIBounds, &matrix); | 1064 helper.init(maskSpaceIBounds, &matrix); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 1092 // the geometry so they can just be drawn normally | 1095 // the geometry so they can just be drawn normally |
| 1093 if (Element::kRect_Type == element->getType()) { | 1096 if (Element::kRect_Type == element->getType()) { |
| 1094 helper.draw(element->getRect(), op, element->isAA(), 0xFF); | 1097 helper.draw(element->getRect(), op, element->isAA(), 0xFF); |
| 1095 } else { | 1098 } else { |
| 1096 SkPath path; | 1099 SkPath path; |
| 1097 element->asPath(&path); | 1100 element->asPath(&path); |
| 1098 helper.draw(path, stroke, op, element->isAA(), 0xFF); | 1101 helper.draw(path, stroke, op, element->isAA(), 0xFF); |
| 1099 } | 1102 } |
| 1100 } | 1103 } |
| 1101 | 1104 |
| 1105 // Allocate clip mask texture | |
|
robertphillips
2014/06/10 21:13:52
this-> ?
krajcevski
2014/06/10 21:23:23
Done.
| |
| 1106 result = allocMaskTexture(elementsGenID, clipSpaceIBounds, true); | |
| 1107 if (NULL == result) { | |
| 1108 fAACache.reset(); | |
| 1109 return NULL; | |
| 1110 } | |
| 1102 helper.toTexture(result); | 1111 helper.toTexture(result); |
| 1103 | 1112 |
| 1104 fCurrClipMaskType = kAlpha_ClipMaskType; | 1113 fCurrClipMaskType = kAlpha_ClipMaskType; |
| 1105 return result; | 1114 return result; |
| 1106 } | 1115 } |
| 1107 | 1116 |
| 1108 //////////////////////////////////////////////////////////////////////////////// | 1117 //////////////////////////////////////////////////////////////////////////////// |
| 1109 void GrClipMaskManager::releaseResources() { | 1118 void GrClipMaskManager::releaseResources() { |
| 1110 fAACache.releaseResources(); | 1119 fAACache.releaseResources(); |
| 1111 } | 1120 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1132 | 1141 |
| 1133 // TODO: dynamically attach a stencil buffer | 1142 // TODO: dynamically attach a stencil buffer |
| 1134 int stencilBits = 0; | 1143 int stencilBits = 0; |
| 1135 GrStencilBuffer* stencilBuffer = | 1144 GrStencilBuffer* stencilBuffer = |
| 1136 drawState.getRenderTarget()->getStencilBuffer(); | 1145 drawState.getRenderTarget()->getStencilBuffer(); |
| 1137 if (NULL != stencilBuffer) { | 1146 if (NULL != stencilBuffer) { |
| 1138 stencilBits = stencilBuffer->bits(); | 1147 stencilBits = stencilBuffer->bits(); |
| 1139 this->adjustStencilParams(settings, clipMode, stencilBits); | 1148 this->adjustStencilParams(settings, clipMode, stencilBits); |
| 1140 } | 1149 } |
| 1141 } | 1150 } |
| OLD | NEW |