Make the orientation of a texture accessible from and known by GrSurface.

R=robertphillips@google.com
Review URL: https://codereview.appspot.com/6801044

git-svn-id: http://skia.googlecode.com/svn/branches/gpu_dev@6148 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index 58a3aa5..2a6e62a 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -40,7 +40,7 @@
 
     // GrSurface overrides
     /**
-     * @return the texture associated with the rendertarget, may be NULL.
+     * @return the texture associated with the render target, may be NULL.
      */
     virtual GrTexture* asTexture() SK_OVERRIDE { return fTexture; }
     virtual const GrTexture* asTexture() const SK_OVERRIDE { return fTexture; }
@@ -75,7 +75,7 @@
     /**
      * If this RT is multisampled, this is the buffer it is resolved to.
      * Otherwise, same as getRenderTargetHandle().
-     * (In GL a separate FBO ID is used for the msaa and resolved buffers)
+     * (In GL a separate FBO ID is used for the MSAA and resolved buffers)
      * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
      */
     virtual GrBackendObject getRenderTargetResolvedHandle() const = 0;
@@ -150,15 +150,16 @@
 protected:
     GrRenderTarget(GrGpu* gpu,
                    GrTexture* texture,
-                   const GrTextureDesc& desc)
-        : INHERITED(gpu, desc)
+                   const GrTextureDesc& desc,
+                   Origin origin)
+        : INHERITED(gpu, desc, origin)
         , fStencilBuffer(NULL)
         , fTexture(texture) {
         fResolveRect.setLargestInverted();
     }
 
     friend class GrTexture;
-    // When a texture unrefs an owned rendertarget this func
+    // When a texture unrefs an owned render target this func
     // removes the back pointer. This could be called from
     // texture's destructor but would have to be done in derived
     // classes. By the time of texture base destructor it has already
diff --git a/include/gpu/GrSurface.h b/include/gpu/GrSurface.h
index aa237ae..d7aa267 100644
--- a/include/gpu/GrSurface.h
+++ b/include/gpu/GrSurface.h
@@ -34,6 +34,22 @@
     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);
+        return fOrigin;
+    }
+
+    /**
      * Retrieves the pixel config specified when the surface was created.
      * For render targets this can be kUnknown_GrPixelConfig
      * if client asked us to render to a target that has a pixel
@@ -66,7 +82,7 @@
      * @param height        height of rectangle to read in pixels.
      * @param config        the pixel config of the destination buffer
      * @param buffer        memory to read the rectangle into.
-     * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
+     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
      *                      packed.
      * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
      *
@@ -88,7 +104,7 @@
      * @param height        height of rectangle to write in pixels.
      * @param config        the pixel config of the source buffer
      * @param buffer        memory to read the rectangle from.
-     * @param rowBytes      number of bytes bewtween consecutive rows. Zero means rows are tightly
+     * @param rowBytes      number of bytes between consecutive rows. Zero means rows are tightly
      *                      packed.
      * @param pixelOpsFlags See the GrContext::PixelOpsFlags enum.
      */
@@ -99,14 +115,17 @@
                              uint32_t pixelOpsFlags = 0) = 0;
 
 protected:
-    GrTextureDesc fDesc;
-
-    GrSurface(GrGpu* gpu, const GrTextureDesc& desc)
+    GrSurface(GrGpu* gpu, const GrTextureDesc& desc, Origin origin)
     : INHERITED(gpu)
-    , fDesc(desc) {
+    , fDesc(desc)
+    , fOrigin(origin) {
     }
 
+    GrTextureDesc fDesc;
+
 private:
+    Origin fOrigin;
+
     typedef GrResource INHERITED;
 };
 
diff --git a/include/gpu/GrTexture.h b/include/gpu/GrTexture.h
index a8d67e7..65950a6 100644
--- a/include/gpu/GrTexture.h
+++ b/include/gpu/GrTexture.h
@@ -146,8 +146,8 @@
                                    // base class cons sets to NULL
                                    // subclass cons can create and set
 
-    GrTexture(GrGpu* gpu, const GrTextureDesc& desc)
-    : INHERITED(gpu, desc)
+    GrTexture(GrGpu* gpu, const GrTextureDesc& desc, Origin origin)
+    : INHERITED(gpu, desc, origin)
     , fRenderTarget(NULL) {
 
         // only make sense if alloc size is pow2
diff --git a/include/gpu/GrTypes.h b/include/gpu/GrTypes.h
index 8bd1f2f..9723868 100644
--- a/include/gpu/GrTypes.h
+++ b/include/gpu/GrTypes.h
@@ -457,7 +457,7 @@
      * applies if the kRenderTarget_GrTextureFlagBit is set. The actual number
      * of samples may not exactly match the request. The request will be rounded
      * up to the next supported sample count, or down if it is larger than the
-     * max supportex count.
+     * max supported count.
      */
     int                    fSampleCnt;
 };
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 803acaa..bf91295 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -17,7 +17,6 @@
 #include "GrBackendEffectFactory.h"
 #include "effects/GrSingleTextureEffect.h"
 #include "gl/GrGLEffect.h"
-#include "gl/GrGLTexture.h"
 #include "GrEffect.h"
 
 class GrGLDiffuseLightingEffect;
@@ -1175,8 +1174,8 @@
 
 void GrGLLightingEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
     const GrLightingEffect& effect =static_cast<const GrLightingEffect&>(*stage.getEffect());
-    GrGLTexture* texture = static_cast<GrGLTexture*>(effect.texture(0));
-    float ySign = texture->orientation() == GrGLTexture::kTopDown_Orientation ? -1.0f : 1.0f;
+    GrTexture* texture = effect.texture(0);
+    float ySign = texture->origin() == GrSurface::kTopLeft_Origin ? -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 1b8efcf..f5422c0 100644
--- a/src/effects/SkMatrixConvolutionImageFilter.cpp
+++ b/src/effects/SkMatrixConvolutionImageFilter.cpp
@@ -428,7 +428,7 @@
                                           const GrEffectStage& stage) {
     const GrMatrixConvolutionEffect& effect =
         static_cast<const GrMatrixConvolutionEffect&>(*stage.getEffect());
-    GrGLTexture& texture = *static_cast<GrGLTexture*>(effect.texture(0));
+    GrTexture& texture = *effect.texture(0);
     // the code we generated was for a specific kernel size
     GrAssert(effect.kernelSize() == fKernelSize);
     GrAssert(effect.tileMode() == fTileMode);
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index f561eaa..9fa46e2 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -351,7 +351,7 @@
 
 void GrGLMorphologyEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
     const Gr1DKernelEffect& kern = static_cast<const Gr1DKernelEffect&>(*stage.getEffect());
-    GrGLTexture& texture = *static_cast<GrGLTexture*>(kern.texture(0));
+    GrTexture& texture = *kern.texture(0);
     // the code we generated was for a specific kernel radius
     GrAssert(kern.radius() == fRadius);
     float imageIncrement[2] = { 0 };
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
index 9afddcc..4c9c44d 100644
--- a/src/gpu/effects/GrTextureDomainEffect.cpp
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -71,8 +71,7 @@
         GrScalarToFloat(domain.bottom())
     };
     // vertical flip if necessary
-    const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect.texture(0));
-    if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
+    if (GrSurface::kBottomLeft_Origin == 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/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index 324fdc1..35867c2 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -83,7 +83,7 @@
         fEffects[s] = NULL;
         fTextureMatrices[s] = GrMatrix::InvalidMatrix();
         // this is arbitrary, just initialize to something
-        fTextureOrientation[s] = GrGLTexture::kBottomUp_Orientation;
+        fTextureOrigin[s] = GrSurface::kBottomLeft_Origin;
     }
 
     this->genProgram(effects);
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 8adcd62..5fad7cc 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -248,10 +248,9 @@
     GrColor                     fCoverage;
     GrColor                     fColorFilterColor;
     int                         fRTHeight;
-    /// When it is sent to GL, the texture matrix will be flipped if the texture orientation
-    /// (below) requires.
+    /// When it is sent to GL, the texture matrix will be flipped if the texture origin requires.
     GrMatrix                    fTextureMatrices[GrDrawState::kNumStages];
-    GrGLTexture::Orientation    fTextureOrientation[GrDrawState::kNumStages];
+    GrSurface::Origin           fTextureOrigin[GrDrawState::kNumStages];
 
     GrGLEffect*                 fEffects[GrDrawState::kNumStages];
 
diff --git a/src/gpu/gl/GrGLRenderTarget.cpp b/src/gpu/gl/GrGLRenderTarget.cpp
index 3e72757..9bbc842 100644
--- a/src/gpu/gl/GrGLRenderTarget.cpp
+++ b/src/gpu/gl/GrGLRenderTarget.cpp
@@ -49,7 +49,9 @@
                 texture,
                 MakeDesc(kNone_GrTextureFlags,
                          viewport.fWidth, viewport.fHeight,
-                         desc.fConfig, desc.fSampleCnt)) {
+                         desc.fConfig, desc.fSampleCnt),
+                texture->origin()) {
+    GrAssert(kBottomLeft_Origin == texture->origin());
     GrAssert(NULL != texID);
     GrAssert(NULL != texture);
     // FBO 0 can't also be a texture, right?
@@ -70,7 +72,8 @@
                 NULL,
                 MakeDesc(kNone_GrTextureFlags,
                          viewport.fWidth, viewport.fHeight,
-                         desc.fConfig, desc.fSampleCnt)) {
+                         desc.fConfig, desc.fSampleCnt),
+                kBottomLeft_Origin) {
     this->init(desc, viewport, NULL);
 }
 
diff --git a/src/gpu/gl/GrGLRenderTarget.h b/src/gpu/gl/GrGLRenderTarget.h
index 64b0d21..11a877f 100644
--- a/src/gpu/gl/GrGLRenderTarget.h
+++ b/src/gpu/gl/GrGLRenderTarget.h
@@ -51,7 +51,7 @@
     const GrGLIRect& getViewport() const { return fViewport; }
 
     // The following two functions return the same ID when a
-    // texture-rendertarget is multisampled, and different IDs when
+    // texture/render target is multisampled, and different IDs when
     // it is.
     // FBO ID used to render into
     GrGLuint renderFBOID() const { return fRTFBOID; }
@@ -93,7 +93,7 @@
     // else own them.
     bool        fOwnIDs;
 
-    // when we switch to this rendertarget we want to set the viewport to
+    // when we switch to this render target we want to set the viewport to
     // only render to to content area (as opposed to the whole allocation) and
     // we want the rendering to be at top left (GL has origin in bottom left)
     GrGLIRect fViewport;
diff --git a/src/gpu/gl/GrGLTexture.cpp b/src/gpu/gl/GrGLTexture.cpp
index 0aa4884..c1821b2 100644
--- a/src/gpu/gl/GrGLTexture.cpp
+++ b/src/gpu/gl/GrGLTexture.cpp
@@ -26,10 +26,9 @@
                                      (GPUGL->glInterface(),
                                       textureDesc.fTextureID,
                                       textureDesc.fOwnsID));
-    fOrientation        = textureDesc.fOrientation;
-
+    
     if (NULL != rtDesc) {
-        // we render to the top left
+        GrAssert(kBottomLeft_Origin == textureDesc.fOrigin);
         GrGLIRect vp;
         vp.fLeft   = 0;
         vp.fWidth  = textureDesc.fWidth;
@@ -43,14 +42,14 @@
 
 GrGLTexture::GrGLTexture(GrGpuGL* gpu,
                          const Desc& textureDesc)
-    : INHERITED(gpu, textureDesc) {
+    : INHERITED(gpu, textureDesc, textureDesc.fOrigin) {
     this->init(gpu, textureDesc, NULL);
 }
 
 GrGLTexture::GrGLTexture(GrGpuGL* gpu,
                          const Desc& textureDesc,
                          const GrGLRenderTarget::Desc& rtDesc)
-    : INHERITED(gpu, textureDesc) {
+    : INHERITED(gpu, textureDesc, textureDesc.fOrigin) {
     this->init(gpu, textureDesc, &rtDesc);
 }
 
diff --git a/src/gpu/gl/GrGLTexture.h b/src/gpu/gl/GrGLTexture.h
index a2e4af2..4666bfb 100644
--- a/src/gpu/gl/GrGLTexture.h
+++ b/src/gpu/gl/GrGLTexture.h
@@ -48,11 +48,6 @@
 class GrGLTexture : public GrTexture {
 
 public:
-    enum Orientation {
-        kBottomUp_Orientation,
-        kTopDown_Orientation,
-    };
-
     struct TexParams {
         GrGLenum fFilter;
         GrGLenum fWrapS;
@@ -64,7 +59,7 @@
     struct Desc : public GrTextureDesc {
         GrGLuint        fTextureID;
         bool            fOwnsID;
-        Orientation     fOrientation;
+        Origin          fOrigin;
     };
 
     // creates a texture that is also an RT
@@ -95,16 +90,6 @@
     }
     GrGLuint textureID() const { return fTexIDObj->id(); }
 
-    // Ganesh assumes texture coordinates have their origin
-    // in the top-left corner of the image. OpenGL, however,
-    // has the origin in the lower-left corner. For content that
-    // is loaded by Ganesh we just push the content "upside down"
-    // (by GL's understanding of the world) in glTex*Image and the
-    // addressing just works out. However, content generated by GL
-    // (FBO or externally imported texture) will be updside down
-    // and it is up to the GrGpuGL derivative to handle y-mirroing.
-    Orientation orientation() const { return fOrientation; }
-
 protected:
 
     // overrides of GrTexture
@@ -115,7 +100,6 @@
     TexParams                       fTexParams;
     GrGpu::ResetTimestamp           fTexParamsTimestamp;
     GrGLTexID*                      fTexIDObj;
-    Orientation                     fOrientation;
 
     void init(GrGpuGL* gpu,
               const Desc& textureDesc,
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 04d0f8e..28963f1 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -490,7 +490,7 @@
     glTexDesc.fSampleCnt = desc.fSampleCnt;
     glTexDesc.fTextureID = static_cast<GrGLuint>(desc.fTextureHandle);
     glTexDesc.fOwnsID = false;
-    glTexDesc.fOrientation = GrGLTexture::kBottomUp_Orientation;
+    glTexDesc.fOrigin = GrSurface::kBottomLeft_Origin;
 
     GrGLTexture* texture = NULL;
     if (desc.fFlags & kRenderTarget_GrBackendTextureFlag) {
@@ -574,7 +574,7 @@
     desc.fConfig = glTex->config();
     desc.fSampleCnt = glTex->desc().fSampleCnt;
     desc.fTextureID = glTex->textureID();
-    desc.fOrientation = glTex->orientation();
+    desc.fOrigin = glTex->origin();
 
     this->uploadTexData(desc, false,
                         left, top, width, height,
@@ -665,7 +665,7 @@
     bool swFlipY = false;
     bool glFlipY = false;
     if (NULL != data) {
-        if (GrGLTexture::kBottomUp_Orientation == desc.fOrientation) {
+        if (GrSurface::kBottomLeft_Origin == desc.fOrigin) {
             if (this->glCaps().unpackFlipYSupport()) {
                 glFlipY = true;
             } else {
@@ -948,8 +948,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.fOrientation = renderTarget ? GrGLTexture::kBottomUp_Orientation :
-                                            GrGLTexture::kTopDown_Orientation;
+    glTexDesc.fOrigin = renderTarget ? GrSurface::kBottomLeft_Origin : GrSurface::kTopLeft_Origin;
 
     glRTDesc.fSampleCnt = desc.fSampleCnt;
     if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() &&
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 4985d99..466c4a7 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -146,8 +146,7 @@
     const GrGLContextInfo& glContextInfo() const { return fGLContextInfo; }
 
     // adjusts texture matrix to account for orientation
-    static void AdjustTextureMatrix(const GrGLTexture* texture,
-                                    GrMatrix* matrix);
+    static void AdjustTextureMatrix(const GrTexture* texture, GrMatrix* matrix);
 
     // This helper determines if what optimizations can be applied to the matrix after any coord
     // adjustments are applied. The return is a bitfield of GrGLProgram::StageDesc::OptFlags.
diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp
index 3be5afc..ba36abe 100644
--- a/src/gpu/gl/GrGpuGL_program.cpp
+++ b/src/gpu/gl/GrGpuGL_program.cpp
@@ -161,19 +161,15 @@
 
 // helpers for texture matrices
 
-void GrGpuGL::AdjustTextureMatrix(const GrGLTexture* texture,
-                                  GrMatrix* matrix) {
+void GrGpuGL::AdjustTextureMatrix(const GrTexture* texture, GrMatrix* matrix) {
     GrAssert(NULL != texture);
     GrAssert(NULL != matrix);
-    GrGLTexture::Orientation orientation = texture->orientation();
-    if (GrGLTexture::kBottomUp_Orientation == orientation) {
+    if (GrSurface::kBottomLeft_Origin == texture->origin()) {
         GrMatrix invY;
         invY.setAll(GR_Scalar1, 0,           0,
                     0,          -GR_Scalar1, GR_Scalar1,
                     0,          0,           GrMatrix::I()[8]);
         matrix->postConcat(invY);
-    } else {
-        GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
     }
 }
 
@@ -183,7 +179,7 @@
     GrMatrix matrix;
     stage.getTotalMatrix(&matrix);
 
-    bool canBeIndentity = GrGLTexture::kTopDown_Orientation == texture->orientation();
+    bool canBeIndentity = GrSurface::kTopLeft_Origin == texture->origin();
 
     if (canBeIndentity && matrix.isIdentity()) {
         return GrGLProgram::StageDesc::kIdentityMatrix_OptFlagBit;
@@ -206,8 +202,7 @@
     const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect->texture(0));
     if (NULL != texture) {
 
-        bool orientationChange = fCurrentProgram->fTextureOrientation[s] !=
-                                 texture->orientation();
+        bool originChange = fCurrentProgram->fTextureOrigin[s] != texture->origin();
 
         UniformHandle matrixUni = fCurrentProgram->fUniforms.fStages[s].fTextureMatrixUni;
 
@@ -216,7 +211,7 @@
         drawState.getStage(s).getTotalMatrix(&samplerMatrix);
 
         if (kInvalidUniformHandle != matrixUni &&
-            (orientationChange || !hwMatrix.cheapEqualTo(samplerMatrix))) {
+            (originChange || !hwMatrix.cheapEqualTo(samplerMatrix))) {
 
             GrMatrix m = samplerMatrix;
             AdjustTextureMatrix(texture, &m);
@@ -239,7 +234,7 @@
             fCurrentProgram->fTextureMatrices[s] = samplerMatrix;
         }
 
-        fCurrentProgram->fTextureOrientation[s] = texture->orientation();
+        fCurrentProgram->fTextureOrigin[s] = texture->origin();
     }
 }