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
This commit is contained in:
parent
28a15fb8d6
commit
2d0baded0f
@ -40,7 +40,7 @@ public:
|
||||
|
||||
// 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 @@ public:
|
||||
/**
|
||||
* 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 @@ public:
|
||||
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
|
||||
|
@ -33,6 +33,22 @@ public:
|
||||
*/
|
||||
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
|
||||
@ -66,7 +82,7 @@ public:
|
||||
* @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 @@ public:
|
||||
* @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 @@ public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -146,8 +146,8 @@ protected:
|
||||
// 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
|
||||
|
@ -457,7 +457,7 @@ struct GrTextureDesc {
|
||||
* 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;
|
||||
};
|
||||
|
@ -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 @@ GrGLEffect::EffectKey GrGLLightingEffect::GenKey(const GrEffect& s,
|
||||
|
||||
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());
|
||||
|
@ -428,7 +428,7 @@ void GrGLMatrixConvolutionEffect::setData(const GrGLUniformManager& uman,
|
||||
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);
|
||||
|
@ -351,7 +351,7 @@ GrGLEffect::EffectKey GrGLMorphologyEffect::GenKey(const GrEffect& s,
|
||||
|
||||
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 };
|
||||
|
@ -71,8 +71,7 @@ void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEf
|
||||
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
|
||||
|
@ -83,7 +83,7 @@ GrGLProgram::GrGLProgram(const GrGLContextInfo& gl,
|
||||
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);
|
||||
|
@ -248,10 +248,9 @@ private:
|
||||
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];
|
||||
|
||||
|
@ -49,7 +49,9 @@ GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
|
||||
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 @@ GrGLRenderTarget::GrGLRenderTarget(GrGpuGL* gpu,
|
||||
NULL,
|
||||
MakeDesc(kNone_GrTextureFlags,
|
||||
viewport.fWidth, viewport.fHeight,
|
||||
desc.fConfig, desc.fSampleCnt)) {
|
||||
desc.fConfig, desc.fSampleCnt),
|
||||
kBottomLeft_Origin) {
|
||||
this->init(desc, viewport, NULL);
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ public:
|
||||
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 @@ private:
|
||||
// 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;
|
||||
|
@ -26,10 +26,9 @@ void GrGLTexture::init(GrGpuGL* gpu,
|
||||
(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 @@ void GrGLTexture::init(GrGpuGL* gpu,
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -48,11 +48,6 @@ private:
|
||||
class GrGLTexture : public GrTexture {
|
||||
|
||||
public:
|
||||
enum Orientation {
|
||||
kBottomUp_Orientation,
|
||||
kTopDown_Orientation,
|
||||
};
|
||||
|
||||
struct TexParams {
|
||||
GrGLenum fFilter;
|
||||
GrGLenum fWrapS;
|
||||
@ -64,7 +59,7 @@ public:
|
||||
struct Desc : public GrTextureDesc {
|
||||
GrGLuint fTextureID;
|
||||
bool fOwnsID;
|
||||
Orientation fOrientation;
|
||||
Origin fOrigin;
|
||||
};
|
||||
|
||||
// creates a texture that is also an RT
|
||||
@ -95,16 +90,6 @@ public:
|
||||
}
|
||||
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 @@ private:
|
||||
TexParams fTexParams;
|
||||
GrGpu::ResetTimestamp fTexParamsTimestamp;
|
||||
GrGLTexID* fTexIDObj;
|
||||
Orientation fOrientation;
|
||||
|
||||
void init(GrGpuGL* gpu,
|
||||
const Desc& textureDesc,
|
||||
|
@ -490,7 +490,7 @@ GrTexture* GrGpuGL::onWrapBackendTexture(const GrBackendTextureDesc& desc) {
|
||||
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 @@ void GrGpuGL::onWriteTexturePixels(GrTexture* texture,
|
||||
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 GrGpuGL::uploadTexData(const GrGLTexture::Desc& desc,
|
||||
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 @@ GrTexture* GrGpuGL::onCreateTexture(const GrTextureDesc& desc,
|
||||
// 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() &&
|
||||
|
@ -146,8 +146,7 @@ private:
|
||||
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.
|
||||
|
@ -161,19 +161,15 @@ void GrGpuGL::flushViewMatrix(DrawType type) {
|
||||
|
||||
// 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 @@ int GrGpuGL::TextureMatrixOptFlags(const GrGLTexture* texture,
|
||||
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 @@ void GrGpuGL::flushTextureMatrix(int s) {
|
||||
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 @@ void GrGpuGL::flushTextureMatrix(int s) {
|
||||
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 @@ void GrGpuGL::flushTextureMatrix(int s) {
|
||||
fCurrentProgram->fTextureMatrices[s] = samplerMatrix;
|
||||
}
|
||||
|
||||
fCurrentProgram->fTextureOrientation[s] = texture->orientation();
|
||||
fCurrentProgram->fTextureOrigin[s] = texture->origin();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user