Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrDrawTarget.cpp
index 0909e08..eb89915 100644 (file)
@@ -13,6 +13,7 @@
 #include "GrDrawTargetCaps.h"
 #include "GrPath.h"
 #include "GrRenderTarget.h"
+#include "GrTemplates.h"
 #include "GrTexture.h"
 #include "GrVertexBuffer.h"
 
@@ -31,7 +32,7 @@ GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
     fVerticesPerInstance    = di.fVerticesPerInstance;
     fIndicesPerInstance     = di.fIndicesPerInstance;
 
-    if (NULL != di.fDevBounds) {
+    if (di.fDevBounds) {
         SkASSERT(di.fDevBounds == &di.fDevBoundsStorage);
         fDevBoundsStorage = di.fDevBoundsStorage;
         fDevBounds = &fDevBoundsStorage;
@@ -88,8 +89,9 @@ void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
 
 GrDrawTarget::GrDrawTarget(GrContext* context)
     : fClip(NULL)
-    , fContext(context) {
-    SkASSERT(NULL != context);
+    , fContext(context)
+    , fGpuTraceMarkerCount(0) {
+    SkASSERT(context);
 
     fDrawState = &fDefaultDrawState;
     // We assume that fDrawState always owns a ref to the object it points at.
@@ -133,7 +135,7 @@ const GrClipData* GrDrawTarget::getClip() const {
 }
 
 void GrDrawTarget::setDrawState(GrDrawState*  drawState) {
-    SkASSERT(NULL != fDrawState);
+    SkASSERT(fDrawState);
     if (NULL == drawState) {
         drawState = &fDefaultDrawState;
     }
@@ -150,7 +152,7 @@ bool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
     bool acquired = false;
     if (vertexCount > 0) {
-        SkASSERT(NULL != vertices);
+        SkASSERT(vertices);
         this->releasePreviousVertexSource();
         geoSrc.fVertexSrc = kNone_GeometrySrcType;
 
@@ -162,7 +164,7 @@ bool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
         geoSrc.fVertexSrc = kReserved_GeometrySrcType;
         geoSrc.fVertexCount = vertexCount;
         geoSrc.fVertexSize = vertexSize;
-    } else if (NULL != vertices) {
+    } else if (vertices) {
         *vertices = NULL;
     }
     return acquired;
@@ -173,7 +175,7 @@ bool GrDrawTarget::reserveIndexSpace(int indexCount,
     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
     bool acquired = false;
     if (indexCount > 0) {
-        SkASSERT(NULL != indices);
+        SkASSERT(indices);
         this->releasePreviousIndexSource();
         geoSrc.fIndexSrc = kNone_GeometrySrcType;
 
@@ -182,7 +184,7 @@ bool GrDrawTarget::reserveIndexSpace(int indexCount,
     if (acquired) {
         geoSrc.fIndexSrc = kReserved_GeometrySrcType;
         geoSrc.fIndexCount = indexCount;
-    } else if (NULL != indices) {
+    } else if (indices) {
         *indices = NULL;
     }
     return acquired;
@@ -193,10 +195,10 @@ bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
                                               int indexCount,
                                               void** vertices,
                                               void** indices) {
-    size_t vertexSize = this->drawState()->getVertexSize();
+    size_t vertexStride = this->drawState()->getVertexStride();
     this->willReserveVertexAndIndexSpace(vertexCount, indexCount);
     if (vertexCount) {
-        if (!this->reserveVertexSpace(vertexSize, vertexCount, vertices)) {
+        if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) {
             if (indexCount) {
                 this->resetIndexSource();
             }
@@ -216,10 +218,10 @@ bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
 
 bool GrDrawTarget::geometryHints(int32_t* vertexCount,
                                  int32_t* indexCount) const {
-    if (NULL != vertexCount) {
+    if (vertexCount) {
         *vertexCount = -1;
     }
-    if (NULL != indexCount) {
+    if (indexCount) {
         *indexCount = -1;
     }
     return false;
@@ -243,7 +245,7 @@ void GrDrawTarget::releasePreviousVertexSource() {
 #endif
             break;
         default:
-            GrCrash("Unknown Vertex Source Type.");
+            SkFAIL("Unknown Vertex Source Type.");
             break;
     }
 }
@@ -266,7 +268,7 @@ void GrDrawTarget::releasePreviousIndexSource() {
 #endif
             break;
         default:
-            GrCrash("Unknown Index Source Type.");
+            SkFAIL("Unknown Index Source Type.");
             break;
     }
 }
@@ -276,7 +278,7 @@ void GrDrawTarget::setVertexSourceToArray(const void* vertexArray,
     this->releasePreviousVertexSource();
     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
     geoSrc.fVertexSrc = kArray_GeometrySrcType;
-    geoSrc.fVertexSize = this->drawState()->getVertexSize();
+    geoSrc.fVertexSize = this->drawState()->getVertexStride();
     geoSrc.fVertexCount = vertexCount;
     this->onSetVertexSourceToArray(vertexArray, vertexCount);
 }
@@ -296,7 +298,7 @@ void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
     geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
     geoSrc.fVertexBuffer = buffer;
     buffer->ref();
-    geoSrc.fVertexSize = this->drawState()->getVertexSize();
+    geoSrc.fVertexSize = this->drawState()->getVertexStride();
 }
 
 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
@@ -354,41 +356,50 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
     int maxValidVertex;
     switch (geoSrc.fVertexSrc) {
         case kNone_GeometrySrcType:
-            GrCrash("Attempting to draw without vertex src.");
+            SkFAIL("Attempting to draw without vertex src.");
         case kReserved_GeometrySrcType: // fallthrough
         case kArray_GeometrySrcType:
             maxValidVertex = geoSrc.fVertexCount;
             break;
         case kBuffer_GeometrySrcType:
-            maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->sizeInBytes() / geoSrc.fVertexSize);
+            maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->gpuMemorySize() / geoSrc.fVertexSize);
             break;
     }
     if (maxVertex > maxValidVertex) {
-        GrCrash("Drawing outside valid vertex range.");
+        SkFAIL("Drawing outside valid vertex range.");
     }
     if (indexCount > 0) {
         int maxIndex = startIndex + indexCount;
         int maxValidIndex;
         switch (geoSrc.fIndexSrc) {
             case kNone_GeometrySrcType:
-                GrCrash("Attempting to draw indexed geom without index src.");
+                SkFAIL("Attempting to draw indexed geom without index src.");
             case kReserved_GeometrySrcType: // fallthrough
             case kArray_GeometrySrcType:
                 maxValidIndex = geoSrc.fIndexCount;
                 break;
             case kBuffer_GeometrySrcType:
-                maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t));
+                maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->gpuMemorySize() / sizeof(uint16_t));
                 break;
         }
         if (maxIndex > maxValidIndex) {
-            GrCrash("Index reads outside valid index range.");
+            SkFAIL("Index reads outside valid index range.");
         }
     }
 
-    SkASSERT(NULL != drawState.getRenderTarget());
+    SkASSERT(drawState.getRenderTarget());
+
+    if (drawState.hasGeometryProcessor()) {
+        const GrGeometryProcessor* gp = drawState.getGeometryProcessor()->getGeometryProcessor();
+        int numTextures = gp->numTextures();
+        for (int t = 0; t < numTextures; ++t) {
+            GrTexture* texture = gp->texture(t);
+            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
+        }
+    }
 
     for (int s = 0; s < drawState.numColorStages(); ++s) {
-        const GrEffectRef& effect = *drawState.getColorStage(s).getEffect();
+        const GrProcessor* effect = drawState.getColorStage(s).getProcessor();
         int numTextures = effect->numTextures();
         for (int t = 0; t < numTextures; ++t) {
             GrTexture* texture = effect->texture(t);
@@ -396,7 +407,7 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
         }
     }
     for (int s = 0; s < drawState.numCoverageStages(); ++s) {
-        const GrEffectRef& effect = *drawState.getCoverageStage(s).getEffect();
+        const GrProcessor* effect = drawState.getCoverageStage(s).getProcessor();
         int numTextures = effect->numTextures();
         for (int t = 0; t < numTextures; ++t) {
             GrTexture* texture = effect->texture(t);
@@ -421,7 +432,7 @@ bool GrDrawTarget::setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const
     const GrClipData* clip = this->getClip();
     clip->getConservativeBounds(rt, &copyRect);
 
-    if (NULL != drawBounds) {
+    if (drawBounds) {
         SkIRect drawIBounds;
         drawBounds->roundOut(&drawIBounds);
         if (!copyRect.intersect(drawIBounds)) {
@@ -477,7 +488,7 @@ void GrDrawTarget::drawIndexed(GrPrimitiveType type,
         info.fVerticesPerInstance   = 0;
         info.fIndicesPerInstance    = 0;
 
-        if (NULL != devBounds) {
+        if (devBounds) {
             info.setDevBounds(*devBounds);
         }
         // TODO: We should continue with incorrect blending.
@@ -504,7 +515,7 @@ void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
         info.fVerticesPerInstance   = 0;
         info.fIndicesPerInstance    = 0;
 
-        if (NULL != devBounds) {
+        if (devBounds) {
             info.setDevBounds(*devBounds);
         }
         // TODO: We should continue with incorrect blending.
@@ -517,7 +528,7 @@ void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
 
 void GrDrawTarget::stencilPath(const GrPath* path, SkPath::FillType fill) {
     // TODO: extract portions of checkDraw that are relevant to path stenciling.
-    SkASSERT(NULL != path);
+    SkASSERT(path);
     SkASSERT(this->caps()->pathRenderingSupport());
     SkASSERT(!SkPath::IsInverseFillType(fill));
     this->onStencilPath(path, fill);
@@ -525,7 +536,7 @@ void GrDrawTarget::stencilPath(const GrPath* path, SkPath::FillType fill) {
 
 void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) {
     // TODO: extract portions of checkDraw that are relevant to path rendering.
-    SkASSERT(NULL != path);
+    SkASSERT(path);
     SkASSERT(this->caps()->pathRenderingSupport());
     const GrDrawState* drawState = &getDrawState();
 
@@ -547,26 +558,67 @@ void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) {
     this->onDrawPath(path, fill, dstCopy.texture() ? &dstCopy : NULL);
 }
 
-////////////////////////////////////////////////////////////////////////////////
+void GrDrawTarget::drawPaths(const GrPathRange* pathRange,
+                             const uint32_t indices[], int count,
+                             const float transforms[], PathTransformType transformsType,
+                             SkPath::FillType fill) {
+    SkASSERT(this->caps()->pathRenderingSupport());
+    SkASSERT(pathRange);
+    SkASSERT(indices);
+    SkASSERT(transforms);
+
+    // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt
+    // instead for it to just copy the entire dst. Realistically this is a moot
+    // point, because any context that supports NV_path_rendering will also
+    // support NV_blend_equation_advanced.
+    GrDeviceCoordTexture dstCopy;
+    if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
+        return;
+    }
 
-bool GrDrawTarget::willUseHWAALines() const {
-    // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth
-    // lines tweak the incoming alpha value but not in a premul-alpha way. So we only use them when
-    // our alpha is 0xff and tweaking the color for partial coverage is OK
-    if (!this->caps()->hwAALineSupport() ||
-        !this->getDrawState().isHWAntialiasState()) {
-        return false;
+    this->onDrawPaths(pathRange, indices, count, transforms, transformsType, fill,
+                      dstCopy.texture() ? &dstCopy : NULL);
+}
+
+typedef GrTraceMarkerSet::Iter TMIter;
+void GrDrawTarget::saveActiveTraceMarkers() {
+    if (this->caps()->gpuTracingSupport()) {
+        SkASSERT(0 == fStoredTraceMarkers.count());
+        fStoredTraceMarkers.addSet(fActiveTraceMarkers);
+        for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
+            this->removeGpuTraceMarker(&(*iter));
+        }
     }
-    GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts();
-    return (GrDrawState::kDisableBlend_BlendOptFlag & opts) &&
-           (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts);
 }
 
-bool GrDrawTarget::canApplyCoverage() const {
-    // we can correctly apply coverage if a) we have dual source blending
-    // or b) one of our blend optimizations applies.
-    return this->caps()->dualSourceBlendingSupport() ||
-           GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true);
+void GrDrawTarget::restoreActiveTraceMarkers() {
+    if (this->caps()->gpuTracingSupport()) {
+        SkASSERT(0 == fActiveTraceMarkers.count());
+        for (TMIter iter = fStoredTraceMarkers.begin(); iter != fStoredTraceMarkers.end(); ++iter) {
+            this->addGpuTraceMarker(&(*iter));
+        }
+        for (TMIter iter = fActiveTraceMarkers.begin(); iter != fActiveTraceMarkers.end(); ++iter) {
+            this->fStoredTraceMarkers.remove(*iter);
+        }
+    }
+}
+
+void GrDrawTarget::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
+    if (this->caps()->gpuTracingSupport()) {
+        SkASSERT(fGpuTraceMarkerCount >= 0);
+        this->fActiveTraceMarkers.add(*marker);
+        this->didAddGpuTraceMarker();
+        ++fGpuTraceMarkerCount;
+    }
+}
+
+void GrDrawTarget::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
+    if (this->caps()->gpuTracingSupport()) {
+        SkASSERT(fGpuTraceMarkerCount >= 1);
+        this->fActiveTraceMarkers.remove(*marker);
+        this->didRemoveGpuTraceMarker();
+        --fGpuTraceMarkerCount;
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -593,7 +645,7 @@ void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
     info.fVerticesPerInstance = verticesPerInstance;
 
     // Set the same bounds for all the draws.
-    if (NULL != devBounds) {
+    if (devBounds) {
         info.setDevBounds(*devBounds);
     }
     // TODO: We should continue with incorrect blending.
@@ -602,7 +654,7 @@ void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
     }
 
     while (instanceCount) {
-        info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw);
+        info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw);
         info.fVertexCount = info.fInstanceCount * verticesPerInstance;
         info.fIndexCount = info.fInstanceCount * indicesPerInstance;
 
@@ -625,30 +677,24 @@ namespace {
 // position + (optional) texture coord
 extern const GrVertexAttrib gBWRectPosUVAttribs[] = {
     {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
-    {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
+    {kVec2f_GrVertexAttribType, sizeof(SkPoint), kLocalCoord_GrVertexAttribBinding}
 };
 
 void set_vertex_attributes(GrDrawState* drawState, bool hasUVs) {
     if (hasUVs) {
-        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2);
+        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2, 2 * sizeof(SkPoint));
     } else {
-        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1);
+        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1, sizeof(SkPoint));
     }
 }
 
 };
 
 void GrDrawTarget::onDrawRect(const SkRect& rect,
-                              const SkMatrix* matrix,
                               const SkRect* localRect,
                               const SkMatrix* localMatrix) {
 
-    GrDrawState::AutoViewMatrixRestore avmr;
-    if (NULL != matrix) {
-        avmr.set(this->drawState(), *matrix);
-    }
-
-    set_vertex_attributes(this->drawState(), NULL != localRect);
+    set_vertex_attributes(this->drawState(), SkToBool(localRect));
 
     AutoReleaseGeometry geo(this, 4, 0);
     if (!geo.succeeded()) {
@@ -656,16 +702,16 @@ void GrDrawTarget::onDrawRect(const SkRect& rect,
         return;
     }
 
-    size_t vsize = this->drawState()->getVertexSize();
-    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
-    if (NULL != localRect) {
-        GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
-                                            sizeof(GrPoint));
+    size_t vstride = this->drawState()->getVertexStride();
+    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
+    if (localRect) {
+        SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
+                                            sizeof(SkPoint));
         coords->setRectFan(localRect->fLeft, localRect->fTop,
                            localRect->fRight, localRect->fBottom,
-                           vsize);
-        if (NULL != localMatrix) {
-            localMatrix->mapPointsWithStride(coords, vsize, 4);
+                           vstride);
+        if (localMatrix) {
+            localMatrix->mapPointsWithStride(coords, vstride, 4);
         }
     }
     SkRect bounds;
@@ -691,7 +737,7 @@ GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
 }
 
 GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
-    if (NULL != fDrawTarget) {
+    if (fDrawTarget) {
         fDrawTarget->setDrawState(fSavedState);
         fSavedState->unref();
     }
@@ -771,8 +817,7 @@ bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
     this->reset();
     fTarget = target;
     bool success = true;
-    if (NULL != fTarget) {
-        fTarget = target;
+    if (fTarget) {
         success = target->reserveVertexAndIndexSpace(vertexCount,
                                                      indexCount,
                                                      &fVertices,
@@ -782,16 +827,16 @@ bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
             this->reset();
         }
     }
-    SkASSERT(success == (NULL != fTarget));
+    SkASSERT(success == SkToBool(fTarget));
     return success;
 }
 
 void GrDrawTarget::AutoReleaseGeometry::reset() {
-    if (NULL != fTarget) {
-        if (NULL != fVertices) {
+    if (fTarget) {
+        if (fVertices) {
             fTarget->resetVertexSource();
         }
-        if (NULL != fIndices) {
+        if (fIndices) {
             fTarget->resetIndexSource();
         }
         fTarget = NULL;
@@ -866,8 +911,8 @@ bool GrDrawTarget::copySurface(GrSurface* dst,
                                GrSurface* src,
                                const SkIRect& srcRect,
                                const SkIPoint& dstPoint) {
-    SkASSERT(NULL != dst);
-    SkASSERT(NULL != src);
+    SkASSERT(dst);
+    SkASSERT(src);
 
     SkIRect clippedSrcRect;
     SkIPoint clippedDstPoint;
@@ -891,8 +936,8 @@ bool GrDrawTarget::canCopySurface(GrSurface* dst,
                                   GrSurface* src,
                                   const SkIRect& srcRect,
                                   const SkIPoint& dstPoint) {
-    SkASSERT(NULL != dst);
-    SkASSERT(NULL != src);
+    SkASSERT(dst);
+    SkASSERT(src);
 
     SkIRect clippedSrcRect;
     SkIPoint clippedDstPoint;
@@ -919,7 +964,7 @@ bool GrDrawTarget::onCanCopySurface(GrSurface* dst,
     SkASSERT(dstPoint.fX + srcRect.width() <= dst->width() &&
              dstPoint.fY + srcRect.height() <= dst->height());
 
-    return !dst->isSameAs(src) && NULL != dst->asRenderTarget() && NULL != src->asTexture();
+    return !dst->isSameAs(src) && dst->asRenderTarget() && src->asTexture();
 }
 
 bool GrDrawTarget::onCopySurface(GrSurface* dst,
@@ -939,7 +984,7 @@ bool GrDrawTarget::onCopySurface(GrSurface* dst,
     matrix.setTranslate(SkIntToScalar(srcRect.fLeft - dstPoint.fX),
                         SkIntToScalar(srcRect.fTop - dstPoint.fY));
     matrix.postIDiv(tex->width(), tex->height());
-    this->drawState()->addColorTextureEffect(tex, matrix);
+    this->drawState()->addColorTextureProcessor(tex, matrix);
     SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX,
                                         dstPoint.fY,
                                         srcRect.width(),
@@ -958,7 +1003,6 @@ void GrDrawTarget::initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* d
 ///////////////////////////////////////////////////////////////////////////////
 
 void GrDrawTargetCaps::reset() {
-    f8BitPaletteSupport = false;
     fMipMapSupport = false;
     fNPOTTextureTileSupport = false;
     fTwoSidedStencilSupport = false;
@@ -967,20 +1011,24 @@ void GrDrawTargetCaps::reset() {
     fShaderDerivativeSupport = false;
     fGeometryShaderSupport = false;
     fDualSourceBlendingSupport = false;
-    fBufferLockSupport = false;
     fPathRenderingSupport = false;
     fDstReadInShaderSupport = false;
+    fDiscardRenderTargetSupport = false;
     fReuseScratchTextures = true;
+    fGpuTracingSupport = false;
+    fCompressedTexSubImageSupport = false;
+
+    fMapBufferFlags = kNone_MapFlags;
 
     fMaxRenderTargetSize = 0;
     fMaxTextureSize = 0;
     fMaxSampleCount = 0;
 
     memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport));
+    memset(fConfigTextureSupport, 0, sizeof(fConfigTextureSupport));
 }
 
 GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
-    f8BitPaletteSupport = other.f8BitPaletteSupport;
     fMipMapSupport = other.fMipMapSupport;
     fNPOTTextureTileSupport = other.fNPOTTextureTileSupport;
     fTwoSidedStencilSupport = other.fTwoSidedStencilSupport;
@@ -989,39 +1037,67 @@ GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
     fShaderDerivativeSupport = other.fShaderDerivativeSupport;
     fGeometryShaderSupport = other.fGeometryShaderSupport;
     fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
-    fBufferLockSupport = other.fBufferLockSupport;
     fPathRenderingSupport = other.fPathRenderingSupport;
     fDstReadInShaderSupport = other.fDstReadInShaderSupport;
+    fDiscardRenderTargetSupport = other.fDiscardRenderTargetSupport;
     fReuseScratchTextures = other.fReuseScratchTextures;
+    fGpuTracingSupport = other.fGpuTracingSupport;
+    fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport;
+
+    fMapBufferFlags = other.fMapBufferFlags;
 
     fMaxRenderTargetSize = other.fMaxRenderTargetSize;
     fMaxTextureSize = other.fMaxTextureSize;
     fMaxSampleCount = other.fMaxSampleCount;
 
     memcpy(fConfigRenderSupport, other.fConfigRenderSupport, sizeof(fConfigRenderSupport));
+    memcpy(fConfigTextureSupport, other.fConfigTextureSupport, sizeof(fConfigTextureSupport));
 
     return *this;
 }
 
+static SkString map_flags_to_string(uint32_t flags) {
+    SkString str;
+    if (GrDrawTargetCaps::kNone_MapFlags == flags) {
+        str = "none";
+    } else {
+        SkASSERT(GrDrawTargetCaps::kCanMap_MapFlag & flags);
+        SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kCanMap_MapFlag);
+        str = "can_map";
+
+        if (GrDrawTargetCaps::kSubset_MapFlag & flags) {
+            str.append(" partial");
+        } else {
+            str.append(" full");
+        }
+        SkDEBUGCODE(flags &= ~GrDrawTargetCaps::kSubset_MapFlag);
+    }
+    SkASSERT(0 == flags); // Make sure we handled all the flags.
+    return str;
+}
+
 SkString GrDrawTargetCaps::dump() const {
     SkString r;
     static const char* gNY[] = {"NO", "YES"};
-    r.appendf("8 Bit Palette Support       : %s\n", gNY[f8BitPaletteSupport]);
-    r.appendf("MIP Map Support             : %s\n", gNY[fMipMapSupport]);
-    r.appendf("NPOT Texture Tile Support   : %s\n", gNY[fNPOTTextureTileSupport]);
-    r.appendf("Two Sided Stencil Support   : %s\n", gNY[fTwoSidedStencilSupport]);
-    r.appendf("Stencil Wrap Ops  Support   : %s\n", gNY[fStencilWrapOpsSupport]);
-    r.appendf("HW AA Lines Support         : %s\n", gNY[fHWAALineSupport]);
-    r.appendf("Shader Derivative Support   : %s\n", gNY[fShaderDerivativeSupport]);
-    r.appendf("Geometry Shader Support     : %s\n", gNY[fGeometryShaderSupport]);
-    r.appendf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
-    r.appendf("Buffer Lock Support         : %s\n", gNY[fBufferLockSupport]);
-    r.appendf("Path Rendering Support      : %s\n", gNY[fPathRenderingSupport]);
-    r.appendf("Dst Read In Shader Support  : %s\n", gNY[fDstReadInShaderSupport]);
-    r.appendf("Reuse Scratch Textures      : %s\n", gNY[fReuseScratchTextures]);
-    r.appendf("Max Texture Size            : %d\n", fMaxTextureSize);
-    r.appendf("Max Render Target Size      : %d\n", fMaxRenderTargetSize);
-    r.appendf("Max Sample Count            : %d\n", fMaxSampleCount);
+    r.appendf("MIP Map Support              : %s\n", gNY[fMipMapSupport]);
+    r.appendf("NPOT Texture Tile Support    : %s\n", gNY[fNPOTTextureTileSupport]);
+    r.appendf("Two Sided Stencil Support    : %s\n", gNY[fTwoSidedStencilSupport]);
+    r.appendf("Stencil Wrap Ops  Support    : %s\n", gNY[fStencilWrapOpsSupport]);
+    r.appendf("HW AA Lines Support          : %s\n", gNY[fHWAALineSupport]);
+    r.appendf("Shader Derivative Support    : %s\n", gNY[fShaderDerivativeSupport]);
+    r.appendf("Geometry Shader Support      : %s\n", gNY[fGeometryShaderSupport]);
+    r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]);
+    r.appendf("Path Rendering Support       : %s\n", gNY[fPathRenderingSupport]);
+    r.appendf("Dst Read In Shader Support   : %s\n", gNY[fDstReadInShaderSupport]);
+    r.appendf("Discard Render Target Support: %s\n", gNY[fDiscardRenderTargetSupport]);
+    r.appendf("Reuse Scratch Textures       : %s\n", gNY[fReuseScratchTextures]);
+    r.appendf("Gpu Tracing Support          : %s\n", gNY[fGpuTracingSupport]);
+    r.appendf("Compressed Update Support    : %s\n", gNY[fCompressedTexSubImageSupport]);
+    r.appendf("Max Texture Size             : %d\n", fMaxTextureSize);
+    r.appendf("Max Render Target Size       : %d\n", fMaxRenderTargetSize);
+    r.appendf("Max Sample Count             : %d\n", fMaxSampleCount);
+
+    r.appendf("Map Buffer Support           : %s\n", map_flags_to_string(fMapBufferFlags).c_str());
 
     static const char* kConfigNames[] = {
         "Unknown",  // kUnknown_GrPixelConfig
@@ -1031,25 +1107,53 @@ SkString GrDrawTargetCaps::dump() const {
         "RGBA444",  // kRGBA_4444_GrPixelConfig,
         "RGBA8888", // kRGBA_8888_GrPixelConfig,
         "BGRA8888", // kBGRA_8888_GrPixelConfig,
+        "ETC1",     // kETC1_GrPixelConfig,
+        "LATC",     // kLATC_GrPixelConfig,
+        "R11EAC",   // kR11_EAC_GrPixelConfig,
+        "ASTC12x12",// kASTC_12x12_GrPixelConfig,
+        "RGBAFloat",  // kRGBA_float_GrPixelConfig
     };
-    GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
-    GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
-    GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
-    GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
-    GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
-    GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
-    GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(0  == kUnknown_GrPixelConfig);
+    GR_STATIC_ASSERT(1  == kAlpha_8_GrPixelConfig);
+    GR_STATIC_ASSERT(2  == kIndex_8_GrPixelConfig);
+    GR_STATIC_ASSERT(3  == kRGB_565_GrPixelConfig);
+    GR_STATIC_ASSERT(4  == kRGBA_4444_GrPixelConfig);
+    GR_STATIC_ASSERT(5  == kRGBA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(6  == kBGRA_8888_GrPixelConfig);
+    GR_STATIC_ASSERT(7  == kETC1_GrPixelConfig);
+    GR_STATIC_ASSERT(8  == kLATC_GrPixelConfig);
+    GR_STATIC_ASSERT(9  == kR11_EAC_GrPixelConfig);
+    GR_STATIC_ASSERT(10 == kASTC_12x12_GrPixelConfig);
+    GR_STATIC_ASSERT(11 == kRGBA_float_GrPixelConfig);
     GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
 
     SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][0]);
     SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][1]);
-    for (size_t i = 0; i < SK_ARRAY_COUNT(kConfigNames); ++i)  {
-        if (i != kUnknown_GrPixelConfig) {
-            r.appendf("%s is renderable: %s, with MSAA: %s\n",
-                     kConfigNames[i],
-                     gNY[fConfigRenderSupport[i][0]],
-                     gNY[fConfigRenderSupport[i][1]]);
-        }
+
+    for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i)  {
+        r.appendf("%s is renderable: %s, with MSAA: %s\n",
+                  kConfigNames[i],
+                  gNY[fConfigRenderSupport[i][0]],
+                  gNY[fConfigRenderSupport[i][1]]);
     }
+
+    SkASSERT(!fConfigTextureSupport[kUnknown_GrPixelConfig]);
+
+    for (size_t i = 1; i < SK_ARRAY_COUNT(kConfigNames); ++i)  {
+        r.appendf("%s is uploadable to a texture: %s\n",
+                  kConfigNames[i],
+                  gNY[fConfigTextureSupport[i]]);
+    }
+
     return r;
 }
+
+uint32_t GrDrawTargetCaps::CreateUniqueID() {
+    static int32_t gUniqueID = SK_InvalidUniqueID;
+    uint32_t id;
+    do {
+        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
+    } while (id == SK_InvalidUniqueID);
+    return id;
+}
+