1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrDrawTarget.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,915 @@ 1.4 +/* 1.5 + * Copyright 2010 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef GrDrawTarget_DEFINED 1.12 +#define GrDrawTarget_DEFINED 1.13 + 1.14 +#include "GrClipData.h" 1.15 +#include "GrDrawState.h" 1.16 +#include "GrIndexBuffer.h" 1.17 + 1.18 +#include "SkClipStack.h" 1.19 +#include "SkMatrix.h" 1.20 +#include "SkPath.h" 1.21 +#include "SkTArray.h" 1.22 +#include "SkTLazy.h" 1.23 +#include "SkTypes.h" 1.24 +#include "SkXfermode.h" 1.25 + 1.26 +class GrClipData; 1.27 +class GrDrawTargetCaps; 1.28 +class GrPath; 1.29 +class GrVertexBuffer; 1.30 +class SkStrokeRec; 1.31 + 1.32 +class GrDrawTarget : public SkRefCnt { 1.33 +protected: 1.34 + class DrawInfo; 1.35 + 1.36 +public: 1.37 + SK_DECLARE_INST_COUNT(GrDrawTarget) 1.38 + 1.39 + /////////////////////////////////////////////////////////////////////////// 1.40 + 1.41 + // The context may not be fully constructed and should not be used during GrDrawTarget 1.42 + // construction. 1.43 + GrDrawTarget(GrContext* context); 1.44 + virtual ~GrDrawTarget(); 1.45 + 1.46 + /** 1.47 + * Gets the capabilities of the draw target. 1.48 + */ 1.49 + const GrDrawTargetCaps* caps() const { return fCaps.get(); } 1.50 + 1.51 + /** 1.52 + * Sets the current clip to the region specified by clip. All draws will be 1.53 + * clipped against this clip if kClip_StateBit is enabled. 1.54 + * 1.55 + * Setting the clip may (or may not) zero out the client's stencil bits. 1.56 + * 1.57 + * @param description of the clipping region 1.58 + */ 1.59 + void setClip(const GrClipData* clip); 1.60 + 1.61 + /** 1.62 + * Gets the current clip. 1.63 + * 1.64 + * @return the clip. 1.65 + */ 1.66 + const GrClipData* getClip() const; 1.67 + 1.68 + /** 1.69 + * Sets the draw state object for the draw target. Note that this does not 1.70 + * make a copy. The GrDrawTarget will take a reference to passed object. 1.71 + * Passing NULL will cause the GrDrawTarget to use its own internal draw 1.72 + * state object rather than an externally provided one. 1.73 + */ 1.74 + void setDrawState(GrDrawState* drawState); 1.75 + 1.76 + /** 1.77 + * Read-only access to the GrDrawTarget's current draw state. 1.78 + */ 1.79 + const GrDrawState& getDrawState() const { return *fDrawState; } 1.80 + 1.81 + /** 1.82 + * Read-write access to the GrDrawTarget's current draw state. Note that 1.83 + * this doesn't ref. 1.84 + */ 1.85 + GrDrawState* drawState() { return fDrawState; } 1.86 + 1.87 + /** 1.88 + * Color alpha and coverage are two inputs to the drawing pipeline. For some 1.89 + * blend modes it is safe to fold the coverage into constant or per-vertex 1.90 + * color alpha value. For other blend modes they must be handled separately. 1.91 + * Depending on features available in the underlying 3D API this may or may 1.92 + * not be possible. 1.93 + * 1.94 + * This function considers the current draw state and the draw target's 1.95 + * capabilities to determine whether coverage can be handled correctly. The 1.96 + * following assumptions are made: 1.97 + * 1. The caller intends to somehow specify coverage. This can be 1.98 + * specified either by enabling a coverage stage on the GrDrawState or 1.99 + * via the vertex layout. 1.100 + * 2. Other than enabling coverage stages or enabling coverage in the 1.101 + * layout, the current configuration of the target's GrDrawState is as 1.102 + * it will be at draw time. 1.103 + */ 1.104 + bool canApplyCoverage() const; 1.105 + 1.106 + /** When we're using coverage AA but the blend is incompatible (given gpu 1.107 + * limitations) we should disable AA. */ 1.108 + bool shouldDisableCoverageAAForBlend() { 1.109 + // Enable below if we should draw with AA even when it produces 1.110 + // incorrect blending. 1.111 + // return false; 1.112 + return !this->canApplyCoverage(); 1.113 + } 1.114 + 1.115 + /** 1.116 + * Given the current draw state and hw support, will HW AA lines be used (if 1.117 + * a line primitive type is drawn)? 1.118 + */ 1.119 + bool willUseHWAALines() const; 1.120 + 1.121 + /** 1.122 + * There are three types of "sources" of geometry (vertices and indices) for 1.123 + * draw calls made on the target. When performing an indexed draw, the 1.124 + * indices and vertices can use different source types. Once a source is 1.125 + * specified it can be used for multiple draws. However, the time at which 1.126 + * the geometry data is no longer editable depends on the source type. 1.127 + * 1.128 + * Sometimes it is necessary to perform a draw while upstack code has 1.129 + * already specified geometry that it isn't finished with. So there are push 1.130 + * and pop methods. This allows the client to push the sources, draw 1.131 + * something using alternate sources, and then pop to restore the original 1.132 + * sources. 1.133 + * 1.134 + * Aside from pushes and pops, a source remains valid until another source 1.135 + * is set or resetVertexSource / resetIndexSource is called. Drawing from 1.136 + * a reset source is an error. 1.137 + * 1.138 + * The three types of sources are: 1.139 + * 1.140 + * 1. A cpu array (set*SourceToArray). This is useful when the caller 1.141 + * already provided vertex data in a format compatible with a 1.142 + * GrVertexLayout. The data in the array is consumed at the time that 1.143 + * set*SourceToArray is called and subsequent edits to the array will not 1.144 + * be reflected in draws. 1.145 + * 1.146 + * 2. Reserve. This is most useful when the caller has data it must 1.147 + * transform before drawing and is not long-lived. The caller requests 1.148 + * that the draw target make room for some amount of vertex and/or index 1.149 + * data. The target provides ptrs to hold the vertex and/or index data. 1.150 + * 1.151 + * The data is writable up until the next drawIndexed, drawNonIndexed, 1.152 + * drawIndexedInstances, drawRect, copySurface, or pushGeometrySource. At 1.153 + * this point the data is frozen and the ptrs are no longer valid. 1.154 + * 1.155 + * Where the space is allocated and how it is uploaded to the GPU is 1.156 + * subclass-dependent. 1.157 + * 1.158 + * 3. Vertex and Index Buffers. This is most useful for geometry that will 1.159 + * is long-lived. When the data in the buffer is consumed depends on the 1.160 + * GrDrawTarget subclass. For deferred subclasses the caller has to 1.161 + * guarantee that the data is still available in the buffers at playback. 1.162 + * (TODO: Make this more automatic as we have done for read/write pixels) 1.163 + * 1.164 + * The size of each vertex is determined by querying the current GrDrawState. 1.165 + */ 1.166 + 1.167 + /** 1.168 + * Reserves space for vertices and/or indices. Zero can be specifed as 1.169 + * either the vertex or index count if the caller desires to only reserve 1.170 + * space for only indices or only vertices. If zero is specifed for 1.171 + * vertexCount then the vertex source will be unmodified and likewise for 1.172 + * indexCount. 1.173 + * 1.174 + * If the function returns true then the reserve suceeded and the vertices 1.175 + * and indices pointers will point to the space created. 1.176 + * 1.177 + * If the target cannot make space for the request then this function will 1.178 + * return false. If vertexCount was non-zero then upon failure the vertex 1.179 + * source is reset and likewise for indexCount. 1.180 + * 1.181 + * The pointers to the space allocated for vertices and indices remain valid 1.182 + * until a drawIndexed, drawNonIndexed, drawIndexedInstances, drawRect, 1.183 + * copySurface, or push/popGeomtrySource is called. At that point logically a 1.184 + * snapshot of the data is made and the pointers are invalid. 1.185 + * 1.186 + * @param vertexCount the number of vertices to reserve space for. Can be 1.187 + * 0. Vertex size is queried from the current GrDrawState. 1.188 + * @param indexCount the number of indices to reserve space for. Can be 0. 1.189 + * @param vertices will point to reserved vertex space if vertexCount is 1.190 + * non-zero. Illegal to pass NULL if vertexCount > 0. 1.191 + * @param indices will point to reserved index space if indexCount is 1.192 + * non-zero. Illegal to pass NULL if indexCount > 0. 1.193 + */ 1.194 + bool reserveVertexAndIndexSpace(int vertexCount, 1.195 + int indexCount, 1.196 + void** vertices, 1.197 + void** indices); 1.198 + 1.199 + /** 1.200 + * Provides hints to caller about the number of vertices and indices 1.201 + * that can be allocated cheaply. This can be useful if caller is reserving 1.202 + * space but doesn't know exactly how much geometry is needed. 1.203 + * 1.204 + * Also may hint whether the draw target should be flushed first. This is 1.205 + * useful for deferred targets. 1.206 + * 1.207 + * @param vertexCount in: hint about how many vertices the caller would 1.208 + * like to allocate. Vertex size is queried from the 1.209 + * current GrDrawState. 1.210 + * out: a hint about the number of vertices that can be 1.211 + * allocated cheaply. Negative means no hint. 1.212 + * Ignored if NULL. 1.213 + * @param indexCount in: hint about how many indices the caller would 1.214 + * like to allocate. 1.215 + * out: a hint about the number of indices that can be 1.216 + * allocated cheaply. Negative means no hint. 1.217 + * Ignored if NULL. 1.218 + * 1.219 + * @return true if target should be flushed based on the input values. 1.220 + */ 1.221 + virtual bool geometryHints(int* vertexCount, 1.222 + int* indexCount) const; 1.223 + 1.224 + /** 1.225 + * Sets source of vertex data for the next draw. Array must contain 1.226 + * the vertex data when this is called. 1.227 + * 1.228 + * @param vertexArray cpu array containing vertex data. 1.229 + * @param vertexCount the number of vertices in the array. Vertex size is 1.230 + * queried from the current GrDrawState. 1.231 + */ 1.232 + void setVertexSourceToArray(const void* vertexArray, int vertexCount); 1.233 + 1.234 + /** 1.235 + * Sets source of index data for the next indexed draw. Array must contain 1.236 + * the indices when this is called. 1.237 + * 1.238 + * @param indexArray cpu array containing index data. 1.239 + * @param indexCount the number of indices in the array. 1.240 + */ 1.241 + void setIndexSourceToArray(const void* indexArray, int indexCount); 1.242 + 1.243 + /** 1.244 + * Sets source of vertex data for the next draw. Data does not have to be 1.245 + * in the buffer until drawIndexed, drawNonIndexed, or drawIndexedInstances. 1.246 + * 1.247 + * @param buffer vertex buffer containing vertex data. Must be 1.248 + * unlocked before draw call. Vertex size is queried 1.249 + * from current GrDrawState. 1.250 + */ 1.251 + void setVertexSourceToBuffer(const GrVertexBuffer* buffer); 1.252 + 1.253 + /** 1.254 + * Sets source of index data for the next indexed draw. Data does not have 1.255 + * to be in the buffer until drawIndexed. 1.256 + * 1.257 + * @param buffer index buffer containing indices. Must be unlocked 1.258 + * before indexed draw call. 1.259 + */ 1.260 + void setIndexSourceToBuffer(const GrIndexBuffer* buffer); 1.261 + 1.262 + /** 1.263 + * Resets vertex source. Drawing from reset vertices is illegal. Set vertex 1.264 + * source to reserved, array, or buffer before next draw. May be able to free 1.265 + * up temporary storage allocated by setVertexSourceToArray or 1.266 + * reserveVertexSpace. 1.267 + */ 1.268 + void resetVertexSource(); 1.269 + 1.270 + /** 1.271 + * Resets index source. Indexed Drawing from reset indices is illegal. Set 1.272 + * index source to reserved, array, or buffer before next indexed draw. May 1.273 + * be able to free up temporary storage allocated by setIndexSourceToArray 1.274 + * or reserveIndexSpace. 1.275 + */ 1.276 + void resetIndexSource(); 1.277 + 1.278 + /** 1.279 + * Query to find out if the vertex or index source is reserved. 1.280 + */ 1.281 + bool hasReservedVerticesOrIndices() const { 1.282 + return kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc || 1.283 + kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc; 1.284 + } 1.285 + 1.286 + /** 1.287 + * Pushes and resets the vertex/index sources. Any reserved vertex / index 1.288 + * data is finalized (i.e. cannot be updated after the matching pop but can 1.289 + * be drawn from). Must be balanced by a pop. 1.290 + */ 1.291 + void pushGeometrySource(); 1.292 + 1.293 + /** 1.294 + * Pops the vertex / index sources from the matching push. 1.295 + */ 1.296 + void popGeometrySource(); 1.297 + 1.298 + /** 1.299 + * Draws indexed geometry using the current state and current vertex / index 1.300 + * sources. 1.301 + * 1.302 + * @param type The type of primitives to draw. 1.303 + * @param startVertex the vertex in the vertex array/buffer corresponding 1.304 + * to index 0 1.305 + * @param startIndex first index to read from index src. 1.306 + * @param vertexCount one greater than the max index. 1.307 + * @param indexCount the number of index elements to read. The index count 1.308 + * is effectively trimmed to the last completely 1.309 + * specified primitive. 1.310 + * @param devBounds optional bounds hint. This is a promise from the caller, 1.311 + * not a request for clipping. 1.312 + */ 1.313 + void drawIndexed(GrPrimitiveType type, 1.314 + int startVertex, 1.315 + int startIndex, 1.316 + int vertexCount, 1.317 + int indexCount, 1.318 + const SkRect* devBounds = NULL); 1.319 + 1.320 + /** 1.321 + * Draws non-indexed geometry using the current state and current vertex 1.322 + * sources. 1.323 + * 1.324 + * @param type The type of primitives to draw. 1.325 + * @param startVertex the vertex in the vertex array/buffer corresponding 1.326 + * to index 0 1.327 + * @param vertexCount one greater than the max index. 1.328 + * @param devBounds optional bounds hint. This is a promise from the caller, 1.329 + * not a request for clipping. 1.330 + */ 1.331 + void drawNonIndexed(GrPrimitiveType type, 1.332 + int startVertex, 1.333 + int vertexCount, 1.334 + const SkRect* devBounds = NULL); 1.335 + 1.336 + /** 1.337 + * Draws path into the stencil buffer. The fill must be either even/odd or 1.338 + * winding (not inverse or hairline). It will respect the HW antialias flag 1.339 + * on the draw state (if possible in the 3D API). 1.340 + */ 1.341 + void stencilPath(const GrPath*, SkPath::FillType fill); 1.342 + 1.343 + /** 1.344 + * Draws a path. Fill must not be a hairline. It will respect the HW 1.345 + * antialias flag on the draw state (if possible in the 3D API). 1.346 + */ 1.347 + void drawPath(const GrPath*, SkPath::FillType fill); 1.348 + 1.349 + /** 1.350 + * Helper function for drawing rects. It performs a geometry src push and pop 1.351 + * and thus will finalize any reserved geometry. 1.352 + * 1.353 + * @param rect the rect to draw 1.354 + * @param matrix optional matrix applied to rect (before viewMatrix) 1.355 + * @param localRect optional rect that specifies local coords to map onto 1.356 + * rect. If NULL then rect serves as the local coords. 1.357 + * @param localMatrix optional matrix applied to localRect. If 1.358 + * srcRect is non-NULL and srcMatrix is non-NULL 1.359 + * then srcRect will be transformed by srcMatrix. 1.360 + * srcMatrix can be NULL when no srcMatrix is desired. 1.361 + */ 1.362 + void drawRect(const SkRect& rect, 1.363 + const SkMatrix* matrix, 1.364 + const SkRect* localRect, 1.365 + const SkMatrix* localMatrix) { 1.366 + AutoGeometryPush agp(this); 1.367 + this->onDrawRect(rect, matrix, localRect, localMatrix); 1.368 + } 1.369 + 1.370 + /** 1.371 + * Helper for drawRect when the caller doesn't need separate local rects or matrices. 1.372 + */ 1.373 + void drawSimpleRect(const SkRect& rect, const SkMatrix* matrix = NULL) { 1.374 + this->drawRect(rect, matrix, NULL, NULL); 1.375 + } 1.376 + void drawSimpleRect(const SkIRect& irect, const SkMatrix* matrix = NULL) { 1.377 + SkRect rect = SkRect::Make(irect); 1.378 + this->drawRect(rect, matrix, NULL, NULL); 1.379 + } 1.380 + 1.381 + /** 1.382 + * This call is used to draw multiple instances of some geometry with a 1.383 + * given number of vertices (V) and indices (I) per-instance. The indices in 1.384 + * the index source must have the form i[k+I] == i[k] + V. Also, all indices 1.385 + * i[kI] ... i[(k+1)I-1] must be elements of the range kV ... (k+1)V-1. As a 1.386 + * concrete example, the following index buffer for drawing a series of 1.387 + * quads each as two triangles each satisfies these conditions with V=4 and 1.388 + * I=6: 1.389 + * (0,1,2,0,2,3, 4,5,6,4,6,7, 8,9,10,8,10,11, ...) 1.390 + * 1.391 + * The call assumes that the pattern of indices fills the entire index 1.392 + * source. The size of the index buffer limits the number of instances that 1.393 + * can be drawn by the GPU in a single draw. However, the caller may specify 1.394 + * any (positive) number for instanceCount and if necessary multiple GPU 1.395 + * draws will be issued. Moreover, when drawIndexedInstances is called 1.396 + * multiple times it may be possible for GrDrawTarget to group them into a 1.397 + * single GPU draw. 1.398 + * 1.399 + * @param type the type of primitives to draw 1.400 + * @param instanceCount the number of instances to draw. Each instance 1.401 + * consists of verticesPerInstance vertices indexed by 1.402 + * indicesPerInstance indices drawn as the primitive 1.403 + * type specified by type. 1.404 + * @param verticesPerInstance The number of vertices in each instance (V 1.405 + * in the above description). 1.406 + * @param indicesPerInstance The number of indices in each instance (I 1.407 + * in the above description). 1.408 + * @param devBounds optional bounds hint. This is a promise from the caller, 1.409 + * not a request for clipping. 1.410 + */ 1.411 + void drawIndexedInstances(GrPrimitiveType type, 1.412 + int instanceCount, 1.413 + int verticesPerInstance, 1.414 + int indicesPerInstance, 1.415 + const SkRect* devBounds = NULL); 1.416 + 1.417 + /** 1.418 + * Clear the current render target if one isn't passed in. Ignores the 1.419 + * clip and all other draw state (blend mode, stages, etc). Clears the 1.420 + * whole thing if rect is NULL, otherwise just the rect. If canIgnoreRect 1.421 + * is set then the entire render target can be optionally cleared. 1.422 + */ 1.423 + virtual void clear(const SkIRect* rect, 1.424 + GrColor color, 1.425 + bool canIgnoreRect, 1.426 + GrRenderTarget* renderTarget = NULL) = 0; 1.427 + 1.428 + /** 1.429 + * instantGpuTraceEvent places a single "sign post" type marker into command stream. The 1.430 + * argument marker will be the name of the annotation that is added. 1.431 + */ 1.432 + void instantGpuTraceEvent(const char* marker); 1.433 + /** 1.434 + * The following two functions are used for marking groups of commands. Use pushGpuTraceEvent 1.435 + * to set the beginning of a command set, and popGpuTraceEvent is be called at end of the 1.436 + * command set. The argument marker is the name for the annotation that is added. The push and 1.437 + * pops can be used hierarchically, but every push must have a match pop. 1.438 + */ 1.439 + void pushGpuTraceEvent(const char* marker); 1.440 + void popGpuTraceEvent(); 1.441 + 1.442 + /** 1.443 + * Copies a pixel rectangle from one surface to another. This call may finalize 1.444 + * reserved vertex/index data (as though a draw call was made). The src pixels 1.445 + * copied are specified by srcRect. They are copied to a rect of the same 1.446 + * size in dst with top left at dstPoint. If the src rect is clipped by the 1.447 + * src bounds then pixel values in the dst rect corresponding to area clipped 1.448 + * by the src rect are not overwritten. This method can fail and return false 1.449 + * depending on the type of surface, configs, etc, and the backend-specific 1.450 + * limitations. If rect is clipped out entirely by the src or dst bounds then 1.451 + * true is returned since there is no actual copy necessary to succeed. 1.452 + */ 1.453 + bool copySurface(GrSurface* dst, 1.454 + GrSurface* src, 1.455 + const SkIRect& srcRect, 1.456 + const SkIPoint& dstPoint); 1.457 + /** 1.458 + * Function that determines whether a copySurface call would succeed without 1.459 + * performing the copy. 1.460 + */ 1.461 + bool canCopySurface(GrSurface* dst, 1.462 + GrSurface* src, 1.463 + const SkIRect& srcRect, 1.464 + const SkIPoint& dstPoint); 1.465 + 1.466 + /** 1.467 + * This is can be called before allocating a texture to be a dst for copySurface. It will 1.468 + * populate the origin, config, and flags fields of the desc such that copySurface is more 1.469 + * likely to succeed and be efficient. 1.470 + */ 1.471 + virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc); 1.472 + 1.473 + 1.474 + /** 1.475 + * Release any resources that are cached but not currently in use. This 1.476 + * is intended to give an application some recourse when resources are low. 1.477 + */ 1.478 + virtual void purgeResources() {}; 1.479 + 1.480 + /** 1.481 + * For subclass internal use to invoke a call to onDraw(). See DrawInfo below. 1.482 + */ 1.483 + void executeDraw(const DrawInfo& info) { this->onDraw(info); } 1.484 + 1.485 + /** 1.486 + * For subclass internal use to invoke a call to onDrawPath(). 1.487 + */ 1.488 + void executeDrawPath(const GrPath* path, SkPath::FillType fill, 1.489 + const GrDeviceCoordTexture* dstCopy) { 1.490 + this->onDrawPath(path, fill, dstCopy); 1.491 + } 1.492 + 1.493 + //////////////////////////////////////////////////////////////////////////// 1.494 + 1.495 + /** 1.496 + * See AutoStateRestore below. 1.497 + */ 1.498 + enum ASRInit { 1.499 + kPreserve_ASRInit, 1.500 + kReset_ASRInit 1.501 + }; 1.502 + 1.503 + /** 1.504 + * Saves off the current state and restores it in the destructor. It will 1.505 + * install a new GrDrawState object on the target (setDrawState) and restore 1.506 + * the previous one in the destructor. The caller should call drawState() to 1.507 + * get the new draw state after the ASR is installed. 1.508 + * 1.509 + * GrDrawState* state = target->drawState(); 1.510 + * AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit). 1.511 + * state->setRenderTarget(rt); // state refers to the GrDrawState set on 1.512 + * // target before asr was initialized. 1.513 + * // Therefore, rt is set on the GrDrawState 1.514 + * // that will be restored after asr's 1.515 + * // destructor rather than target's current 1.516 + * // GrDrawState. 1.517 + */ 1.518 + class AutoStateRestore : public ::SkNoncopyable { 1.519 + public: 1.520 + /** 1.521 + * Default ASR will have no effect unless set() is subsequently called. 1.522 + */ 1.523 + AutoStateRestore(); 1.524 + 1.525 + /** 1.526 + * Saves the state on target. The state will be restored when the ASR 1.527 + * is destroyed. If this constructor is used do not call set(). 1.528 + * 1.529 + * @param init Should the newly installed GrDrawState be a copy of the 1.530 + * previous state or a default-initialized GrDrawState. 1.531 + * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's 1.532 + * matrix will be preconcat'ed with the param. All stages will be 1.533 + updated to compensate for the matrix change. If init == kReset 1.534 + then the draw state's matrix will be this matrix. 1.535 + */ 1.536 + AutoStateRestore(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL); 1.537 + 1.538 + ~AutoStateRestore(); 1.539 + 1.540 + /** 1.541 + * Saves the state on target. The state will be restored when the ASR 1.542 + * is destroyed. This should only be called once per ASR object and only 1.543 + * when the default constructor was used. For nested saves use multiple 1.544 + * ASR objects. 1.545 + * 1.546 + * @param init Should the newly installed GrDrawState be a copy of the 1.547 + * previous state or a default-initialized GrDrawState. 1.548 + * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's 1.549 + * matrix will be preconcat'ed with the param. All stages will be 1.550 + updated to compensate for the matrix change. If init == kReset 1.551 + then the draw state's matrix will be this matrix. 1.552 + */ 1.553 + void set(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL); 1.554 + 1.555 + /** 1.556 + * Like set() but makes the view matrix identity. When init is kReset it is as though 1.557 + * NULL was passed to set's viewMatrix param. When init is kPreserve it is as though 1.558 + * the inverse view matrix was passed. If kPreserve is passed and the draw state's matrix 1.559 + * is not invertible then this may fail. 1.560 + */ 1.561 + bool setIdentity(GrDrawTarget* target, ASRInit init); 1.562 + 1.563 + private: 1.564 + GrDrawTarget* fDrawTarget; 1.565 + SkTLazy<GrDrawState> fTempState; 1.566 + GrDrawState* fSavedState; 1.567 + }; 1.568 + 1.569 + //////////////////////////////////////////////////////////////////////////// 1.570 + 1.571 + class AutoReleaseGeometry : public ::SkNoncopyable { 1.572 + public: 1.573 + AutoReleaseGeometry(GrDrawTarget* target, 1.574 + int vertexCount, 1.575 + int indexCount); 1.576 + AutoReleaseGeometry(); 1.577 + ~AutoReleaseGeometry(); 1.578 + bool set(GrDrawTarget* target, 1.579 + int vertexCount, 1.580 + int indexCount); 1.581 + bool succeeded() const { return NULL != fTarget; } 1.582 + void* vertices() const { SkASSERT(this->succeeded()); return fVertices; } 1.583 + void* indices() const { SkASSERT(this->succeeded()); return fIndices; } 1.584 + GrPoint* positions() const { 1.585 + return static_cast<GrPoint*>(this->vertices()); 1.586 + } 1.587 + 1.588 + private: 1.589 + void reset(); 1.590 + 1.591 + GrDrawTarget* fTarget; 1.592 + void* fVertices; 1.593 + void* fIndices; 1.594 + }; 1.595 + 1.596 + //////////////////////////////////////////////////////////////////////////// 1.597 + 1.598 + class AutoClipRestore : public ::SkNoncopyable { 1.599 + public: 1.600 + AutoClipRestore(GrDrawTarget* target) { 1.601 + fTarget = target; 1.602 + fClip = fTarget->getClip(); 1.603 + } 1.604 + 1.605 + AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip); 1.606 + 1.607 + ~AutoClipRestore() { 1.608 + fTarget->setClip(fClip); 1.609 + } 1.610 + private: 1.611 + GrDrawTarget* fTarget; 1.612 + const GrClipData* fClip; 1.613 + SkTLazy<SkClipStack> fStack; 1.614 + GrClipData fReplacementClip; 1.615 + }; 1.616 + 1.617 + //////////////////////////////////////////////////////////////////////////// 1.618 + 1.619 + /** 1.620 + * Saves the geometry src state at construction and restores in the destructor. It also saves 1.621 + * and then restores the vertex attrib state. 1.622 + */ 1.623 + class AutoGeometryPush : public ::SkNoncopyable { 1.624 + public: 1.625 + AutoGeometryPush(GrDrawTarget* target) 1.626 + : fAttribRestore(target->drawState()) { 1.627 + SkASSERT(NULL != target); 1.628 + fTarget = target; 1.629 + target->pushGeometrySource(); 1.630 + } 1.631 + 1.632 + ~AutoGeometryPush() { fTarget->popGeometrySource(); } 1.633 + 1.634 + private: 1.635 + GrDrawTarget* fTarget; 1.636 + GrDrawState::AutoVertexAttribRestore fAttribRestore; 1.637 + }; 1.638 + 1.639 + /** 1.640 + * Combination of AutoGeometryPush and AutoStateRestore. The vertex attribs will be in default 1.641 + * state regardless of ASRInit value. 1.642 + */ 1.643 + class AutoGeometryAndStatePush : public ::SkNoncopyable { 1.644 + public: 1.645 + AutoGeometryAndStatePush(GrDrawTarget* target, 1.646 + ASRInit init, 1.647 + const SkMatrix* viewMatrix = NULL) 1.648 + : fState(target, init, viewMatrix) { 1.649 + SkASSERT(NULL != target); 1.650 + fTarget = target; 1.651 + target->pushGeometrySource(); 1.652 + if (kPreserve_ASRInit == init) { 1.653 + target->drawState()->setDefaultVertexAttribs(); 1.654 + } 1.655 + } 1.656 + 1.657 + ~AutoGeometryAndStatePush() { fTarget->popGeometrySource(); } 1.658 + 1.659 + private: 1.660 + AutoStateRestore fState; 1.661 + GrDrawTarget* fTarget; 1.662 + }; 1.663 + 1.664 + /////////////////////////////////////////////////////////////////////////// 1.665 + // Draw execution tracking (for font atlases and other resources) 1.666 + class DrawToken { 1.667 + public: 1.668 + DrawToken(GrDrawTarget* drawTarget, uint32_t drawID) : 1.669 + fDrawTarget(drawTarget), fDrawID(drawID) {} 1.670 + 1.671 + bool isIssued() { return NULL != fDrawTarget && fDrawTarget->isIssued(fDrawID); } 1.672 + 1.673 + private: 1.674 + GrDrawTarget* fDrawTarget; 1.675 + uint32_t fDrawID; // this may wrap, but we're doing direct comparison 1.676 + // so that should be okay 1.677 + }; 1.678 + 1.679 + virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); } 1.680 + 1.681 +protected: 1.682 + 1.683 + enum GeometrySrcType { 1.684 + kNone_GeometrySrcType, //<! src has not been specified 1.685 + kReserved_GeometrySrcType, //<! src was set using reserve*Space 1.686 + kArray_GeometrySrcType, //<! src was set using set*SourceToArray 1.687 + kBuffer_GeometrySrcType //<! src was set using set*SourceToBuffer 1.688 + }; 1.689 + 1.690 + struct GeometrySrcState { 1.691 + GeometrySrcType fVertexSrc; 1.692 + union { 1.693 + // valid if src type is buffer 1.694 + const GrVertexBuffer* fVertexBuffer; 1.695 + // valid if src type is reserved or array 1.696 + int fVertexCount; 1.697 + }; 1.698 + 1.699 + GeometrySrcType fIndexSrc; 1.700 + union { 1.701 + // valid if src type is buffer 1.702 + const GrIndexBuffer* fIndexBuffer; 1.703 + // valid if src type is reserved or array 1.704 + int fIndexCount; 1.705 + }; 1.706 + 1.707 + size_t fVertexSize; 1.708 + }; 1.709 + 1.710 + int indexCountInCurrentSource() const { 1.711 + const GeometrySrcState& src = this->getGeomSrc(); 1.712 + switch (src.fIndexSrc) { 1.713 + case kNone_GeometrySrcType: 1.714 + return 0; 1.715 + case kReserved_GeometrySrcType: 1.716 + case kArray_GeometrySrcType: 1.717 + return src.fIndexCount; 1.718 + case kBuffer_GeometrySrcType: 1.719 + return static_cast<int>(src.fIndexBuffer->sizeInBytes() / sizeof(uint16_t)); 1.720 + default: 1.721 + GrCrash("Unexpected Index Source."); 1.722 + return 0; 1.723 + } 1.724 + } 1.725 + 1.726 + // This method is called by copySurface The srcRect is guaranteed to be entirely within the 1.727 + // src bounds. Likewise, the dst rect implied by dstPoint and srcRect's width and height falls 1.728 + // entirely within the dst. The default implementation will draw a rect from the src to the 1.729 + // dst if the src is a texture and the dst is a render target and fail otherwise. 1.730 + virtual bool onCopySurface(GrSurface* dst, 1.731 + GrSurface* src, 1.732 + const SkIRect& srcRect, 1.733 + const SkIPoint& dstPoint); 1.734 + 1.735 + // Called to determine whether an onCopySurface call would succeed or not. This is useful for 1.736 + // proxy subclasses to test whether the copy would succeed without executing it yet. Derived 1.737 + // classes must keep this consistent with their implementation of onCopySurface(). The inputs 1.738 + // are the same as onCopySurface(), i.e. srcRect and dstPoint are clipped to be inside the src 1.739 + // and dst bounds. 1.740 + virtual bool onCanCopySurface(GrSurface* dst, 1.741 + GrSurface* src, 1.742 + const SkIRect& srcRect, 1.743 + const SkIPoint& dstPoint); 1.744 + 1.745 + GrContext* getContext() { return fContext; } 1.746 + const GrContext* getContext() const { return fContext; } 1.747 + 1.748 + // A subclass may override this function if it wishes to be notified when the clip is changed. 1.749 + // The override should call INHERITED::clipWillBeSet(). 1.750 + virtual void clipWillBeSet(const GrClipData* clipData); 1.751 + 1.752 + // subclasses must call this in their destructors to ensure all vertex 1.753 + // and index sources have been released (including those held by 1.754 + // pushGeometrySource()) 1.755 + void releaseGeometry(); 1.756 + 1.757 + // accessors for derived classes 1.758 + const GeometrySrcState& getGeomSrc() const { return fGeoSrcStateStack.back(); } 1.759 + // it is preferable to call this rather than getGeomSrc()->fVertexSize because of the assert. 1.760 + size_t getVertexSize() const { 1.761 + // the vertex layout is only valid if a vertex source has been specified. 1.762 + SkASSERT(this->getGeomSrc().fVertexSrc != kNone_GeometrySrcType); 1.763 + return this->getGeomSrc().fVertexSize; 1.764 + } 1.765 + 1.766 + // Subclass must initialize this in its constructor. 1.767 + SkAutoTUnref<const GrDrawTargetCaps> fCaps; 1.768 + 1.769 + /** 1.770 + * Used to communicate draws to subclass's onDraw function. 1.771 + */ 1.772 + class DrawInfo { 1.773 + public: 1.774 + DrawInfo(const DrawInfo& di) { (*this) = di; } 1.775 + DrawInfo& operator =(const DrawInfo& di); 1.776 + 1.777 + GrPrimitiveType primitiveType() const { return fPrimitiveType; } 1.778 + int startVertex() const { return fStartVertex; } 1.779 + int startIndex() const { return fStartIndex; } 1.780 + int vertexCount() const { return fVertexCount; } 1.781 + int indexCount() const { return fIndexCount; } 1.782 + int verticesPerInstance() const { return fVerticesPerInstance; } 1.783 + int indicesPerInstance() const { return fIndicesPerInstance; } 1.784 + int instanceCount() const { return fInstanceCount; } 1.785 + 1.786 + bool isIndexed() const { return fIndexCount > 0; } 1.787 +#ifdef SK_DEBUG 1.788 + bool isInstanced() const; // this version is longer because of asserts 1.789 +#else 1.790 + bool isInstanced() const { return fInstanceCount > 0; } 1.791 +#endif 1.792 + 1.793 + // adds or remove instances 1.794 + void adjustInstanceCount(int instanceOffset); 1.795 + // shifts the start vertex 1.796 + void adjustStartVertex(int vertexOffset); 1.797 + // shifts the start index 1.798 + void adjustStartIndex(int indexOffset); 1.799 + 1.800 + void setDevBounds(const SkRect& bounds) { 1.801 + fDevBoundsStorage = bounds; 1.802 + fDevBounds = &fDevBoundsStorage; 1.803 + } 1.804 + const SkRect* getDevBounds() const { return fDevBounds; } 1.805 + 1.806 + // NULL if no copy of the dst is needed for the draw. 1.807 + const GrDeviceCoordTexture* getDstCopy() const { 1.808 + if (NULL != fDstCopy.texture()) { 1.809 + return &fDstCopy; 1.810 + } else { 1.811 + return NULL; 1.812 + } 1.813 + } 1.814 + 1.815 + private: 1.816 + DrawInfo() { fDevBounds = NULL; } 1.817 + 1.818 + friend class GrDrawTarget; 1.819 + 1.820 + GrPrimitiveType fPrimitiveType; 1.821 + 1.822 + int fStartVertex; 1.823 + int fStartIndex; 1.824 + int fVertexCount; 1.825 + int fIndexCount; 1.826 + 1.827 + int fInstanceCount; 1.828 + int fVerticesPerInstance; 1.829 + int fIndicesPerInstance; 1.830 + 1.831 + SkRect fDevBoundsStorage; 1.832 + SkRect* fDevBounds; 1.833 + 1.834 + GrDeviceCoordTexture fDstCopy; 1.835 + }; 1.836 + 1.837 +private: 1.838 + // A subclass can optionally overload this function to be notified before 1.839 + // vertex and index space is reserved. 1.840 + virtual void willReserveVertexAndIndexSpace(int vertexCount, int indexCount) {} 1.841 + 1.842 + // implemented by subclass to allocate space for reserved geom 1.843 + virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) = 0; 1.844 + virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0; 1.845 + // implemented by subclass to handle release of reserved geom space 1.846 + virtual void releaseReservedVertexSpace() = 0; 1.847 + virtual void releaseReservedIndexSpace() = 0; 1.848 + // subclass must consume array contents when set 1.849 + virtual void onSetVertexSourceToArray(const void* vertexArray, int vertexCount) = 0; 1.850 + virtual void onSetIndexSourceToArray(const void* indexArray, int indexCount) = 0; 1.851 + // subclass is notified that geom source will be set away from an array 1.852 + virtual void releaseVertexArray() = 0; 1.853 + virtual void releaseIndexArray() = 0; 1.854 + // subclass overrides to be notified just before geo src state is pushed/popped. 1.855 + virtual void geometrySourceWillPush() = 0; 1.856 + virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0; 1.857 + // subclass called to perform drawing 1.858 + virtual void onDraw(const DrawInfo&) = 0; 1.859 + // Implementation of drawRect. The geometry src and vertex attribs will already 1.860 + // be saved before this is called and restored afterwards. A subclass may override 1.861 + // this to perform more optimal rect rendering. Its draws should be funneled through 1.862 + // one of the public GrDrawTarget draw methods (e.g. drawNonIndexed, 1.863 + // drawIndexedInstances, ...). The base class draws a two triangle fan using 1.864 + // drawNonIndexed from reserved vertex space. 1.865 + virtual void onDrawRect(const SkRect& rect, 1.866 + const SkMatrix* matrix, 1.867 + const SkRect* localRect, 1.868 + const SkMatrix* localMatrix); 1.869 + 1.870 + virtual void onStencilPath(const GrPath*, SkPath::FillType) = 0; 1.871 + virtual void onDrawPath(const GrPath*, SkPath::FillType, 1.872 + const GrDeviceCoordTexture* dstCopy) = 0; 1.873 + 1.874 + virtual void onInstantGpuTraceEvent(const char* marker) = 0; 1.875 + virtual void onPushGpuTraceEvent(const char* marker) = 0; 1.876 + virtual void onPopGpuTraceEvent() = 0; 1.877 + 1.878 + // helpers for reserving vertex and index space. 1.879 + bool reserveVertexSpace(size_t vertexSize, 1.880 + int vertexCount, 1.881 + void** vertices); 1.882 + bool reserveIndexSpace(int indexCount, void** indices); 1.883 + 1.884 + // called by drawIndexed and drawNonIndexed. Use a negative indexCount to 1.885 + // indicate non-indexed drawing. 1.886 + bool checkDraw(GrPrimitiveType type, int startVertex, 1.887 + int startIndex, int vertexCount, 1.888 + int indexCount) const; 1.889 + // called when setting a new vert/idx source to unref prev vb/ib 1.890 + void releasePreviousVertexSource(); 1.891 + void releasePreviousIndexSource(); 1.892 + 1.893 + // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required 1.894 + // but couldn't be made. Otherwise, returns true. 1.895 + bool setupDstReadIfNecessary(DrawInfo* info) { 1.896 + return this->setupDstReadIfNecessary(&info->fDstCopy, info->getDevBounds()); 1.897 + } 1.898 + bool setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds); 1.899 + 1.900 + // Check to see if this set of draw commands has been sent out 1.901 + virtual bool isIssued(uint32_t drawID) { return true; } 1.902 + 1.903 + enum { 1.904 + kPreallocGeoSrcStateStackCnt = 4, 1.905 + }; 1.906 + SkSTArray<kPreallocGeoSrcStateStackCnt, GeometrySrcState, true> fGeoSrcStateStack; 1.907 + const GrClipData* fClip; 1.908 + GrDrawState* fDrawState; 1.909 + GrDrawState fDefaultDrawState; 1.910 + // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget. 1.911 + GrContext* fContext; 1.912 + // To keep track that we always have at least as many debug marker pushes as pops 1.913 + int fPushGpuTraceCount; 1.914 + 1.915 + typedef SkRefCnt INHERITED; 1.916 +}; 1.917 + 1.918 +#endif