Home | History | Annotate | Download | only in include
      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