1 /* 2 Copyright 2011 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #ifndef GrContext_impl_DEFINED 18 #define GrContext_impl_DEFINED 19 20 struct GrContext::OffscreenRecord { 21 OffscreenRecord() { fEntry0 = NULL; fEntry1 = NULL; } 22 ~OffscreenRecord() { GrAssert(NULL == fEntry0 && NULL == fEntry1); } 23 24 enum Downsample { 25 k4x4TwoPass_Downsample, 26 k4x4SinglePass_Downsample, 27 kFSAA_Downsample 28 } fDownsample; 29 GrTextureEntry* fEntry0; 30 GrTextureEntry* fEntry1; 31 GrDrawTarget::SavedDrawState fSavedState; 32 }; 33 34 template <typename POS_SRC, typename TEX_SRC, 35 typename COL_SRC, typename IDX_SRC> 36 inline void GrContext::drawCustomVertices(const GrPaint& paint, 37 GrPrimitiveType primitiveType, 38 const POS_SRC& posSrc, 39 const TEX_SRC* texCoordSrc, 40 const COL_SRC* colorSrc, 41 const IDX_SRC* idxSrc) { 42 43 GrDrawTarget::AutoReleaseGeometry geo; 44 45 GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); 46 47 bool hasTexCoords[GrPaint::kTotalStages] = { 48 NULL != texCoordSrc, // texCoordSrc provides explicit stage 0 coords 49 0 // remaining stages use positions 50 }; 51 GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); 52 53 if (NULL != colorSrc) { 54 layout |= GrDrawTarget::kColor_VertexLayoutBit; 55 } 56 57 int vertexCount = posSrc.count(); 58 int indexCount = (NULL != idxSrc) ? idxSrc->count() : 0; 59 60 if (!geo.set(target, layout, vertexCount, indexCount)) { 61 GrPrintf("Failed to get space for vertices!"); 62 return; 63 } 64 65 int texOffsets[GrDrawTarget::kMaxTexCoords]; 66 int colorOffset; 67 int vsize = GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, 68 texOffsets, 69 &colorOffset); 70 void* curVertex = geo.vertices(); 71 72 for (int i = 0; i < vertexCount; ++i) { 73 posSrc.writeValue(i, (GrPoint*)curVertex); 74 75 if (texOffsets[0] > 0) { 76 texCoordSrc->writeValue(i, (GrPoint*)((intptr_t)curVertex + texOffsets[0])); 77 } 78 if (colorOffset > 0) { 79 colorSrc->writeValue(i, (GrColor*)((intptr_t)curVertex + colorOffset)); 80 } 81 curVertex = (void*)((intptr_t)curVertex + vsize); 82 } 83 84 uint16_t* indices = (uint16_t*) geo.indices(); 85 for (int i = 0; i < indexCount; ++i) { 86 idxSrc->writeValue(i, indices + i); 87 } 88 89 bool doAA = false; 90 OffscreenRecord record; 91 GrIRect bounds; 92 93 if (-1 == texOffsets[0] && -1 == colorOffset && 94 this->doOffscreenAA(target, paint, GrIsPrimTypeLines(primitiveType))) { 95 GrRect b; 96 b.setBounds(geo.positions(), vertexCount); 97 target->getViewMatrix().mapRect(&b); 98 b.roundOut(&bounds); 99 if (this->setupOffscreenAAPass1(target, false, bounds, &record)) { 100 doAA = true; 101 } 102 } 103 104 if (NULL == idxSrc) { 105 target->drawNonIndexed(primitiveType, 0, vertexCount); 106 } else { 107 target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); 108 } 109 110 if (doAA) { 111 geo.set(NULL, 0, 0, 0); // have to release geom before can draw again 112 this->offscreenAAPass2(target, paint, bounds, &record); 113 } 114 } 115 116 class GrNullTexCoordSource { 117 public: 118 void writeValue(int i, GrPoint* dstCoord) const { GrAssert(false); } 119 }; 120 121 class GrNullColorSource { 122 public: 123 void writeValue(int i, GrColor* dstColor) const { GrAssert(false); } 124 }; 125 126 class GrNullIndexSource { 127 public: 128 void writeValue(int i, uint16_t* dstIndex) const { GrAssert(false); } 129 int count() const { GrAssert(false); return 0; } 130 }; 131 132 template <typename POS_SRC> 133 inline void GrContext::drawCustomVertices(const GrPaint& paint, 134 GrPrimitiveType primitiveType, 135 const POS_SRC& posSrc) { 136 this->drawCustomVertices<POS_SRC, 137 GrNullTexCoordSource, 138 GrNullColorSource, 139 GrNullIndexSource>(paint, primitiveType, posSrc, 140 NULL, NULL, NULL); 141 } 142 143 template <typename POS_SRC, typename TEX_SRC> 144 inline void GrContext::drawCustomVertices(const GrPaint& paint, 145 GrPrimitiveType primitiveType, 146 const POS_SRC& posSrc, 147 const TEX_SRC* texCoordSrc) { 148 this->drawCustomVertices<POS_SRC, TEX_SRC, 149 GrNullColorSource, 150 GrNullIndexSource>(paint, primitiveType, posSrc, 151 texCoordSrc, NULL, NULL); 152 } 153 154 template <typename POS_SRC, typename TEX_SRC, typename COL_SRC> 155 inline void GrContext::drawCustomVertices(const GrPaint& paint, 156 GrPrimitiveType primitiveType, 157 const POS_SRC& posSrc, 158 const TEX_SRC* texCoordSrc, 159 const COL_SRC* colorSrc) { 160 drawCustomVertices<POS_SRC, TEX_SRC, COL_SRC, 161 GrNullIndexSource>(paint, primitiveType, posSrc, 162 texCoordSrc, colorSrc, NULL); 163 } 164 165 #endif 166