Add an origin flag for backend (external) textures.  Some textures in WebKit have a topdown orientation, and skia needs to be notified of this, so that they are not drawn upside-down.

Review URL: https://codereview.appspot.com/7200048

git-svn-id: http://skia.googlecode.com/svn/trunk@7414 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index 4e77466..19a37a5 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -142,7 +142,7 @@
                    bool isWrapped,
                    GrTexture* texture,
                    const GrTextureDesc& desc,
-                   Origin origin)
+                   GrSurfaceOrigin origin)
         : INHERITED(gpu, isWrapped, desc, origin)
         , fStencilBuffer(NULL)
         , fTexture(texture) {
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index 4ef0acb..8ccbc98 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -33,19 +33,8 @@
      */
     int height() const { return fDesc.fHeight; }
 
-    /**
-     * Some surfaces will be stored such that the upper and left edges of the content meet at the
-     * the origin (in texture coord space) and for other surfaces the lower and left edges meet at
-     * the origin. Render-targets are always consistent with the convention of the underlying
-     * backend API to make it easier to mix native backend rendering with Skia rendering. Wrapped
-     * backend surfaces always use the backend's convention as well.
-     */
-    enum Origin {
-        kTopLeft_Origin,
-        kBottomLeft_Origin,
-    };
-    Origin origin() const {
-        GrAssert(kTopLeft_Origin == fOrigin || kBottomLeft_Origin == fOrigin);
+    GrSurfaceOrigin origin() const {
+        GrAssert(kTopLeft_SurfaceOrigin == fOrigin || kBottomLeft_SurfaceOrigin == fOrigin);
         return fOrigin;
     }
 
@@ -115,7 +104,7 @@
                              uint32_t pixelOpsFlags = 0) = 0;
 
 protected:
-    GrSurface(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc, Origin origin)
+    GrSurface(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc, GrSurfaceOrigin origin)
     : INHERITED(gpu, isWrapped)
     , fDesc(desc)
     , fOrigin(origin) {
@@ -124,7 +113,7 @@
     GrTextureDesc fDesc;
 
 private:
-    Origin fOrigin;
+    GrSurfaceOrigin fOrigin;
 
     typedef GrResource INHERITED;
 };
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index 657e6e5..94d5788 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -140,7 +140,7 @@
                                    // base class cons sets to NULL
                                    // subclass cons can create and set
 
-    GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc, Origin origin)
+    GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc, GrSurfaceOrigin origin)
     : INHERITED(gpu, isWrapped, desc, origin)
     , fRenderTarget(NULL) {
 
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index d7241b4..055750d 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -425,6 +425,17 @@
     kGrColorTableSize = 256 * 4 //sizeof(GrColor)
 };
 
+/**
+ * Some textures will be stored such that the upper and left edges of the content meet at the
+ * the origin (in texture coord space) and for other textures the lower and left edges meet at
+ * the origin. Render-targets are always consistent with the convention of the underlying
+ * backend API to make it easier to mix native backend rendering with Skia rendering.
+ */
+
+enum GrSurfaceOrigin {
+    kBottomLeft_GrSurfaceOrigin,
+    kTopLeft_GrSurfaceOrigin,
+};
 
 /**
  * Describes a texture to be created.
@@ -596,6 +607,7 @@
 struct GrBackendTextureDesc {
     GrBackendTextureDesc() { memset(this, 0, sizeof(*this)); }
     GrBackendTextureFlags           fFlags;
+    GrSurfaceOrigin                 fOrigin;
     int                             fWidth;         //<! width in pixels
     int                             fHeight;        //<! height in pixels
     GrPixelConfig                   fConfig;        //<! color format
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 0fef7c6..aeb47dc 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -516,7 +516,7 @@
                                colorTex);
 
     uman.set2f(fScaleUni, SkScalarToFloat(displacementMap.scale()),
-                colorTex->origin() == GrSurface::kTopLeft_Origin ?
+                colorTex->origin() == kTopLeft_GrSurfaceOrigin ?
                 SkScalarToFloat(displacementMap.scale()) :
                 SkScalarToFloat(-displacementMap.scale()));
 }
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index dd892f9..498c8e0 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -1218,7 +1218,7 @@
 void GrGLLightingEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
     const GrLightingEffect& effect = GetEffectFromStage<GrLightingEffect>(stage);
     GrTexture* texture = effect.texture(0);
-    float ySign = texture->origin() == GrSurface::kTopLeft_Origin ? -1.0f : 1.0f;
+    float ySign = texture->origin() == kTopLeft_GrSurfaceOrigin ? -1.0f : 1.0f;
     uman.set2f(fImageIncrementUni, 1.0f / texture->width(), ySign / texture->height());
     uman.set1f(fSurfaceScaleUni, effect.surfaceScale());
     fLight->setData(uman, effect.light());
diff --git a/src/effects/SkMatrixConvolutionImageFilter.cpp b/src/effects/SkMatrixConvolutionImageFilter.cpp
index 0c2a24e..5a97ec4f 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -473,7 +473,7 @@
     GrAssert(effect.kernelSize() == fKernelSize);
     GrAssert(effect.tileMode() == fTileMode);
     float imageIncrement[2];
-    float ySign = texture.origin() == GrSurface::kTopLeft_Origin ? 1.0f : -1.0f;
+    float ySign = texture.origin() == kTopLeft_GrSurfaceOrigin ? 1.0f : -1.0f;
     imageIncrement[0] = 1.0f / texture.width();
     imageIncrement[1] = ySign / texture.height();
     uman.set2fv(fImageIncrementUni, 0, 1, imageIncrement);
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
index bfd62c2..833c198 100644
--- a/src/gpu/effects/GrTextureDomainEffect.cpp
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -90,7 +90,7 @@
         SkScalarToFloat(domain.bottom())
     };
     // vertical flip if necessary
-    if (GrSurface::kBottomLeft_Origin == effect.texture(0)->origin()) {
+    if (kBottomLeft_GrSurfaceOrigin == effect.texture(0)->origin()) {
         values[1] = 1.0f - values[1];
         values[3] = 1.0f - values[3];
         // The top and bottom were just flipped, so correct the ordering
diff --git a/src/gpu/gl/GrGLEffectMatrix.cpp b/src/gpu/gl/GrGLEffectMatrix.cpp
index 6dcb6e6..5fdde2c 100644
--- a/src/gpu/gl/GrGLEffectMatrix.cpp
+++ b/src/gpu/gl/GrGLEffectMatrix.cpp
@@ -19,7 +19,7 @@
                                      SkMatrix::kPerspective_Mask;
     int combinedTypes = type0 | type1;
 
-    bool reverseY = (NULL != texture) && GrSurface::kBottomLeft_Origin == texture->origin();
+    bool reverseY = (NULL != texture) && kBottomLeft_GrSurfaceOrigin == texture->origin();
 
     if (SkMatrix::kPerspective_Mask & combinedTypes) {
         return kGeneral_Key;
@@ -173,11 +173,11 @@
         case kVoid_GrSLType:
             GrAssert(matrix.isIdentity());
             GrAssert(coordChangeMatrix.isIdentity());
-            GrAssert(NULL == texture || GrSurface::kTopLeft_Origin == texture->origin());
+            GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
             return;
         case kVec2f_GrSLType: {
             GrAssert(SkMatrix::kTranslate_Mask == (matrix.getType() | coordChangeMatrix.getType()));
-            GrAssert(NULL == texture || GrSurface::kTopLeft_Origin == texture->origin());
+            GrAssert(NULL == texture || kTopLeft_GrSurfaceOrigin == texture->origin());
             SkScalar tx = matrix[SkMatrix::kMTransX] + coordChangeMatrix[SkMatrix::kMTransX];
             SkScalar ty = matrix[SkMatrix::kMTransY] + coordChangeMatrix[SkMatrix::kMTransY];
             if (fPrevMatrix.get(SkMatrix::kMTransX) != tx ||
@@ -191,7 +191,7 @@
         case kMat33f_GrSLType: {
             SkMatrix combined;
             combined.setConcat(matrix, coordChangeMatrix);
-            if (NULL != texture && GrSurface::kBottomLeft_Origin == texture->origin()) {
+            if (NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin()) {
                 // combined.postScale(1,-1);
                 // combined.postTranslate(0,1);
                 combined.set(SkMatrix::kMSkewY,
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index c68283e..47128e7 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -51,7 +51,7 @@
                          viewport.fWidth, viewport.fHeight,
                          desc.fConfig, desc.fSampleCnt),
                 texture->origin()) {
-    GrAssert(kBottomLeft_Origin == texture->origin());
+    GrAssert(kBottomLeft_GrSurfaceOrigin == texture->origin());
     GrAssert(NULL != texID);
     GrAssert(NULL != texture);
     // FBO 0 can't also be a texture, right?
@@ -74,7 +74,7 @@
                 MakeDesc(kNone_GrTextureFlags,
                          viewport.fWidth, viewport.fHeight,
                          desc.fConfig, desc.fSampleCnt),
-                kBottomLeft_Origin) {
+                kBottomLeft_GrSurfaceOrigin) {
     this->init(desc, viewport, NULL);
 }
 
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 5c588e7..3ec555a 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -28,7 +28,7 @@
                                       textureDesc.fIsWrapped));
 
     if (NULL != rtDesc) {
-        GrAssert(kBottomLeft_Origin == textureDesc.fOrigin);
+        GrAssert(kBottomLeft_GrSurfaceOrigin == textureDesc.fSurfaceOrigin);
         GrGLIRect vp;
         vp.fLeft   = 0;
         vp.fWidth  = textureDesc.fWidth;
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index 527bab0..2314821 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -59,7 +59,7 @@
     struct Desc : public GrTextureDesc {
         GrGLuint        fTextureID;
         bool            fIsWrapped;
-        Origin          fOrigin;
+        GrSurfaceOrigin fOrigin;
     };
 
     // creates a texture that is also an RT
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 670f6ac..a1a5bee 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -485,6 +485,12 @@
         return NULL;
     }
 
+    // FIXME:  add support for TopLeft RT's by flipping all draws.
+    if (desc.fFlags & kRenderTarget_GrBackendTextureFlag &&
+        kBottomLeft_GrSurfaceOrigin != desc.fOrigin) {
+        return NULL;
+    }
+
     int maxSize = this->getCaps().maxTextureSize();
     if (desc.fWidth > maxSize || desc.fHeight > maxSize) {
         return NULL;
@@ -499,7 +505,7 @@
     glTexDesc.fSampleCnt = desc.fSampleCnt;
     glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
     glTexDesc.fIsWrapped = true;
-    glTexDesc.fOrigin = GrSurface::kBottomLeft_Origin;
+    glTexDesc.fOrigin = desc.fOrigin;
 
     GrGLTexture* texture = NULL;
     if (desc.fFlags & kRenderTarget_GrBackendTextureFlag) {
@@ -675,7 +681,7 @@
     bool swFlipY = false;
     bool glFlipY = false;
     if (NULL != data) {
-        if (GrSurface::kBottomLeft_Origin == desc.fOrigin) {
+        if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
             if (this->glCaps().unpackFlipYSupport()) {
                 glFlipY = true;
             } else {
@@ -957,7 +963,7 @@
     // We keep GrRenderTargets in GL's normal orientation so that they
     // can be drawn to by the outside world without the client having
     // to render upside down.
-    glTexDesc.fOrigin = renderTarget ? GrSurface::kBottomLeft_Origin : GrSurface::kTopLeft_Origin;
+    glTexDesc.fOrigin = renderTarget ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
 
     glRTDesc.fSampleCnt = desc.fSampleCnt;
     if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() &&