5fd7d5c20a
Before, gradients would only interpolate the linear portion of the quadratic equation if there was no perspective. This updates them to do so even in the case that there is perspective. The rearrangement of math causes noise differences in the following gm tests: gradients_no_texture_gpu gradients_view_perspective_gpu gradients_local_perspective_gpu gradients_gpu R=bsalomon@google.com Author: cdalton@nvidia.com Review URL: https://codereview.chromium.org/25645006 git-svn-id: http://skia.googlecode.com/svn/trunk@11595 2bbb7eff-a529-9590-31e7-b0007b416f81
120 lines
3.9 KiB
C++
120 lines
3.9 KiB
C++
/*
|
|
* Copyright 2013 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef GrCoordTransform_DEFINED
|
|
#define GrCoordTransform_DEFINED
|
|
|
|
#include "GrEffect.h"
|
|
#include "SkMatrix.h"
|
|
#include "GrTexture.h"
|
|
#include "GrTypes.h"
|
|
|
|
/**
|
|
* Coordinates available to GrEffect subclasses for requesting transformations. Transformed
|
|
* coordinates are made available in the the portion of fragment shader emitted by the effect.
|
|
*/
|
|
enum GrCoordSet {
|
|
/**
|
|
* The user-space coordinates that map to the fragment being rendered. These coords account for
|
|
* any change of coordinate system done on the CPU by GrContext before rendering, and also are
|
|
* correct for draws that take explicit local coords rather than inferring them from the
|
|
* primitive's positions (e.g. drawVertices). These are usually the coords a GrEffect wants.
|
|
*/
|
|
kLocal_GrCoordSet,
|
|
|
|
/**
|
|
* The actual vertex position. Note that GrContext may not draw using the original view matrix
|
|
* specified by the caller, as it may have transformed vertices into another space. These are
|
|
* usually not the coordinates a GrEffect wants.
|
|
*/
|
|
kPosition_GrCoordSet
|
|
};
|
|
|
|
/**
|
|
* A class representing a linear transformation from one of the built-in coordinate sets (local or
|
|
* position). GrEffects just define these transformations, and the framework does the rest of the
|
|
* work to make the transformed coordinates available in their fragment shader.
|
|
*/
|
|
class GrCoordTransform : public SkNoncopyable {
|
|
public:
|
|
GrCoordTransform() { SkDEBUGCODE(fInEffect = false); }
|
|
|
|
/**
|
|
* Create a transformation that maps [0, 1] to a texture's boundaries.
|
|
*/
|
|
GrCoordTransform(GrCoordSet sourceCoords, const GrTexture* texture) {
|
|
SkDEBUGCODE(fInEffect = false);
|
|
this->reset(sourceCoords, texture);
|
|
}
|
|
|
|
/**
|
|
* Create a transformation from a matrix. The optional texture parameter is used to infer if the
|
|
* framework should internally do a y reversal to account for it being upside down by Skia's
|
|
* coord convention.
|
|
*/
|
|
GrCoordTransform(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
|
|
SkDEBUGCODE(fInEffect = false);
|
|
this->reset(sourceCoords, m, texture);
|
|
}
|
|
|
|
void reset(GrCoordSet sourceCoords, const GrTexture* texture) {
|
|
SkASSERT(!fInEffect);
|
|
SkASSERT(NULL != texture);
|
|
this->reset(sourceCoords, GrEffect::MakeDivByTextureWHMatrix(texture), texture);
|
|
}
|
|
|
|
void reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture = NULL) {
|
|
SkASSERT(!fInEffect);
|
|
fSourceCoords = sourceCoords;
|
|
fMatrix = m;
|
|
fReverseY = NULL != texture && kBottomLeft_GrSurfaceOrigin == texture->origin();
|
|
}
|
|
|
|
GrCoordTransform& operator= (const GrCoordTransform& other) {
|
|
SkASSERT(!fInEffect);
|
|
fSourceCoords = other.fSourceCoords;
|
|
fMatrix = other.fMatrix;
|
|
fReverseY = other.fReverseY;
|
|
return *this;
|
|
}
|
|
|
|
/**
|
|
* Access the matrix for editing. Note, this must be done before adding the transform to an
|
|
* effect, since effects are immutable.
|
|
*/
|
|
SkMatrix* accessMatrix() {
|
|
SkASSERT(!fInEffect);
|
|
return &fMatrix;
|
|
}
|
|
|
|
bool operator== (const GrCoordTransform& other) const {
|
|
return fSourceCoords == other.fSourceCoords &&
|
|
fMatrix.cheapEqualTo(other.fMatrix) &&
|
|
fReverseY == other.fReverseY;
|
|
}
|
|
|
|
GrCoordSet sourceCoords() const { return fSourceCoords; }
|
|
const SkMatrix& getMatrix() const { return fMatrix; }
|
|
bool reverseY() const { return fReverseY; }
|
|
|
|
private:
|
|
GrCoordSet fSourceCoords;
|
|
SkMatrix fMatrix;
|
|
bool fReverseY;
|
|
|
|
typedef SkNoncopyable INHERITED;
|
|
|
|
#ifdef SK_DEBUG
|
|
public:
|
|
void setInEffect() const { fInEffect = true; }
|
|
private:
|
|
mutable bool fInEffect;
|
|
#endif
|
|
};
|
|
|
|
#endif
|