Remove notion of default rendertarget. This doesn't map well to usage patterns outside sample app. Make binding between SkGpuDevice and a GrRenderTarget more explicit. Create method on GrContext to wrap the current target in the 3D API with a GrRenderTarget.
git-svn-id: http://skia.googlecode.com/svn/trunk@706 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
44b2c73ca6
commit
2e7b43d33c
@ -41,7 +41,7 @@ public:
|
||||
* Helper to create a opengl-shader based context
|
||||
*/
|
||||
static GrContext* CreateGLShaderContext();
|
||||
|
||||
|
||||
virtual ~GrContext();
|
||||
|
||||
/**
|
||||
@ -114,6 +114,19 @@ public:
|
||||
GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
|
||||
int width, int height);
|
||||
|
||||
/**
|
||||
* Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
|
||||
* viewport state from the underlying 3D API and wraps it in a
|
||||
* GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
|
||||
* underlying object in its destructor and it is up to caller to guarantee
|
||||
* that it remains valid while the GrRenderTarget is used.
|
||||
*
|
||||
* @return the newly created GrRenderTarget
|
||||
*/
|
||||
GrRenderTarget* createRenderTargetFrom3DApiState() {
|
||||
return fGpu->createRenderTargetFrom3DApiState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified use of an indexed texture is supported.
|
||||
*/
|
||||
@ -126,8 +139,6 @@ public:
|
||||
const GrClip& getClip() const { return fGpu->getClip(); }
|
||||
|
||||
void setRenderTarget(GrRenderTarget* target);
|
||||
void setDefaultRenderTargetSize(uint32_t width, uint32_t height);
|
||||
GrRenderTarget* defaultRenderTarget() { return fGpu->defaultRenderTarget(); }
|
||||
|
||||
void setTexture(int stage, GrTexture* texture);
|
||||
void setSamplerState(int stage, const GrSamplerState&);
|
||||
|
@ -196,6 +196,17 @@ public:
|
||||
intptr_t platformRenderTarget,
|
||||
int width, int height) = 0;
|
||||
|
||||
/**
|
||||
* Reads the current target object (e.g. FBO or IDirect3DSurface9*) and
|
||||
* viewport state from the underlying 3D API and wraps it in a
|
||||
* GrRenderTarget. The GrRenderTarget will not attempt to delete/destroy the
|
||||
* underlying object in its destructor and it is up to caller to guarantee
|
||||
* that it remains valid while the GrRenderTarget is used.
|
||||
*
|
||||
* @return the newly created GrRenderTarget
|
||||
*/
|
||||
virtual GrRenderTarget* createRenderTargetFrom3DApiState() = 0;
|
||||
|
||||
/**
|
||||
* Creates a vertex buffer.
|
||||
*
|
||||
@ -220,21 +231,6 @@ public:
|
||||
*/
|
||||
virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic) = 0;
|
||||
|
||||
/**
|
||||
* Gets the default render target. This is the render target set in the
|
||||
* 3D API at the time the GrGpu was created.
|
||||
*/
|
||||
virtual GrRenderTarget* defaultRenderTarget() = 0;
|
||||
|
||||
/**
|
||||
* At construction time the GrGpu infers the render target and viewport from
|
||||
* the state of the underlying 3D API. However, a platform-specific resize
|
||||
* event may occur.
|
||||
* @param width new width of the default rendertarget
|
||||
* @param height new height of the default rendertarget
|
||||
*/
|
||||
virtual void setDefaultRenderTargetSize(uint32_t width, uint32_t height) = 0;
|
||||
|
||||
/**
|
||||
* Erase the entire render target, ignoring any clips/scissors.
|
||||
*
|
||||
|
@ -30,8 +30,8 @@ static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024;
|
||||
|
||||
#if DEFER_TEXT_RENDERING
|
||||
static const uint32_t POOL_VB_SIZE = 2048 *
|
||||
GrDrawTarget::VertexSize(
|
||||
GrDrawTarget::kTextFormat_VertexLayoutBit |
|
||||
GrDrawTarget::VertexSize(
|
||||
GrDrawTarget::kTextFormat_VertexLayoutBit |
|
||||
GrDrawTarget::StageTexCoordVertexLayoutBit(0,0));
|
||||
static const uint32_t NUM_POOL_VBS = 8;
|
||||
#else
|
||||
@ -856,10 +856,6 @@ GrRenderTarget* GrContext::currentRenderTarget() const {
|
||||
return fGpu->currentRenderTarget();
|
||||
}
|
||||
|
||||
void GrContext::setDefaultRenderTargetSize(uint32_t width, uint32_t height) {
|
||||
fGpu->setDefaultRenderTargetSize(width, height);
|
||||
}
|
||||
|
||||
void GrContext::setSamplerState(int stage, const GrSamplerState& samplerState) {
|
||||
fGpu->setSamplerState(stage, samplerState);
|
||||
}
|
||||
|
@ -178,6 +178,14 @@ void GrGpu::clipWillChange(const GrClip& clip) {
|
||||
bool GrGpu::setupClipAndFlushState(PrimitiveType type) {
|
||||
const GrIRect* r = NULL;
|
||||
|
||||
// we check this early because we need a valid
|
||||
// render target to setup stencil clipping
|
||||
// before even going into flushGraphicsState
|
||||
if (NULL == fCurrDrawState.fRenderTarget) {
|
||||
GrAssert(!"No render target bound.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fCurrDrawState.fFlagBits & kClip_StateBit) {
|
||||
fClipState.fClipInStencil = fClip.countRects() > 1;
|
||||
|
||||
|
@ -152,24 +152,7 @@ GrGpuGL::GrGpuGL() {
|
||||
|
||||
resetContextHelper();
|
||||
|
||||
GrGLRenderTarget::GLRenderTargetIDs defaultRTIDs;
|
||||
GR_GL_GetIntegerv(GR_FRAMEBUFFER_BINDING, (GLint*)&defaultRTIDs.fRTFBOID);
|
||||
defaultRTIDs.fTexFBOID = defaultRTIDs.fRTFBOID;
|
||||
defaultRTIDs.fMSColorRenderbufferID = 0;
|
||||
defaultRTIDs.fStencilRenderbufferID = 0;
|
||||
GLint vp[4];
|
||||
GR_GL_GetIntegerv(GL_VIEWPORT, vp);
|
||||
fHWBounds.fViewportRect.setLTRB(vp[0],
|
||||
vp[1] + vp[3],
|
||||
vp[0] + vp[2],
|
||||
vp[1]);
|
||||
defaultRTIDs.fOwnIDs = false;
|
||||
|
||||
fDefaultRenderTarget = new GrGLRenderTarget(defaultRTIDs,
|
||||
fHWBounds.fViewportRect,
|
||||
NULL,
|
||||
this);
|
||||
fHWDrawState.fRenderTarget = fDefaultRenderTarget;
|
||||
fHWDrawState.fRenderTarget = NULL;
|
||||
fRenderTargetChanged = true;
|
||||
|
||||
GLint maxTextureUnits;
|
||||
@ -445,17 +428,13 @@ GrGpuGL::GrGpuGL() {
|
||||
fMinRenderTargetWidth = GrMax<GLuint>(fMinRenderTargetWidth, 16);
|
||||
fMinRenderTargetHeight = GrMax<GLuint>(fMinRenderTargetHeight, 16);
|
||||
#endif
|
||||
// bind back to original FBO
|
||||
GR_GLEXT(fExts, BindFramebuffer(GR_FRAMEBUFFER, defaultRTIDs.fRTFBOID));
|
||||
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fRenderTargetChngCnt;
|
||||
#endif
|
||||
eraseStencil(0, ~0);
|
||||
}
|
||||
|
||||
GrGpuGL::~GrGpuGL() {
|
||||
fDefaultRenderTarget->abandon();
|
||||
fDefaultRenderTarget->unref();
|
||||
}
|
||||
|
||||
void GrGpuGL::resetContextHelper() {
|
||||
@ -501,6 +480,7 @@ void GrGpuGL::resetContextHelper() {
|
||||
fHWBounds.fScissorRect.setLTRB(0,0,0,0);
|
||||
fHWBounds.fScissorEnabled = false;
|
||||
GR_GL(Disable(GL_SCISSOR_TEST));
|
||||
fHWBounds.fViewportRect.setLTRB(-1,-1,-1,-1);
|
||||
|
||||
// disabling the stencil test also disables
|
||||
// stencil buffer writes
|
||||
@ -546,6 +526,30 @@ GrRenderTarget* GrGpuGL::createPlatformRenderTarget(
|
||||
return rt;
|
||||
}
|
||||
|
||||
GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiState() {
|
||||
|
||||
GrGLRenderTarget::GLRenderTargetIDs rtIDs;
|
||||
|
||||
GR_GL_GetIntegerv(GR_FRAMEBUFFER_BINDING, (GLint*)&rtIDs.fRTFBOID);
|
||||
rtIDs.fTexFBOID = rtIDs.fRTFBOID;
|
||||
rtIDs.fMSColorRenderbufferID = 0;
|
||||
rtIDs.fStencilRenderbufferID = 0;
|
||||
|
||||
GLint vp[4];
|
||||
GR_GL_GetIntegerv(GL_VIEWPORT, vp);
|
||||
GrIRect viewportRect;
|
||||
viewportRect.setLTRB(vp[0],
|
||||
vp[1] + vp[3],
|
||||
vp[0] + vp[2],
|
||||
vp[1]);
|
||||
rtIDs.fOwnIDs = false;
|
||||
|
||||
return new GrGLRenderTarget(rtIDs,
|
||||
viewportRect,
|
||||
NULL,
|
||||
this);
|
||||
}
|
||||
|
||||
// defines stencil formats from more to less preferred
|
||||
GLenum GR_GL_STENCIL_FORMAT_ARRAY[] = {
|
||||
GR_STENCIL_INDEX8,
|
||||
@ -979,10 +983,6 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
return tex;
|
||||
}
|
||||
|
||||
GrRenderTarget* GrGpuGL::defaultRenderTarget() {
|
||||
return fDefaultRenderTarget;
|
||||
}
|
||||
|
||||
GrVertexBuffer* GrGpuGL::createVertexBuffer(uint32_t size, bool dynamic) {
|
||||
GLuint id;
|
||||
GR_GL(GenBuffers(1, &id));
|
||||
@ -1029,16 +1029,6 @@ GrIndexBuffer* GrGpuGL::createIndexBuffer(uint32_t size, bool dynamic) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GrGpuGL::setDefaultRenderTargetSize(uint32_t width, uint32_t height) {
|
||||
GrIRect viewport(0, height, width, 0);
|
||||
if (viewport != fDefaultRenderTarget->viewport()) {
|
||||
fDefaultRenderTarget->setViewport(viewport);
|
||||
if (fHWDrawState.fRenderTarget == fDefaultRenderTarget) {
|
||||
fHWDrawState.fRenderTarget = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::flushScissor(const GrIRect* rect) {
|
||||
GrAssert(NULL != fCurrDrawState.fRenderTarget);
|
||||
const GrIRect& vp =
|
||||
@ -1153,6 +1143,9 @@ bool GrGpuGL::readPixels(int left, int top, int width, int height,
|
||||
}
|
||||
|
||||
void GrGpuGL::flushRenderTarget() {
|
||||
|
||||
GrAssert(NULL != fCurrDrawState.fRenderTarget);
|
||||
|
||||
if (fHWDrawState.fRenderTarget != fCurrDrawState.fRenderTarget) {
|
||||
GrGLRenderTarget* rt = (GrGLRenderTarget*)fCurrDrawState.fRenderTarget;
|
||||
GR_GLEXT(fExts, BindFramebuffer(GR_FRAMEBUFFER, rt->renderFBOID()));
|
||||
@ -1459,7 +1452,11 @@ void GrGpuGL::flushStencil() {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::flushGLStateCommon(PrimitiveType type) {
|
||||
bool GrGpuGL::flushGLStateCommon(PrimitiveType type) {
|
||||
|
||||
// GrGpu::setupClipAndFlushState should have already checked this
|
||||
// and bailed if not true.
|
||||
GrAssert(NULL != fCurrDrawState.fRenderTarget);
|
||||
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
bool usingTexture = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
|
||||
@ -1521,15 +1518,7 @@ void GrGpuGL::flushGLStateCommon(PrimitiveType type) {
|
||||
nextTexture->setTexParams(newTexParams);
|
||||
} else {
|
||||
GrAssert(!"Rendering with texture vert flag set but no texture");
|
||||
if (NULL != fHWDrawState.fTextures[s]) {
|
||||
setTextureUnit(s);
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, 0));
|
||||
// GrPrintf("---- bindtexture 0\n");
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fTextureChngCnt;
|
||||
#endif
|
||||
fHWDrawState.fTextures[s] = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1607,6 +1596,7 @@ void GrGpuGL::flushGLStateCommon(PrimitiveType type) {
|
||||
flushStencil();
|
||||
|
||||
fHWDrawState.fFlagBits = fCurrDrawState.fFlagBits;
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrGpuGL::notifyVertexBufferBind(const GrGLVertexBuffer* buffer) {
|
||||
@ -1645,7 +1635,7 @@ void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
|
||||
// b) we set more state than just FBO based on the RT
|
||||
// So trash the HW state to force an RT flush next time
|
||||
if (fCurrDrawState.fRenderTarget == renderTarget) {
|
||||
fCurrDrawState.fRenderTarget = fDefaultRenderTarget;
|
||||
fCurrDrawState.fRenderTarget = NULL;
|
||||
}
|
||||
if (fHWDrawState.fRenderTarget == renderTarget) {
|
||||
fHWDrawState.fRenderTarget = NULL;
|
||||
|
@ -42,9 +42,7 @@ public:
|
||||
intptr_t platformRenderTarget,
|
||||
int width, int height);
|
||||
|
||||
virtual GrRenderTarget* defaultRenderTarget();
|
||||
|
||||
virtual void setDefaultRenderTargetSize(uint32_t width, uint32_t height);
|
||||
virtual GrRenderTarget* createRenderTargetFrom3DApiState();
|
||||
|
||||
virtual void eraseColor(GrColor color);
|
||||
|
||||
@ -98,7 +96,7 @@ protected:
|
||||
// sampler state (filtering, tiling)
|
||||
// FBO binding
|
||||
// line width
|
||||
void flushGLStateCommon(PrimitiveType type);
|
||||
bool flushGLStateCommon(PrimitiveType type);
|
||||
|
||||
// set when this class changes the rendertarget.
|
||||
// Subclass should notice at flush time, take appropriate action,
|
||||
@ -114,8 +112,6 @@ protected:
|
||||
GrGLExts fExts;
|
||||
|
||||
private:
|
||||
GrGLRenderTarget* fDefaultRenderTarget;
|
||||
|
||||
void resetContextHelper();
|
||||
|
||||
// notify callbacks to update state tracking when related
|
||||
|
@ -140,7 +140,9 @@ bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
|
||||
}
|
||||
}
|
||||
|
||||
flushGLStateCommon(type);
|
||||
if (!flushGLStateCommon(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fRenderTargetChanged) {
|
||||
flushProjectionMatrix();
|
||||
|
@ -741,7 +741,9 @@ bool GrGpuGLShaders::flushGraphicsState(PrimitiveType type) {
|
||||
}
|
||||
}
|
||||
|
||||
flushGLStateCommon(type);
|
||||
if (!flushGLStateCommon(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fRenderTargetChanged) {
|
||||
// our coords are in pixel space and the GL matrices map to NDC
|
||||
|
@ -1233,7 +1233,9 @@ void GrGpuGLShaders2::flushProgram(PrimitiveType type) {
|
||||
|
||||
bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) {
|
||||
|
||||
flushGLStateCommon(type);
|
||||
if (!flushGLStateCommon(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fRenderTargetChanged) {
|
||||
// our coords are in pixel space and the GL matrices map to NDC
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "SkCanvas.h"
|
||||
|
||||
class GrContext;
|
||||
class GrRenderTarget;
|
||||
|
||||
/**
|
||||
* Subclass of canvas that creates devices compatible with the GrContext pass
|
||||
@ -32,8 +33,15 @@ public:
|
||||
* The GrContext object is reference counted. When passed to our
|
||||
* constructor, its reference count is incremented. In our destructor, the
|
||||
* GrGpu's reference count will be decremented.
|
||||
* GrRenderTarget represents the rendering destination in the underlying
|
||||
* 3D API. Its reference count is incremented in the constructor and
|
||||
* decremented in the destructor.
|
||||
* SkGpuDevice::Current3DApiRenderTarget() can be passed as a special
|
||||
* value that will cause the factory to create a render target object
|
||||
* that reflects the state of the underlying 3D API at the time of
|
||||
* construction.
|
||||
*/
|
||||
explicit SkGpuCanvas(GrContext*);
|
||||
explicit SkGpuCanvas(GrContext*, GrRenderTarget*);
|
||||
virtual ~SkGpuCanvas();
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,22 @@ class GrTextContext;
|
||||
*/
|
||||
class SkGpuDevice : public SkDevice {
|
||||
public:
|
||||
SkGpuDevice(GrContext*, const SkBitmap& bitmap, bool isLayer);
|
||||
/**
|
||||
* The SkGpuDevice will render to the GrRenderTarget, or if the paremeter is
|
||||
* null it will create its own render target and manage that target's
|
||||
* lifetime.
|
||||
*/
|
||||
SkGpuDevice(GrContext*,
|
||||
const SkBitmap& bitmap,
|
||||
GrRenderTarget* renderTargetOrNull);
|
||||
|
||||
/**
|
||||
* Magic value that can be passed to constructor. Causes
|
||||
* the device to infer rendertarget from underlying 3D API (e.g. GL or D3D).
|
||||
* This isn't a valid pointer, don't attempt to dereference.
|
||||
*/
|
||||
static GrRenderTarget* Current3DApiRenderTarget();
|
||||
|
||||
virtual ~SkGpuDevice();
|
||||
|
||||
GrContext* context() const { return fContext; }
|
||||
@ -46,14 +61,6 @@ public:
|
||||
*/
|
||||
intptr_t getLayerTextureHandle() const;
|
||||
|
||||
/**
|
||||
* Attaches the device to a rendering surface. This device will then render
|
||||
* to the surface.
|
||||
* For example, in OpenGL, the device will interpret handle as an FBO ID
|
||||
* and drawing to the device would direct GL to the FBO.
|
||||
*/
|
||||
void bindDeviceToTargetHandle(intptr_t handle);
|
||||
|
||||
// call to set the clip to the specified rect
|
||||
void scissor(const SkIRect&);
|
||||
|
||||
|
@ -26,8 +26,14 @@ public:
|
||||
/**
|
||||
* The constructor will ref() the context, passing it to each device
|
||||
* that it creates. It will be unref()'d in the destructor
|
||||
* Non-layered devices created by the factory will draw to the
|
||||
* rootRenderTarget. rootRenderTarget is ref-counted by the factory.
|
||||
* SkGpuDevice::Current3DApiRenderTarget() can be passed as a special
|
||||
* value that will cause the factory to create a render target object
|
||||
* that reflects the state of the underlying 3D API at the time of
|
||||
* construction.
|
||||
*/
|
||||
SkGpuDeviceFactory(GrContext*);
|
||||
SkGpuDeviceFactory(GrContext*, GrRenderTarget* rootRenderTarget);
|
||||
|
||||
virtual ~SkGpuDeviceFactory();
|
||||
|
||||
@ -36,6 +42,7 @@ public:
|
||||
|
||||
private:
|
||||
GrContext* fContext;
|
||||
GrRenderTarget* fRootRenderTarget;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -36,7 +36,7 @@ SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
|
||||
gHead = NULL;
|
||||
gOnce = true;
|
||||
}
|
||||
|
||||
|
||||
fChain = gHead;
|
||||
gHead = this;
|
||||
}
|
||||
@ -45,21 +45,6 @@ SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
|
||||
#define SK_USE_SHADERS
|
||||
#endif
|
||||
|
||||
static GrContext* get_global_grctx(SkOSWindow* oswin) {
|
||||
// should be pthread-local at least
|
||||
static GrContext* ctx;
|
||||
if (NULL == ctx) {
|
||||
#if defined(SK_SUPPORT_GL)
|
||||
#if defined(SK_USE_SHADERS)
|
||||
ctx = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
|
||||
#else
|
||||
ctx = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const char gCharEvtName[] = "SampleCode_Char_Event";
|
||||
@ -156,12 +141,12 @@ protected:
|
||||
virtual bool onHandleKey(SkKey key);
|
||||
virtual bool onHandleChar(SkUnichar);
|
||||
virtual void onSizeChange();
|
||||
|
||||
|
||||
virtual SkCanvas* beforeChildren(SkCanvas*);
|
||||
virtual void afterChildren(SkCanvas*);
|
||||
virtual void beforeChild(SkView* child, SkCanvas* canvas);
|
||||
virtual void afterChild(SkView* child, SkCanvas* canvas);
|
||||
|
||||
|
||||
virtual bool onEvent(const SkEvent& evt);
|
||||
virtual bool onQuery(SkEvent* evt);
|
||||
|
||||
@ -170,18 +155,21 @@ protected:
|
||||
virtual bool handleEvent(const SkEvent& evt);
|
||||
virtual bool handleKey(SkKey key);
|
||||
virtual bool handleKeyUp(SkKey key);
|
||||
|
||||
|
||||
virtual bool onClick(Click* click);
|
||||
virtual Click* onFindClickHandler(SkScalar x, SkScalar y);
|
||||
virtual bool onHandleKeyUp(SkKey key);
|
||||
#endif
|
||||
|
||||
private:
|
||||
int fCurrIndex;
|
||||
|
||||
|
||||
SkPicture* fPicture;
|
||||
SkGpuCanvas* fGpuCanvas;
|
||||
GrContext* fGrContext;
|
||||
GrRenderTarget* fGrRenderTarget;
|
||||
SkPath fClipPath;
|
||||
|
||||
|
||||
enum CanvasType {
|
||||
kRaster_CanvasType,
|
||||
kPicture_CanvasType,
|
||||
@ -196,9 +184,11 @@ private:
|
||||
bool fRotate;
|
||||
bool fScale;
|
||||
bool fRequestGrabImage;
|
||||
|
||||
|
||||
int fScrollTestX, fScrollTestY;
|
||||
|
||||
|
||||
bool make3DReady();
|
||||
|
||||
void loadView(SkView*);
|
||||
void updateTitle();
|
||||
bool nextSample();
|
||||
@ -209,13 +199,48 @@ private:
|
||||
evt->post(this->getSinkID(), ANIMATING_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static CanvasType cycle_canvastype(CanvasType);
|
||||
|
||||
typedef SkOSWindow INHERITED;
|
||||
};
|
||||
|
||||
bool SampleWindow::make3DReady() {
|
||||
|
||||
#if defined(SK_SUPPORT_GL)
|
||||
#if defined(USE_OFFSCREEN)
|
||||
// first clear the raster bitmap, so we don't see any leftover bits
|
||||
bitmap.eraseColor(0);
|
||||
// now setup our glcanvas
|
||||
attachGL(&bitmap);
|
||||
#else
|
||||
attachGL(NULL);
|
||||
#endif
|
||||
|
||||
if (NULL == fGrContext) {
|
||||
SkASSERT(NULL == fGrRenderTarget);
|
||||
#if defined(SK_USE_SHADERS)
|
||||
fGrContext = GrContext::Create(GrGpu::kOpenGL_Shaders_Engine, NULL);
|
||||
#else
|
||||
fGrContext = GrContext::Create(GrGpu::kOpenGL_Fixed_Engine, NULL);
|
||||
#endif
|
||||
if (NULL != fGrContext) {
|
||||
fGrRenderTarget = fGrContext->createRenderTargetFrom3DApiState();
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != fGrContext) {
|
||||
SkASSERT(NULL != fGrRenderTarget);
|
||||
return true;
|
||||
} else {
|
||||
detachGL();
|
||||
}
|
||||
#endif
|
||||
SkDebugf("Failed to setup 3D");
|
||||
return false;
|
||||
}
|
||||
|
||||
SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
|
||||
static const CanvasType gCT[] = {
|
||||
kPicture_CanvasType,
|
||||
@ -229,6 +254,9 @@ SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
|
||||
fPicture = NULL;
|
||||
fGpuCanvas = NULL;
|
||||
|
||||
fGrContext = NULL;
|
||||
fGrRenderTarget = NULL;
|
||||
|
||||
#ifdef DEFAULT_TO_GPU
|
||||
fCanvasType = kGPU_CanvasType;
|
||||
#else
|
||||
@ -263,6 +291,12 @@ SampleWindow::SampleWindow(void* hwnd) : INHERITED(hwnd) {
|
||||
SampleWindow::~SampleWindow() {
|
||||
delete fPicture;
|
||||
delete fGpuCanvas;
|
||||
if (NULL != fGrRenderTarget) {
|
||||
fGrRenderTarget->unref();
|
||||
}
|
||||
if (NULL != fGrContext) {
|
||||
fGrContext->unref();
|
||||
}
|
||||
}
|
||||
|
||||
static SkBitmap capture_bitmap(SkCanvas* canvas) {
|
||||
@ -275,7 +309,7 @@ static SkBitmap capture_bitmap(SkCanvas* canvas) {
|
||||
static bool bitmap_diff(SkCanvas* canvas, const SkBitmap& orig,
|
||||
SkBitmap* diff) {
|
||||
const SkBitmap& src = canvas->getDevice()->accessBitmap(false);
|
||||
|
||||
|
||||
SkAutoLockPixels alp0(src);
|
||||
SkAutoLockPixels alp1(orig);
|
||||
for (int y = 0; y < src.height(); y++) {
|
||||
@ -324,7 +358,7 @@ void SampleWindow::draw(SkCanvas* canvas) {
|
||||
this->INHERITED::draw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SkBitmap diff;
|
||||
if (bitmap_diff(canvas, orig, &diff)) {
|
||||
}
|
||||
@ -360,13 +394,13 @@ static void reverseRedAndBlue(const SkBitmap& bm) {
|
||||
SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
|
||||
SkIPoint viewport;
|
||||
bool alreadyGPU = canvas->getViewport(&viewport);
|
||||
|
||||
|
||||
if (kGPU_CanvasType != fCanvasType) {
|
||||
#ifdef SK_SUPPORT_GL
|
||||
detachGL();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
switch (fCanvasType) {
|
||||
case kRaster_CanvasType:
|
||||
canvas = this->INHERITED::beforeChildren(canvas);
|
||||
@ -376,27 +410,17 @@ SkCanvas* SampleWindow::beforeChildren(SkCanvas* canvas) {
|
||||
canvas = fPicture->beginRecording(9999, 9999);
|
||||
break;
|
||||
case kGPU_CanvasType: {
|
||||
if (!alreadyGPU) {
|
||||
if (!alreadyGPU && make3DReady()) {
|
||||
SkDevice* device = canvas->getDevice();
|
||||
const SkBitmap& bitmap = device->accessBitmap(true);
|
||||
#ifdef SK_SUPPORT_GL
|
||||
#ifdef USE_OFFSCREEN
|
||||
// first clear the raster bitmap, so we don't see any leftover bits
|
||||
bitmap.eraseColor(0);
|
||||
// now setup our glcanvas
|
||||
attachGL(&bitmap);
|
||||
#else
|
||||
attachGL(NULL);
|
||||
#endif
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
#endif
|
||||
fGpuCanvas = new SkGpuCanvas(get_global_grctx(this));
|
||||
const SkBitmap& bitmap = device->accessBitmap(true);
|
||||
|
||||
fGpuCanvas = new SkGpuCanvas(fGrContext, fGrRenderTarget);
|
||||
device = fGpuCanvas->createDevice(SkBitmap::kARGB_8888_Config,
|
||||
bitmap.width(), bitmap.height(),
|
||||
false, false);
|
||||
fGpuCanvas->setDevice(device)->unref();
|
||||
canvas = fGpuCanvas;
|
||||
|
||||
|
||||
} else {
|
||||
canvas = this->INHERITED::beforeChildren(canvas);
|
||||
}
|
||||
@ -425,7 +449,7 @@ static void paint_rgn(const SkBitmap& bm, const SkIRect& r,
|
||||
void SampleWindow::afterChildren(SkCanvas* orig) {
|
||||
if (fRequestGrabImage) {
|
||||
fRequestGrabImage = false;
|
||||
|
||||
|
||||
SkCanvas* canvas = fGpuCanvas ? fGpuCanvas : orig;
|
||||
SkDevice* device = canvas->getDevice();
|
||||
SkBitmap bitmap;
|
||||
@ -452,7 +476,7 @@ void SampleWindow::afterChildren(SkCanvas* orig) {
|
||||
SkDynamicMemoryWStream ostream;
|
||||
fPicture->serialize(&ostream);
|
||||
fPicture->unref();
|
||||
|
||||
|
||||
SkMemoryStream istream(ostream.getStream(), ostream.getOffset());
|
||||
SkPicture pict(&istream);
|
||||
orig->drawPicture(pict);
|
||||
@ -473,7 +497,7 @@ void SampleWindow::afterChildren(SkCanvas* orig) {
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// if ((fScrollTestX | fScrollTestY) != 0)
|
||||
if (false) {
|
||||
const SkBitmap& bm = orig->getDevice()->accessBitmap(true);
|
||||
@ -481,7 +505,7 @@ void SampleWindow::afterChildren(SkCanvas* orig) {
|
||||
int dy = fScrollTestY * 7;
|
||||
SkIRect r;
|
||||
SkRegion inval;
|
||||
|
||||
|
||||
r.set(50, 50, 50+100, 50+100);
|
||||
bm.scrollRect(&r, dx, dy, &inval);
|
||||
paint_rgn(bm, r, inval);
|
||||
@ -589,7 +613,7 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dx = 0xFF;
|
||||
int dy = 0xFF;
|
||||
|
||||
@ -603,11 +627,11 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
|
||||
case '9': dx = 1; dy = -1; break;
|
||||
case '3': dx = 1; dy = 1; break;
|
||||
case '1': dx = -1; dy = 1; break;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (0xFF != dx && 0xFF != dy) {
|
||||
if ((dx | dy) == 0) {
|
||||
fScrollTestX = fScrollTestY = 0;
|
||||
@ -618,7 +642,7 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
|
||||
this->inval(NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
switch (uni) {
|
||||
case 'a':
|
||||
fAnimating = !fAnimating;
|
||||
@ -659,7 +683,7 @@ bool SampleWindow::onHandleChar(SkUnichar uni) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return this->INHERITED::onHandleChar(uni);
|
||||
}
|
||||
|
||||
@ -724,7 +748,7 @@ void SampleWindow::loadView(SkView* view) {
|
||||
if (prev) {
|
||||
prev->detachFromParent();
|
||||
}
|
||||
|
||||
|
||||
if (NULL == view) {
|
||||
view = create_overview(fSamples.count(), fSamples.begin());
|
||||
}
|
||||
@ -768,12 +792,12 @@ void SampleWindow::updateTitle() {
|
||||
if (title.size() == 0) {
|
||||
title.set("<unknown>");
|
||||
}
|
||||
|
||||
|
||||
title.prepend(gCanvasTypePrefix[fCanvasType]);
|
||||
|
||||
title.prepend(" ");
|
||||
title.prepend(configToString(this->getBitmap().config()));
|
||||
|
||||
|
||||
if (fAnimating) {
|
||||
title.prepend("<A> ");
|
||||
}
|
||||
@ -795,12 +819,12 @@ void SampleWindow::onSizeChange() {
|
||||
SkView::F2BIter iter(this);
|
||||
SkView* view = iter.next();
|
||||
view->setSize(this->width(), this->height());
|
||||
|
||||
|
||||
// rebuild our clippath
|
||||
{
|
||||
const SkScalar W = this->width();
|
||||
const SkScalar H = this->height();
|
||||
|
||||
|
||||
fClipPath.reset();
|
||||
#if 0
|
||||
for (SkScalar y = SK_Scalar1; y < H; y += SkIntToScalar(32)) {
|
||||
@ -817,7 +841,7 @@ void SampleWindow::onSizeChange() {
|
||||
fClipPath.addRect(r, SkPath::kCW_Direction);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
this->updateTitle(); // to refresh our config
|
||||
}
|
||||
|
||||
@ -838,7 +862,7 @@ template <typename T> void SkTBSort(T array[], int count) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int k = 0; k < count - 1; k++) {
|
||||
SkASSERT(!(array[k+1] < array[k]));
|
||||
}
|
||||
@ -909,7 +933,7 @@ static void test() {
|
||||
for (i = 0; i < SK_ARRAY_COUNT(gRecs); i++) {
|
||||
test_rects(gRecs[i].fRects, gRecs[i].fCount);
|
||||
}
|
||||
|
||||
|
||||
SkRandom rand;
|
||||
for (i = 0; i < 10000; i++) {
|
||||
SkRegion rgn0, rgn1;
|
||||
|
@ -23,11 +23,14 @@
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkDeviceFactory* make_df(GrContext* context) {
|
||||
return SkNEW_ARGS(SkGpuDeviceFactory, (context));
|
||||
static SkDeviceFactory* make_df(GrContext* context,
|
||||
GrRenderTarget* renderTarget) {
|
||||
return SkNEW_ARGS(SkGpuDeviceFactory, (context, renderTarget));
|
||||
}
|
||||
|
||||
SkGpuCanvas::SkGpuCanvas(GrContext* context) : SkCanvas(make_df(context)) {
|
||||
SkGpuCanvas::SkGpuCanvas(GrContext* context,
|
||||
GrRenderTarget* renderTarget)
|
||||
: SkCanvas(make_df(context, renderTarget)) {
|
||||
SkASSERT(context);
|
||||
fContext = context;
|
||||
fContext->ref();
|
||||
|
@ -109,8 +109,14 @@ public:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkGpuDevice::SkGpuDevice(GrContext* context, const SkBitmap& bitmap, bool isLayer)
|
||||
: SkDevice(NULL, bitmap, false) {
|
||||
GrRenderTarget* SkGpuDevice::Current3DApiRenderTarget() {
|
||||
return (GrRenderTarget*) -1;
|
||||
}
|
||||
|
||||
SkGpuDevice::SkGpuDevice(GrContext* context,
|
||||
const SkBitmap& bitmap,
|
||||
GrRenderTarget* renderTargetOrNull)
|
||||
: SkDevice(NULL, bitmap, (NULL == renderTargetOrNull)) {
|
||||
|
||||
fNeedPrepareRenderTarget = false;
|
||||
fDrawProcs = NULL;
|
||||
@ -123,7 +129,7 @@ SkGpuDevice::SkGpuDevice(GrContext* context, const SkBitmap& bitmap, bool isLaye
|
||||
fRenderTarget = NULL;
|
||||
fNeedClear = false;
|
||||
|
||||
if (isLayer) {
|
||||
if (NULL == renderTargetOrNull) {
|
||||
SkBitmap::Config c = bitmap.config();
|
||||
if (c != SkBitmap::kRGB_565_Config) {
|
||||
c = SkBitmap::kARGB_8888_Config;
|
||||
@ -164,16 +170,13 @@ SkGpuDevice::SkGpuDevice(GrContext* context, const SkBitmap& bitmap, bool isLaye
|
||||
} else {
|
||||
GrPrintf("--- failed to create gpu-offscreen [%d %d]\n",
|
||||
this->width(), this->height());
|
||||
GrAssert(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == fRenderTarget) {
|
||||
GrAssert(NULL == fCache);
|
||||
GrAssert(NULL == fTexture);
|
||||
|
||||
fRenderTarget = fContext->currentRenderTarget();
|
||||
} else if (Current3DApiRenderTarget() == renderTargetOrNull) {
|
||||
fRenderTarget = fContext->createRenderTargetFrom3DApiState();
|
||||
} else {
|
||||
fRenderTarget = renderTargetOrNull;
|
||||
fRenderTarget->ref();
|
||||
fContext->setDefaultRenderTargetSize(this->width(), this->height());
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,26 +199,6 @@ SkGpuDevice::~SkGpuDevice() {
|
||||
}
|
||||
}
|
||||
|
||||
void SkGpuDevice::bindDeviceToTargetHandle(intptr_t handle) {
|
||||
if (fCache) {
|
||||
GrAssert(NULL != fTexture);
|
||||
GrAssert(fRenderTarget == fTexture->asRenderTarget());
|
||||
// IMPORTANT: reattach the rendertarget/tex back to the cache.
|
||||
fContext->reattachAndUnlockCachedTexture((GrTextureEntry*)fCache);
|
||||
} else if (NULL != fTexture) {
|
||||
GrAssert(!CACHE_LAYER_TEXTURES);
|
||||
fTexture->unref();
|
||||
} else if (NULL != fRenderTarget) {
|
||||
fRenderTarget->unref();
|
||||
}
|
||||
|
||||
fCache = NULL;
|
||||
fTexture = NULL;
|
||||
fRenderTarget = fContext->createPlatformRenderTarget(handle,
|
||||
this->width(),
|
||||
this->height());
|
||||
}
|
||||
|
||||
intptr_t SkGpuDevice::getLayerTextureHandle() const {
|
||||
if (fTexture) {
|
||||
return fTexture->getTextureHandle();
|
||||
@ -1050,12 +1033,29 @@ void SkGpuDevice::unlockCachedTexture(TexCache* cache) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context) : fContext(context) {
|
||||
SkGpuDeviceFactory::SkGpuDeviceFactory(GrContext* context,
|
||||
GrRenderTarget* rootRenderTarget)
|
||||
: fContext(context) {
|
||||
|
||||
GrAssert(NULL != context);
|
||||
GrAssert(NULL != rootRenderTarget);
|
||||
|
||||
// check this now rather than passing this value to SkGpuDevice cons.
|
||||
// we want the rt that is bound *now* in the 3D API, not the one
|
||||
// at the time of newDevice.
|
||||
if (SkGpuDevice::Current3DApiRenderTarget() == rootRenderTarget) {
|
||||
fRootRenderTarget = context->createRenderTargetFrom3DApiState();
|
||||
} else {
|
||||
fRootRenderTarget = rootRenderTarget;
|
||||
rootRenderTarget->ref();
|
||||
}
|
||||
context->ref();
|
||||
|
||||
}
|
||||
|
||||
SkGpuDeviceFactory::~SkGpuDeviceFactory() {
|
||||
fContext->unref();
|
||||
fRootRenderTarget->unref();
|
||||
}
|
||||
|
||||
SkDevice* SkGpuDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
|
||||
@ -1064,6 +1064,6 @@ SkDevice* SkGpuDeviceFactory::newDevice(SkCanvas*, SkBitmap::Config config,
|
||||
SkBitmap bm;
|
||||
bm.setConfig(config, width, height);
|
||||
bm.setIsOpaque(isOpaque);
|
||||
return new SkGpuDevice(fContext, bm, isLayer);
|
||||
return new SkGpuDevice(fContext, bm, isLayer ? NULL : fRootRenderTarget);
|
||||
}
|
||||
|
||||
|
@ -512,6 +512,7 @@ bool SkOSWindow::attachGL(const SkBitmap* offscreen)
|
||||
|
||||
if (success) {
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClearStencil(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
return success;
|
||||
|
@ -439,7 +439,8 @@ bool SkOSWindow::attachGL(const SkBitmap* offscreen) {
|
||||
}
|
||||
if (wglMakeCurrent(GetDC((HWND)fHWND), (HGLRC)fHGLRC)) {
|
||||
glClearColor(0, 0, 0, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearStencil(0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
fGLAttached = true;
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user