2011-07-29 15:13:20 +00:00
|
|
|
/*
|
2012-12-13 19:24:05 +00:00
|
|
|
* Copyright 2011 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
2011-07-29 15:13:20 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef GrRenderTarget_DEFINED
|
|
|
|
#define GrRenderTarget_DEFINED
|
|
|
|
|
2012-06-21 21:09:06 +00:00
|
|
|
#include "GrSurface.h"
|
2013-07-17 21:39:42 +00:00
|
|
|
#include "SkRect.h"
|
2011-07-29 15:13:20 +00:00
|
|
|
|
2016-05-04 19:47:41 +00:00
|
|
|
class GrCaps;
|
2015-10-16 16:07:06 +00:00
|
|
|
class GrDrawTarget;
|
2015-04-16 18:22:42 +00:00
|
|
|
class GrStencilAttachment;
|
2015-02-23 17:06:38 +00:00
|
|
|
class GrRenderTargetPriv;
|
2011-07-29 15:13:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
|
|
|
|
* A context's render target is set by setRenderTarget(). Render targets are
|
2014-11-03 16:47:23 +00:00
|
|
|
* created by a createTexture with the kRenderTarget_SurfaceFlag flag.
|
2011-07-29 15:13:20 +00:00
|
|
|
* Additionally, GrContext provides methods for creating GrRenderTargets
|
|
|
|
* that wrap externally created render targets.
|
|
|
|
*/
|
2014-11-03 16:47:23 +00:00
|
|
|
class GrRenderTarget : virtual public GrSurface {
|
2011-07-29 15:13:20 +00:00
|
|
|
public:
|
2012-06-21 21:09:06 +00:00
|
|
|
// GrSurface overrides
|
2015-03-26 01:17:31 +00:00
|
|
|
GrRenderTarget* asRenderTarget() override { return this; }
|
|
|
|
const GrRenderTarget* asRenderTarget() const override { return this; }
|
2011-07-29 15:13:20 +00:00
|
|
|
|
2012-06-21 21:09:06 +00:00
|
|
|
// GrRenderTarget
|
2011-07-29 15:13:20 +00:00
|
|
|
/**
|
2015-06-12 15:59:45 +00:00
|
|
|
* On some hardware it is possible for a render target to have multisampling
|
|
|
|
* only in certain buffers.
|
|
|
|
* Enforce only two legal sample configs.
|
|
|
|
* kUnified_SampleConfig signifies multisampling in both color and stencil
|
|
|
|
* buffers and is available across all hardware.
|
|
|
|
* kStencil_SampleConfig means multisampling is present in stencil buffer
|
|
|
|
* only; this config requires hardware support of
|
|
|
|
* NV_framebuffer_mixed_samples.
|
|
|
|
*/
|
|
|
|
enum SampleConfig {
|
|
|
|
kUnified_SampleConfig = 0,
|
|
|
|
kStencil_SampleConfig = 1
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return true if the surface is multisampled in all buffers,
|
|
|
|
* false otherwise
|
|
|
|
*/
|
|
|
|
bool isUnifiedMultisampled() const {
|
|
|
|
if (fSampleConfig != kUnified_SampleConfig) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return 0 != fDesc.fSampleCnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return true if the surface is multisampled in the stencil buffer,
|
|
|
|
* false otherwise
|
|
|
|
*/
|
|
|
|
bool isStencilBufferMultisampled() const {
|
|
|
|
return 0 != fDesc.fSampleCnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the number of color samples-per-pixel, or zero if non-MSAA or
|
|
|
|
* multisampled in the stencil buffer only.
|
2011-07-29 15:13:20 +00:00
|
|
|
*/
|
2015-06-12 15:59:45 +00:00
|
|
|
int numColorSamples() const {
|
|
|
|
if (fSampleConfig == kUnified_SampleConfig) {
|
|
|
|
return fDesc.fSampleCnt;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2011-07-29 20:29:05 +00:00
|
|
|
|
|
|
|
/**
|
2015-06-12 15:59:45 +00:00
|
|
|
* @return the number of stencil samples-per-pixel, or zero if non-MSAA.
|
2011-07-29 20:29:05 +00:00
|
|
|
*/
|
2015-06-12 15:59:45 +00:00
|
|
|
int numStencilSamples() const {
|
|
|
|
return fDesc.fSampleCnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return true if the surface is mixed sampled, false otherwise.
|
|
|
|
*/
|
|
|
|
bool hasMixedSamples() const {
|
|
|
|
SkASSERT(kStencil_SampleConfig != fSampleConfig ||
|
|
|
|
this->isStencilBufferMultisampled());
|
|
|
|
return kStencil_SampleConfig == fSampleConfig;
|
|
|
|
}
|
2011-07-29 15:13:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Call to indicate the multisample contents were modified such that the
|
|
|
|
* render target needs to be resolved before it can be used as texture. Gr
|
|
|
|
* tracks this for its own drawing and thus this only needs to be called
|
2012-10-25 18:43:28 +00:00
|
|
|
* when the render target has been modified outside of Gr. This has no
|
|
|
|
* effect on wrapped backend render targets.
|
|
|
|
*
|
2011-07-29 15:13:20 +00:00
|
|
|
* @param rect a rect bounding the area needing resolve. NULL indicates
|
|
|
|
* the whole RT needs resolving.
|
|
|
|
*/
|
2013-07-17 21:39:42 +00:00
|
|
|
void flagAsNeedingResolve(const SkIRect* rect = NULL);
|
2011-07-29 15:13:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Call to override the region that needs to be resolved.
|
|
|
|
*/
|
2013-07-17 21:39:42 +00:00
|
|
|
void overrideResolveRect(const SkIRect rect);
|
2011-07-29 15:13:20 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Call to indicate that GrRenderTarget was externally resolved. This may
|
|
|
|
* allow Gr to skip a redundant resolve step.
|
|
|
|
*/
|
|
|
|
void flagAsResolved() { fResolveRect.setLargestInverted(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return true if the GrRenderTarget requires MSAA resolving
|
|
|
|
*/
|
|
|
|
bool needsResolve() const { return !fResolveRect.isEmpty(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a rect bounding the region needing resolving.
|
|
|
|
*/
|
2013-07-17 21:39:42 +00:00
|
|
|
const SkIRect& getResolveRect() const { return fResolveRect; }
|
2011-07-29 15:13:20 +00:00
|
|
|
|
2014-03-28 16:08:05 +00:00
|
|
|
/**
|
|
|
|
* Provide a performance hint that the render target's contents are allowed
|
|
|
|
* to become undefined.
|
|
|
|
*/
|
|
|
|
void discard();
|
|
|
|
|
2011-07-29 15:13:20 +00:00
|
|
|
// a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
|
2012-08-23 18:09:54 +00:00
|
|
|
// 0 in GL), or be unresolvable because the client didn't give us the
|
2011-07-29 15:13:20 +00:00
|
|
|
// resolve destination.
|
|
|
|
enum ResolveType {
|
|
|
|
kCanResolve_ResolveType,
|
|
|
|
kAutoResolves_ResolveType,
|
|
|
|
kCantResolve_ResolveType,
|
|
|
|
};
|
|
|
|
virtual ResolveType getResolveType() const = 0;
|
|
|
|
|
2015-07-08 19:54:04 +00:00
|
|
|
/**
|
|
|
|
* Return the native ID or handle to the rendertarget, depending on the
|
|
|
|
* platform. e.g. on OpenGL, return the FBO ID.
|
|
|
|
*/
|
|
|
|
virtual GrBackendObject getRenderTargetHandle() const = 0;
|
|
|
|
|
2015-09-14 19:56:10 +00:00
|
|
|
// Checked when this object is asked to attach a stencil buffer.
|
|
|
|
virtual bool canAttemptStencilAttachment() const = 0;
|
|
|
|
|
2015-02-23 17:06:38 +00:00
|
|
|
// Provides access to functions that aren't part of the public API.
|
|
|
|
GrRenderTargetPriv renderTargetPriv();
|
|
|
|
const GrRenderTargetPriv renderTargetPriv() const;
|
2011-08-03 15:18:33 +00:00
|
|
|
|
2015-10-16 16:07:06 +00:00
|
|
|
void setLastDrawTarget(GrDrawTarget* dt);
|
|
|
|
GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }
|
|
|
|
|
2016-05-04 19:47:41 +00:00
|
|
|
static SampleConfig ComputeSampleConfig(const GrCaps& caps, int sampleCnt);
|
|
|
|
|
2011-07-29 15:13:20 +00:00
|
|
|
protected:
|
Refactor to separate backend object lifecycle and GpuResource budget decision
Refactor GrGpuResource to contain two different pieces of state:
a) instance is budgeted or not budgeted
b) instance references wrapped backend objects or not
The "object lifecycle" was also attached to backend object
handles (ids), which made the code a bit unclear. Backend objects
would be associated with GrGpuResource::LifeCycle, even though
GrGpuResource::LifeCycle refers to the GpuResource, and individual
backend objects in one GpuResource might be governed with different
"lifecycle".
Mark the budgeted/not budgeted with SkBudgeted::kYes, SkBudgeted::kNo.
This was previously GrGpuResource::kCached_LifeCycle,
GrGpuResource::kUncached_LifeCycle.
Mark the "references wrapped object" with boolean. This was previously
GrGpuResource::kBorrowed_LifeCycle,
GrGpuResource::kAdopted_LifeCycle for GrGpuResource.
Associate the backend object ownership status with
GrBackendObjectOwnership for the backend object handles.
The resource type leaf constuctors, such has GrGLTexture or
GrGLTextureRenderTarget take "budgeted" parameter. This parameter
is passed to GrGpuResource::registerWithCache().
The resource type intermediary constructors, such as GrGLTexture
constructors for class GrGLTextureRenderTarget do not take "budgeted"
parameters, intermediary construtors do not call registerWithCache.
Removes the need for tagging GrGpuResource -derived subclass
constructors with "Derived" parameter.
Makes instances that wrap backend objects be registered with
a new function GrGpuResource::registerWithCacheWrapped().
Removes "budgeted" parameter from classes such as StencilAttahment, as
they are always cached and never wrap any external backend objects.
Removes the use of concept "external" from the member function names.
The API refers to the objects as "wrapped", so make all related
functions use the term consistently.
No change in functionality. Resources referencing wrapped objects are
always inserted to the cache with budget decision kNo.
BUG=594928
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1862043002
Review URL: https://codereview.chromium.org/1862043002
2016-04-22 08:48:29 +00:00
|
|
|
GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc,
|
2015-09-14 19:56:10 +00:00
|
|
|
SampleConfig sampleConfig, GrStencilAttachment* stencil = nullptr)
|
Refactor to separate backend object lifecycle and GpuResource budget decision
Refactor GrGpuResource to contain two different pieces of state:
a) instance is budgeted or not budgeted
b) instance references wrapped backend objects or not
The "object lifecycle" was also attached to backend object
handles (ids), which made the code a bit unclear. Backend objects
would be associated with GrGpuResource::LifeCycle, even though
GrGpuResource::LifeCycle refers to the GpuResource, and individual
backend objects in one GpuResource might be governed with different
"lifecycle".
Mark the budgeted/not budgeted with SkBudgeted::kYes, SkBudgeted::kNo.
This was previously GrGpuResource::kCached_LifeCycle,
GrGpuResource::kUncached_LifeCycle.
Mark the "references wrapped object" with boolean. This was previously
GrGpuResource::kBorrowed_LifeCycle,
GrGpuResource::kAdopted_LifeCycle for GrGpuResource.
Associate the backend object ownership status with
GrBackendObjectOwnership for the backend object handles.
The resource type leaf constuctors, such has GrGLTexture or
GrGLTextureRenderTarget take "budgeted" parameter. This parameter
is passed to GrGpuResource::registerWithCache().
The resource type intermediary constructors, such as GrGLTexture
constructors for class GrGLTextureRenderTarget do not take "budgeted"
parameters, intermediary construtors do not call registerWithCache.
Removes the need for tagging GrGpuResource -derived subclass
constructors with "Derived" parameter.
Makes instances that wrap backend objects be registered with
a new function GrGpuResource::registerWithCacheWrapped().
Removes "budgeted" parameter from classes such as StencilAttahment, as
they are always cached and never wrap any external backend objects.
Removes the use of concept "external" from the member function names.
The API refers to the objects as "wrapped", so make all related
functions use the term consistently.
No change in functionality. Resources referencing wrapped objects are
always inserted to the cache with budget decision kNo.
BUG=594928
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1862043002
Review URL: https://codereview.chromium.org/1862043002
2016-04-22 08:48:29 +00:00
|
|
|
: INHERITED(gpu, desc)
|
2015-09-14 19:56:10 +00:00
|
|
|
, fStencilAttachment(stencil)
|
2016-07-06 16:59:43 +00:00
|
|
|
, fMultisampleSpecsID(0)
|
2015-10-16 16:07:06 +00:00
|
|
|
, fSampleConfig(sampleConfig)
|
|
|
|
, fLastDrawTarget(nullptr) {
|
2011-07-29 15:13:20 +00:00
|
|
|
fResolveRect.setLargestInverted();
|
|
|
|
}
|
|
|
|
|
2015-10-30 17:11:30 +00:00
|
|
|
~GrRenderTarget() override;
|
|
|
|
|
2012-09-05 15:46:34 +00:00
|
|
|
// override of GrResource
|
2015-03-26 01:17:31 +00:00
|
|
|
void onAbandon() override;
|
|
|
|
void onRelease() override;
|
2012-09-05 15:46:34 +00:00
|
|
|
|
2011-07-29 15:13:20 +00:00
|
|
|
private:
|
2015-09-14 19:56:10 +00:00
|
|
|
// Allows the backends to perform any additional work that is required for attaching a
|
|
|
|
// GrStencilAttachment. When this is called, the GrStencilAttachment has already been put onto
|
|
|
|
// the GrRenderTarget. This function must return false if any failures occur when completing the
|
|
|
|
// stencil attachment.
|
|
|
|
virtual bool completeStencilAttachment() = 0;
|
2015-02-23 17:06:38 +00:00
|
|
|
|
|
|
|
friend class GrRenderTargetPriv;
|
|
|
|
|
2015-04-16 18:22:42 +00:00
|
|
|
GrStencilAttachment* fStencilAttachment;
|
2016-07-06 16:59:43 +00:00
|
|
|
uint8_t fMultisampleSpecsID;
|
2015-06-12 15:59:45 +00:00
|
|
|
SampleConfig fSampleConfig;
|
2012-06-13 12:53:07 +00:00
|
|
|
|
2015-04-16 18:22:42 +00:00
|
|
|
SkIRect fResolveRect;
|
2011-07-29 15:13:20 +00:00
|
|
|
|
2015-10-16 16:07:06 +00:00
|
|
|
// The last drawTarget that wrote to or is currently going to write to this renderTarget
|
|
|
|
// The drawTarget can be closed (e.g., no draw context is currently bound
|
|
|
|
// to this renderTarget).
|
|
|
|
// This back-pointer is required so that we can add a dependancy between
|
|
|
|
// the drawTarget used to create the current contents of this renderTarget
|
|
|
|
// and the drawTarget of a destination renderTarget to which this one is being drawn.
|
|
|
|
GrDrawTarget* fLastDrawTarget;
|
|
|
|
|
2012-06-21 21:09:06 +00:00
|
|
|
typedef GrSurface INHERITED;
|
2011-07-29 15:13:20 +00:00
|
|
|
};
|
|
|
|
|
2015-06-12 15:59:45 +00:00
|
|
|
|
2011-07-29 15:13:20 +00:00
|
|
|
#endif
|