gfx/skia/trunk/src/gpu/GrDrawTarget.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2010 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #ifndef GrDrawTarget_DEFINED
michael@0 9 #define GrDrawTarget_DEFINED
michael@0 10
michael@0 11 #include "GrClipData.h"
michael@0 12 #include "GrDrawState.h"
michael@0 13 #include "GrIndexBuffer.h"
michael@0 14
michael@0 15 #include "SkClipStack.h"
michael@0 16 #include "SkMatrix.h"
michael@0 17 #include "SkPath.h"
michael@0 18 #include "SkTArray.h"
michael@0 19 #include "SkTLazy.h"
michael@0 20 #include "SkTypes.h"
michael@0 21 #include "SkXfermode.h"
michael@0 22
michael@0 23 class GrClipData;
michael@0 24 class GrDrawTargetCaps;
michael@0 25 class GrPath;
michael@0 26 class GrVertexBuffer;
michael@0 27 class SkStrokeRec;
michael@0 28
michael@0 29 class GrDrawTarget : public SkRefCnt {
michael@0 30 protected:
michael@0 31 class DrawInfo;
michael@0 32
michael@0 33 public:
michael@0 34 SK_DECLARE_INST_COUNT(GrDrawTarget)
michael@0 35
michael@0 36 ///////////////////////////////////////////////////////////////////////////
michael@0 37
michael@0 38 // The context may not be fully constructed and should not be used during GrDrawTarget
michael@0 39 // construction.
michael@0 40 GrDrawTarget(GrContext* context);
michael@0 41 virtual ~GrDrawTarget();
michael@0 42
michael@0 43 /**
michael@0 44 * Gets the capabilities of the draw target.
michael@0 45 */
michael@0 46 const GrDrawTargetCaps* caps() const { return fCaps.get(); }
michael@0 47
michael@0 48 /**
michael@0 49 * Sets the current clip to the region specified by clip. All draws will be
michael@0 50 * clipped against this clip if kClip_StateBit is enabled.
michael@0 51 *
michael@0 52 * Setting the clip may (or may not) zero out the client's stencil bits.
michael@0 53 *
michael@0 54 * @param description of the clipping region
michael@0 55 */
michael@0 56 void setClip(const GrClipData* clip);
michael@0 57
michael@0 58 /**
michael@0 59 * Gets the current clip.
michael@0 60 *
michael@0 61 * @return the clip.
michael@0 62 */
michael@0 63 const GrClipData* getClip() const;
michael@0 64
michael@0 65 /**
michael@0 66 * Sets the draw state object for the draw target. Note that this does not
michael@0 67 * make a copy. The GrDrawTarget will take a reference to passed object.
michael@0 68 * Passing NULL will cause the GrDrawTarget to use its own internal draw
michael@0 69 * state object rather than an externally provided one.
michael@0 70 */
michael@0 71 void setDrawState(GrDrawState* drawState);
michael@0 72
michael@0 73 /**
michael@0 74 * Read-only access to the GrDrawTarget's current draw state.
michael@0 75 */
michael@0 76 const GrDrawState& getDrawState() const { return *fDrawState; }
michael@0 77
michael@0 78 /**
michael@0 79 * Read-write access to the GrDrawTarget's current draw state. Note that
michael@0 80 * this doesn't ref.
michael@0 81 */
michael@0 82 GrDrawState* drawState() { return fDrawState; }
michael@0 83
michael@0 84 /**
michael@0 85 * Color alpha and coverage are two inputs to the drawing pipeline. For some
michael@0 86 * blend modes it is safe to fold the coverage into constant or per-vertex
michael@0 87 * color alpha value. For other blend modes they must be handled separately.
michael@0 88 * Depending on features available in the underlying 3D API this may or may
michael@0 89 * not be possible.
michael@0 90 *
michael@0 91 * This function considers the current draw state and the draw target's
michael@0 92 * capabilities to determine whether coverage can be handled correctly. The
michael@0 93 * following assumptions are made:
michael@0 94 * 1. The caller intends to somehow specify coverage. This can be
michael@0 95 * specified either by enabling a coverage stage on the GrDrawState or
michael@0 96 * via the vertex layout.
michael@0 97 * 2. Other than enabling coverage stages or enabling coverage in the
michael@0 98 * layout, the current configuration of the target's GrDrawState is as
michael@0 99 * it will be at draw time.
michael@0 100 */
michael@0 101 bool canApplyCoverage() const;
michael@0 102
michael@0 103 /** When we're using coverage AA but the blend is incompatible (given gpu
michael@0 104 * limitations) we should disable AA. */
michael@0 105 bool shouldDisableCoverageAAForBlend() {
michael@0 106 // Enable below if we should draw with AA even when it produces
michael@0 107 // incorrect blending.
michael@0 108 // return false;
michael@0 109 return !this->canApplyCoverage();
michael@0 110 }
michael@0 111
michael@0 112 /**
michael@0 113 * Given the current draw state and hw support, will HW AA lines be used (if
michael@0 114 * a line primitive type is drawn)?
michael@0 115 */
michael@0 116 bool willUseHWAALines() const;
michael@0 117
michael@0 118 /**
michael@0 119 * There are three types of "sources" of geometry (vertices and indices) for
michael@0 120 * draw calls made on the target. When performing an indexed draw, the
michael@0 121 * indices and vertices can use different source types. Once a source is
michael@0 122 * specified it can be used for multiple draws. However, the time at which
michael@0 123 * the geometry data is no longer editable depends on the source type.
michael@0 124 *
michael@0 125 * Sometimes it is necessary to perform a draw while upstack code has
michael@0 126 * already specified geometry that it isn't finished with. So there are push
michael@0 127 * and pop methods. This allows the client to push the sources, draw
michael@0 128 * something using alternate sources, and then pop to restore the original
michael@0 129 * sources.
michael@0 130 *
michael@0 131 * Aside from pushes and pops, a source remains valid until another source
michael@0 132 * is set or resetVertexSource / resetIndexSource is called. Drawing from
michael@0 133 * a reset source is an error.
michael@0 134 *
michael@0 135 * The three types of sources are:
michael@0 136 *
michael@0 137 * 1. A cpu array (set*SourceToArray). This is useful when the caller
michael@0 138 * already provided vertex data in a format compatible with a
michael@0 139 * GrVertexLayout. The data in the array is consumed at the time that
michael@0 140 * set*SourceToArray is called and subsequent edits to the array will not
michael@0 141 * be reflected in draws.
michael@0 142 *
michael@0 143 * 2. Reserve. This is most useful when the caller has data it must
michael@0 144 * transform before drawing and is not long-lived. The caller requests
michael@0 145 * that the draw target make room for some amount of vertex and/or index
michael@0 146 * data. The target provides ptrs to hold the vertex and/or index data.
michael@0 147 *
michael@0 148 * The data is writable up until the next drawIndexed, drawNonIndexed,
michael@0 149 * drawIndexedInstances, drawRect, copySurface, or pushGeometrySource. At
michael@0 150 * this point the data is frozen and the ptrs are no longer valid.
michael@0 151 *
michael@0 152 * Where the space is allocated and how it is uploaded to the GPU is
michael@0 153 * subclass-dependent.
michael@0 154 *
michael@0 155 * 3. Vertex and Index Buffers. This is most useful for geometry that will
michael@0 156 * is long-lived. When the data in the buffer is consumed depends on the
michael@0 157 * GrDrawTarget subclass. For deferred subclasses the caller has to
michael@0 158 * guarantee that the data is still available in the buffers at playback.
michael@0 159 * (TODO: Make this more automatic as we have done for read/write pixels)
michael@0 160 *
michael@0 161 * The size of each vertex is determined by querying the current GrDrawState.
michael@0 162 */
michael@0 163
michael@0 164 /**
michael@0 165 * Reserves space for vertices and/or indices. Zero can be specifed as
michael@0 166 * either the vertex or index count if the caller desires to only reserve
michael@0 167 * space for only indices or only vertices. If zero is specifed for
michael@0 168 * vertexCount then the vertex source will be unmodified and likewise for
michael@0 169 * indexCount.
michael@0 170 *
michael@0 171 * If the function returns true then the reserve suceeded and the vertices
michael@0 172 * and indices pointers will point to the space created.
michael@0 173 *
michael@0 174 * If the target cannot make space for the request then this function will
michael@0 175 * return false. If vertexCount was non-zero then upon failure the vertex
michael@0 176 * source is reset and likewise for indexCount.
michael@0 177 *
michael@0 178 * The pointers to the space allocated for vertices and indices remain valid
michael@0 179 * until a drawIndexed, drawNonIndexed, drawIndexedInstances, drawRect,
michael@0 180 * copySurface, or push/popGeomtrySource is called. At that point logically a
michael@0 181 * snapshot of the data is made and the pointers are invalid.
michael@0 182 *
michael@0 183 * @param vertexCount the number of vertices to reserve space for. Can be
michael@0 184 * 0. Vertex size is queried from the current GrDrawState.
michael@0 185 * @param indexCount the number of indices to reserve space for. Can be 0.
michael@0 186 * @param vertices will point to reserved vertex space if vertexCount is
michael@0 187 * non-zero. Illegal to pass NULL if vertexCount > 0.
michael@0 188 * @param indices will point to reserved index space if indexCount is
michael@0 189 * non-zero. Illegal to pass NULL if indexCount > 0.
michael@0 190 */
michael@0 191 bool reserveVertexAndIndexSpace(int vertexCount,
michael@0 192 int indexCount,
michael@0 193 void** vertices,
michael@0 194 void** indices);
michael@0 195
michael@0 196 /**
michael@0 197 * Provides hints to caller about the number of vertices and indices
michael@0 198 * that can be allocated cheaply. This can be useful if caller is reserving
michael@0 199 * space but doesn't know exactly how much geometry is needed.
michael@0 200 *
michael@0 201 * Also may hint whether the draw target should be flushed first. This is
michael@0 202 * useful for deferred targets.
michael@0 203 *
michael@0 204 * @param vertexCount in: hint about how many vertices the caller would
michael@0 205 * like to allocate. Vertex size is queried from the
michael@0 206 * current GrDrawState.
michael@0 207 * out: a hint about the number of vertices that can be
michael@0 208 * allocated cheaply. Negative means no hint.
michael@0 209 * Ignored if NULL.
michael@0 210 * @param indexCount in: hint about how many indices the caller would
michael@0 211 * like to allocate.
michael@0 212 * out: a hint about the number of indices that can be
michael@0 213 * allocated cheaply. Negative means no hint.
michael@0 214 * Ignored if NULL.
michael@0 215 *
michael@0 216 * @return true if target should be flushed based on the input values.
michael@0 217 */
michael@0 218 virtual bool geometryHints(int* vertexCount,
michael@0 219 int* indexCount) const;
michael@0 220
michael@0 221 /**
michael@0 222 * Sets source of vertex data for the next draw. Array must contain
michael@0 223 * the vertex data when this is called.
michael@0 224 *
michael@0 225 * @param vertexArray cpu array containing vertex data.
michael@0 226 * @param vertexCount the number of vertices in the array. Vertex size is
michael@0 227 * queried from the current GrDrawState.
michael@0 228 */
michael@0 229 void setVertexSourceToArray(const void* vertexArray, int vertexCount);
michael@0 230
michael@0 231 /**
michael@0 232 * Sets source of index data for the next indexed draw. Array must contain
michael@0 233 * the indices when this is called.
michael@0 234 *
michael@0 235 * @param indexArray cpu array containing index data.
michael@0 236 * @param indexCount the number of indices in the array.
michael@0 237 */
michael@0 238 void setIndexSourceToArray(const void* indexArray, int indexCount);
michael@0 239
michael@0 240 /**
michael@0 241 * Sets source of vertex data for the next draw. Data does not have to be
michael@0 242 * in the buffer until drawIndexed, drawNonIndexed, or drawIndexedInstances.
michael@0 243 *
michael@0 244 * @param buffer vertex buffer containing vertex data. Must be
michael@0 245 * unlocked before draw call. Vertex size is queried
michael@0 246 * from current GrDrawState.
michael@0 247 */
michael@0 248 void setVertexSourceToBuffer(const GrVertexBuffer* buffer);
michael@0 249
michael@0 250 /**
michael@0 251 * Sets source of index data for the next indexed draw. Data does not have
michael@0 252 * to be in the buffer until drawIndexed.
michael@0 253 *
michael@0 254 * @param buffer index buffer containing indices. Must be unlocked
michael@0 255 * before indexed draw call.
michael@0 256 */
michael@0 257 void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
michael@0 258
michael@0 259 /**
michael@0 260 * Resets vertex source. Drawing from reset vertices is illegal. Set vertex
michael@0 261 * source to reserved, array, or buffer before next draw. May be able to free
michael@0 262 * up temporary storage allocated by setVertexSourceToArray or
michael@0 263 * reserveVertexSpace.
michael@0 264 */
michael@0 265 void resetVertexSource();
michael@0 266
michael@0 267 /**
michael@0 268 * Resets index source. Indexed Drawing from reset indices is illegal. Set
michael@0 269 * index source to reserved, array, or buffer before next indexed draw. May
michael@0 270 * be able to free up temporary storage allocated by setIndexSourceToArray
michael@0 271 * or reserveIndexSpace.
michael@0 272 */
michael@0 273 void resetIndexSource();
michael@0 274
michael@0 275 /**
michael@0 276 * Query to find out if the vertex or index source is reserved.
michael@0 277 */
michael@0 278 bool hasReservedVerticesOrIndices() const {
michael@0 279 return kReserved_GeometrySrcType == this->getGeomSrc().fVertexSrc ||
michael@0 280 kReserved_GeometrySrcType == this->getGeomSrc().fIndexSrc;
michael@0 281 }
michael@0 282
michael@0 283 /**
michael@0 284 * Pushes and resets the vertex/index sources. Any reserved vertex / index
michael@0 285 * data is finalized (i.e. cannot be updated after the matching pop but can
michael@0 286 * be drawn from). Must be balanced by a pop.
michael@0 287 */
michael@0 288 void pushGeometrySource();
michael@0 289
michael@0 290 /**
michael@0 291 * Pops the vertex / index sources from the matching push.
michael@0 292 */
michael@0 293 void popGeometrySource();
michael@0 294
michael@0 295 /**
michael@0 296 * Draws indexed geometry using the current state and current vertex / index
michael@0 297 * sources.
michael@0 298 *
michael@0 299 * @param type The type of primitives to draw.
michael@0 300 * @param startVertex the vertex in the vertex array/buffer corresponding
michael@0 301 * to index 0
michael@0 302 * @param startIndex first index to read from index src.
michael@0 303 * @param vertexCount one greater than the max index.
michael@0 304 * @param indexCount the number of index elements to read. The index count
michael@0 305 * is effectively trimmed to the last completely
michael@0 306 * specified primitive.
michael@0 307 * @param devBounds optional bounds hint. This is a promise from the caller,
michael@0 308 * not a request for clipping.
michael@0 309 */
michael@0 310 void drawIndexed(GrPrimitiveType type,
michael@0 311 int startVertex,
michael@0 312 int startIndex,
michael@0 313 int vertexCount,
michael@0 314 int indexCount,
michael@0 315 const SkRect* devBounds = NULL);
michael@0 316
michael@0 317 /**
michael@0 318 * Draws non-indexed geometry using the current state and current vertex
michael@0 319 * sources.
michael@0 320 *
michael@0 321 * @param type The type of primitives to draw.
michael@0 322 * @param startVertex the vertex in the vertex array/buffer corresponding
michael@0 323 * to index 0
michael@0 324 * @param vertexCount one greater than the max index.
michael@0 325 * @param devBounds optional bounds hint. This is a promise from the caller,
michael@0 326 * not a request for clipping.
michael@0 327 */
michael@0 328 void drawNonIndexed(GrPrimitiveType type,
michael@0 329 int startVertex,
michael@0 330 int vertexCount,
michael@0 331 const SkRect* devBounds = NULL);
michael@0 332
michael@0 333 /**
michael@0 334 * Draws path into the stencil buffer. The fill must be either even/odd or
michael@0 335 * winding (not inverse or hairline). It will respect the HW antialias flag
michael@0 336 * on the draw state (if possible in the 3D API).
michael@0 337 */
michael@0 338 void stencilPath(const GrPath*, SkPath::FillType fill);
michael@0 339
michael@0 340 /**
michael@0 341 * Draws a path. Fill must not be a hairline. It will respect the HW
michael@0 342 * antialias flag on the draw state (if possible in the 3D API).
michael@0 343 */
michael@0 344 void drawPath(const GrPath*, SkPath::FillType fill);
michael@0 345
michael@0 346 /**
michael@0 347 * Helper function for drawing rects. It performs a geometry src push and pop
michael@0 348 * and thus will finalize any reserved geometry.
michael@0 349 *
michael@0 350 * @param rect the rect to draw
michael@0 351 * @param matrix optional matrix applied to rect (before viewMatrix)
michael@0 352 * @param localRect optional rect that specifies local coords to map onto
michael@0 353 * rect. If NULL then rect serves as the local coords.
michael@0 354 * @param localMatrix optional matrix applied to localRect. If
michael@0 355 * srcRect is non-NULL and srcMatrix is non-NULL
michael@0 356 * then srcRect will be transformed by srcMatrix.
michael@0 357 * srcMatrix can be NULL when no srcMatrix is desired.
michael@0 358 */
michael@0 359 void drawRect(const SkRect& rect,
michael@0 360 const SkMatrix* matrix,
michael@0 361 const SkRect* localRect,
michael@0 362 const SkMatrix* localMatrix) {
michael@0 363 AutoGeometryPush agp(this);
michael@0 364 this->onDrawRect(rect, matrix, localRect, localMatrix);
michael@0 365 }
michael@0 366
michael@0 367 /**
michael@0 368 * Helper for drawRect when the caller doesn't need separate local rects or matrices.
michael@0 369 */
michael@0 370 void drawSimpleRect(const SkRect& rect, const SkMatrix* matrix = NULL) {
michael@0 371 this->drawRect(rect, matrix, NULL, NULL);
michael@0 372 }
michael@0 373 void drawSimpleRect(const SkIRect& irect, const SkMatrix* matrix = NULL) {
michael@0 374 SkRect rect = SkRect::Make(irect);
michael@0 375 this->drawRect(rect, matrix, NULL, NULL);
michael@0 376 }
michael@0 377
michael@0 378 /**
michael@0 379 * This call is used to draw multiple instances of some geometry with a
michael@0 380 * given number of vertices (V) and indices (I) per-instance. The indices in
michael@0 381 * the index source must have the form i[k+I] == i[k] + V. Also, all indices
michael@0 382 * i[kI] ... i[(k+1)I-1] must be elements of the range kV ... (k+1)V-1. As a
michael@0 383 * concrete example, the following index buffer for drawing a series of
michael@0 384 * quads each as two triangles each satisfies these conditions with V=4 and
michael@0 385 * I=6:
michael@0 386 * (0,1,2,0,2,3, 4,5,6,4,6,7, 8,9,10,8,10,11, ...)
michael@0 387 *
michael@0 388 * The call assumes that the pattern of indices fills the entire index
michael@0 389 * source. The size of the index buffer limits the number of instances that
michael@0 390 * can be drawn by the GPU in a single draw. However, the caller may specify
michael@0 391 * any (positive) number for instanceCount and if necessary multiple GPU
michael@0 392 * draws will be issued. Moreover, when drawIndexedInstances is called
michael@0 393 * multiple times it may be possible for GrDrawTarget to group them into a
michael@0 394 * single GPU draw.
michael@0 395 *
michael@0 396 * @param type the type of primitives to draw
michael@0 397 * @param instanceCount the number of instances to draw. Each instance
michael@0 398 * consists of verticesPerInstance vertices indexed by
michael@0 399 * indicesPerInstance indices drawn as the primitive
michael@0 400 * type specified by type.
michael@0 401 * @param verticesPerInstance The number of vertices in each instance (V
michael@0 402 * in the above description).
michael@0 403 * @param indicesPerInstance The number of indices in each instance (I
michael@0 404 * in the above description).
michael@0 405 * @param devBounds optional bounds hint. This is a promise from the caller,
michael@0 406 * not a request for clipping.
michael@0 407 */
michael@0 408 void drawIndexedInstances(GrPrimitiveType type,
michael@0 409 int instanceCount,
michael@0 410 int verticesPerInstance,
michael@0 411 int indicesPerInstance,
michael@0 412 const SkRect* devBounds = NULL);
michael@0 413
michael@0 414 /**
michael@0 415 * Clear the current render target if one isn't passed in. Ignores the
michael@0 416 * clip and all other draw state (blend mode, stages, etc). Clears the
michael@0 417 * whole thing if rect is NULL, otherwise just the rect. If canIgnoreRect
michael@0 418 * is set then the entire render target can be optionally cleared.
michael@0 419 */
michael@0 420 virtual void clear(const SkIRect* rect,
michael@0 421 GrColor color,
michael@0 422 bool canIgnoreRect,
michael@0 423 GrRenderTarget* renderTarget = NULL) = 0;
michael@0 424
michael@0 425 /**
michael@0 426 * instantGpuTraceEvent places a single "sign post" type marker into command stream. The
michael@0 427 * argument marker will be the name of the annotation that is added.
michael@0 428 */
michael@0 429 void instantGpuTraceEvent(const char* marker);
michael@0 430 /**
michael@0 431 * The following two functions are used for marking groups of commands. Use pushGpuTraceEvent
michael@0 432 * to set the beginning of a command set, and popGpuTraceEvent is be called at end of the
michael@0 433 * command set. The argument marker is the name for the annotation that is added. The push and
michael@0 434 * pops can be used hierarchically, but every push must have a match pop.
michael@0 435 */
michael@0 436 void pushGpuTraceEvent(const char* marker);
michael@0 437 void popGpuTraceEvent();
michael@0 438
michael@0 439 /**
michael@0 440 * Copies a pixel rectangle from one surface to another. This call may finalize
michael@0 441 * reserved vertex/index data (as though a draw call was made). The src pixels
michael@0 442 * copied are specified by srcRect. They are copied to a rect of the same
michael@0 443 * size in dst with top left at dstPoint. If the src rect is clipped by the
michael@0 444 * src bounds then pixel values in the dst rect corresponding to area clipped
michael@0 445 * by the src rect are not overwritten. This method can fail and return false
michael@0 446 * depending on the type of surface, configs, etc, and the backend-specific
michael@0 447 * limitations. If rect is clipped out entirely by the src or dst bounds then
michael@0 448 * true is returned since there is no actual copy necessary to succeed.
michael@0 449 */
michael@0 450 bool copySurface(GrSurface* dst,
michael@0 451 GrSurface* src,
michael@0 452 const SkIRect& srcRect,
michael@0 453 const SkIPoint& dstPoint);
michael@0 454 /**
michael@0 455 * Function that determines whether a copySurface call would succeed without
michael@0 456 * performing the copy.
michael@0 457 */
michael@0 458 bool canCopySurface(GrSurface* dst,
michael@0 459 GrSurface* src,
michael@0 460 const SkIRect& srcRect,
michael@0 461 const SkIPoint& dstPoint);
michael@0 462
michael@0 463 /**
michael@0 464 * This is can be called before allocating a texture to be a dst for copySurface. It will
michael@0 465 * populate the origin, config, and flags fields of the desc such that copySurface is more
michael@0 466 * likely to succeed and be efficient.
michael@0 467 */
michael@0 468 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc);
michael@0 469
michael@0 470
michael@0 471 /**
michael@0 472 * Release any resources that are cached but not currently in use. This
michael@0 473 * is intended to give an application some recourse when resources are low.
michael@0 474 */
michael@0 475 virtual void purgeResources() {};
michael@0 476
michael@0 477 /**
michael@0 478 * For subclass internal use to invoke a call to onDraw(). See DrawInfo below.
michael@0 479 */
michael@0 480 void executeDraw(const DrawInfo& info) { this->onDraw(info); }
michael@0 481
michael@0 482 /**
michael@0 483 * For subclass internal use to invoke a call to onDrawPath().
michael@0 484 */
michael@0 485 void executeDrawPath(const GrPath* path, SkPath::FillType fill,
michael@0 486 const GrDeviceCoordTexture* dstCopy) {
michael@0 487 this->onDrawPath(path, fill, dstCopy);
michael@0 488 }
michael@0 489
michael@0 490 ////////////////////////////////////////////////////////////////////////////
michael@0 491
michael@0 492 /**
michael@0 493 * See AutoStateRestore below.
michael@0 494 */
michael@0 495 enum ASRInit {
michael@0 496 kPreserve_ASRInit,
michael@0 497 kReset_ASRInit
michael@0 498 };
michael@0 499
michael@0 500 /**
michael@0 501 * Saves off the current state and restores it in the destructor. It will
michael@0 502 * install a new GrDrawState object on the target (setDrawState) and restore
michael@0 503 * the previous one in the destructor. The caller should call drawState() to
michael@0 504 * get the new draw state after the ASR is installed.
michael@0 505 *
michael@0 506 * GrDrawState* state = target->drawState();
michael@0 507 * AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit).
michael@0 508 * state->setRenderTarget(rt); // state refers to the GrDrawState set on
michael@0 509 * // target before asr was initialized.
michael@0 510 * // Therefore, rt is set on the GrDrawState
michael@0 511 * // that will be restored after asr's
michael@0 512 * // destructor rather than target's current
michael@0 513 * // GrDrawState.
michael@0 514 */
michael@0 515 class AutoStateRestore : public ::SkNoncopyable {
michael@0 516 public:
michael@0 517 /**
michael@0 518 * Default ASR will have no effect unless set() is subsequently called.
michael@0 519 */
michael@0 520 AutoStateRestore();
michael@0 521
michael@0 522 /**
michael@0 523 * Saves the state on target. The state will be restored when the ASR
michael@0 524 * is destroyed. If this constructor is used do not call set().
michael@0 525 *
michael@0 526 * @param init Should the newly installed GrDrawState be a copy of the
michael@0 527 * previous state or a default-initialized GrDrawState.
michael@0 528 * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's
michael@0 529 * matrix will be preconcat'ed with the param. All stages will be
michael@0 530 updated to compensate for the matrix change. If init == kReset
michael@0 531 then the draw state's matrix will be this matrix.
michael@0 532 */
michael@0 533 AutoStateRestore(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL);
michael@0 534
michael@0 535 ~AutoStateRestore();
michael@0 536
michael@0 537 /**
michael@0 538 * Saves the state on target. The state will be restored when the ASR
michael@0 539 * is destroyed. This should only be called once per ASR object and only
michael@0 540 * when the default constructor was used. For nested saves use multiple
michael@0 541 * ASR objects.
michael@0 542 *
michael@0 543 * @param init Should the newly installed GrDrawState be a copy of the
michael@0 544 * previous state or a default-initialized GrDrawState.
michael@0 545 * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's
michael@0 546 * matrix will be preconcat'ed with the param. All stages will be
michael@0 547 updated to compensate for the matrix change. If init == kReset
michael@0 548 then the draw state's matrix will be this matrix.
michael@0 549 */
michael@0 550 void set(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL);
michael@0 551
michael@0 552 /**
michael@0 553 * Like set() but makes the view matrix identity. When init is kReset it is as though
michael@0 554 * NULL was passed to set's viewMatrix param. When init is kPreserve it is as though
michael@0 555 * the inverse view matrix was passed. If kPreserve is passed and the draw state's matrix
michael@0 556 * is not invertible then this may fail.
michael@0 557 */
michael@0 558 bool setIdentity(GrDrawTarget* target, ASRInit init);
michael@0 559
michael@0 560 private:
michael@0 561 GrDrawTarget* fDrawTarget;
michael@0 562 SkTLazy<GrDrawState> fTempState;
michael@0 563 GrDrawState* fSavedState;
michael@0 564 };
michael@0 565
michael@0 566 ////////////////////////////////////////////////////////////////////////////
michael@0 567
michael@0 568 class AutoReleaseGeometry : public ::SkNoncopyable {
michael@0 569 public:
michael@0 570 AutoReleaseGeometry(GrDrawTarget* target,
michael@0 571 int vertexCount,
michael@0 572 int indexCount);
michael@0 573 AutoReleaseGeometry();
michael@0 574 ~AutoReleaseGeometry();
michael@0 575 bool set(GrDrawTarget* target,
michael@0 576 int vertexCount,
michael@0 577 int indexCount);
michael@0 578 bool succeeded() const { return NULL != fTarget; }
michael@0 579 void* vertices() const { SkASSERT(this->succeeded()); return fVertices; }
michael@0 580 void* indices() const { SkASSERT(this->succeeded()); return fIndices; }
michael@0 581 GrPoint* positions() const {
michael@0 582 return static_cast<GrPoint*>(this->vertices());
michael@0 583 }
michael@0 584
michael@0 585 private:
michael@0 586 void reset();
michael@0 587
michael@0 588 GrDrawTarget* fTarget;
michael@0 589 void* fVertices;
michael@0 590 void* fIndices;
michael@0 591 };
michael@0 592
michael@0 593 ////////////////////////////////////////////////////////////////////////////
michael@0 594
michael@0 595 class AutoClipRestore : public ::SkNoncopyable {
michael@0 596 public:
michael@0 597 AutoClipRestore(GrDrawTarget* target) {
michael@0 598 fTarget = target;
michael@0 599 fClip = fTarget->getClip();
michael@0 600 }
michael@0 601
michael@0 602 AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip);
michael@0 603
michael@0 604 ~AutoClipRestore() {
michael@0 605 fTarget->setClip(fClip);
michael@0 606 }
michael@0 607 private:
michael@0 608 GrDrawTarget* fTarget;
michael@0 609 const GrClipData* fClip;
michael@0 610 SkTLazy<SkClipStack> fStack;
michael@0 611 GrClipData fReplacementClip;
michael@0 612 };
michael@0 613
michael@0 614 ////////////////////////////////////////////////////////////////////////////
michael@0 615
michael@0 616 /**
michael@0 617 * Saves the geometry src state at construction and restores in the destructor. It also saves
michael@0 618 * and then restores the vertex attrib state.
michael@0 619 */
michael@0 620 class AutoGeometryPush : public ::SkNoncopyable {
michael@0 621 public:
michael@0 622 AutoGeometryPush(GrDrawTarget* target)
michael@0 623 : fAttribRestore(target->drawState()) {
michael@0 624 SkASSERT(NULL != target);
michael@0 625 fTarget = target;
michael@0 626 target->pushGeometrySource();
michael@0 627 }
michael@0 628
michael@0 629 ~AutoGeometryPush() { fTarget->popGeometrySource(); }
michael@0 630
michael@0 631 private:
michael@0 632 GrDrawTarget* fTarget;
michael@0 633 GrDrawState::AutoVertexAttribRestore fAttribRestore;
michael@0 634 };
michael@0 635
michael@0 636 /**
michael@0 637 * Combination of AutoGeometryPush and AutoStateRestore. The vertex attribs will be in default
michael@0 638 * state regardless of ASRInit value.
michael@0 639 */
michael@0 640 class AutoGeometryAndStatePush : public ::SkNoncopyable {
michael@0 641 public:
michael@0 642 AutoGeometryAndStatePush(GrDrawTarget* target,
michael@0 643 ASRInit init,
michael@0 644 const SkMatrix* viewMatrix = NULL)
michael@0 645 : fState(target, init, viewMatrix) {
michael@0 646 SkASSERT(NULL != target);
michael@0 647 fTarget = target;
michael@0 648 target->pushGeometrySource();
michael@0 649 if (kPreserve_ASRInit == init) {
michael@0 650 target->drawState()->setDefaultVertexAttribs();
michael@0 651 }
michael@0 652 }
michael@0 653
michael@0 654 ~AutoGeometryAndStatePush() { fTarget->popGeometrySource(); }
michael@0 655
michael@0 656 private:
michael@0 657 AutoStateRestore fState;
michael@0 658 GrDrawTarget* fTarget;
michael@0 659 };
michael@0 660
michael@0 661 ///////////////////////////////////////////////////////////////////////////
michael@0 662 // Draw execution tracking (for font atlases and other resources)
michael@0 663 class DrawToken {
michael@0 664 public:
michael@0 665 DrawToken(GrDrawTarget* drawTarget, uint32_t drawID) :
michael@0 666 fDrawTarget(drawTarget), fDrawID(drawID) {}
michael@0 667
michael@0 668 bool isIssued() { return NULL != fDrawTarget && fDrawTarget->isIssued(fDrawID); }
michael@0 669
michael@0 670 private:
michael@0 671 GrDrawTarget* fDrawTarget;
michael@0 672 uint32_t fDrawID; // this may wrap, but we're doing direct comparison
michael@0 673 // so that should be okay
michael@0 674 };
michael@0 675
michael@0 676 virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
michael@0 677
michael@0 678 protected:
michael@0 679
michael@0 680 enum GeometrySrcType {
michael@0 681 kNone_GeometrySrcType, //<! src has not been specified
michael@0 682 kReserved_GeometrySrcType, //<! src was set using reserve*Space
michael@0 683 kArray_GeometrySrcType, //<! src was set using set*SourceToArray
michael@0 684 kBuffer_GeometrySrcType //<! src was set using set*SourceToBuffer
michael@0 685 };
michael@0 686
michael@0 687 struct GeometrySrcState {
michael@0 688 GeometrySrcType fVertexSrc;
michael@0 689 union {
michael@0 690 // valid if src type is buffer
michael@0 691 const GrVertexBuffer* fVertexBuffer;
michael@0 692 // valid if src type is reserved or array
michael@0 693 int fVertexCount;
michael@0 694 };
michael@0 695
michael@0 696 GeometrySrcType fIndexSrc;
michael@0 697 union {
michael@0 698 // valid if src type is buffer
michael@0 699 const GrIndexBuffer* fIndexBuffer;
michael@0 700 // valid if src type is reserved or array
michael@0 701 int fIndexCount;
michael@0 702 };
michael@0 703
michael@0 704 size_t fVertexSize;
michael@0 705 };
michael@0 706
michael@0 707 int indexCountInCurrentSource() const {
michael@0 708 const GeometrySrcState& src = this->getGeomSrc();
michael@0 709 switch (src.fIndexSrc) {
michael@0 710 case kNone_GeometrySrcType:
michael@0 711 return 0;
michael@0 712 case kReserved_GeometrySrcType:
michael@0 713 case kArray_GeometrySrcType:
michael@0 714 return src.fIndexCount;
michael@0 715 case kBuffer_GeometrySrcType:
michael@0 716 return static_cast<int>(src.fIndexBuffer->sizeInBytes() / sizeof(uint16_t));
michael@0 717 default:
michael@0 718 GrCrash("Unexpected Index Source.");
michael@0 719 return 0;
michael@0 720 }
michael@0 721 }
michael@0 722
michael@0 723 // This method is called by copySurface The srcRect is guaranteed to be entirely within the
michael@0 724 // src bounds. Likewise, the dst rect implied by dstPoint and srcRect's width and height falls
michael@0 725 // entirely within the dst. The default implementation will draw a rect from the src to the
michael@0 726 // dst if the src is a texture and the dst is a render target and fail otherwise.
michael@0 727 virtual bool onCopySurface(GrSurface* dst,
michael@0 728 GrSurface* src,
michael@0 729 const SkIRect& srcRect,
michael@0 730 const SkIPoint& dstPoint);
michael@0 731
michael@0 732 // Called to determine whether an onCopySurface call would succeed or not. This is useful for
michael@0 733 // proxy subclasses to test whether the copy would succeed without executing it yet. Derived
michael@0 734 // classes must keep this consistent with their implementation of onCopySurface(). The inputs
michael@0 735 // are the same as onCopySurface(), i.e. srcRect and dstPoint are clipped to be inside the src
michael@0 736 // and dst bounds.
michael@0 737 virtual bool onCanCopySurface(GrSurface* dst,
michael@0 738 GrSurface* src,
michael@0 739 const SkIRect& srcRect,
michael@0 740 const SkIPoint& dstPoint);
michael@0 741
michael@0 742 GrContext* getContext() { return fContext; }
michael@0 743 const GrContext* getContext() const { return fContext; }
michael@0 744
michael@0 745 // A subclass may override this function if it wishes to be notified when the clip is changed.
michael@0 746 // The override should call INHERITED::clipWillBeSet().
michael@0 747 virtual void clipWillBeSet(const GrClipData* clipData);
michael@0 748
michael@0 749 // subclasses must call this in their destructors to ensure all vertex
michael@0 750 // and index sources have been released (including those held by
michael@0 751 // pushGeometrySource())
michael@0 752 void releaseGeometry();
michael@0 753
michael@0 754 // accessors for derived classes
michael@0 755 const GeometrySrcState& getGeomSrc() const { return fGeoSrcStateStack.back(); }
michael@0 756 // it is preferable to call this rather than getGeomSrc()->fVertexSize because of the assert.
michael@0 757 size_t getVertexSize() const {
michael@0 758 // the vertex layout is only valid if a vertex source has been specified.
michael@0 759 SkASSERT(this->getGeomSrc().fVertexSrc != kNone_GeometrySrcType);
michael@0 760 return this->getGeomSrc().fVertexSize;
michael@0 761 }
michael@0 762
michael@0 763 // Subclass must initialize this in its constructor.
michael@0 764 SkAutoTUnref<const GrDrawTargetCaps> fCaps;
michael@0 765
michael@0 766 /**
michael@0 767 * Used to communicate draws to subclass's onDraw function.
michael@0 768 */
michael@0 769 class DrawInfo {
michael@0 770 public:
michael@0 771 DrawInfo(const DrawInfo& di) { (*this) = di; }
michael@0 772 DrawInfo& operator =(const DrawInfo& di);
michael@0 773
michael@0 774 GrPrimitiveType primitiveType() const { return fPrimitiveType; }
michael@0 775 int startVertex() const { return fStartVertex; }
michael@0 776 int startIndex() const { return fStartIndex; }
michael@0 777 int vertexCount() const { return fVertexCount; }
michael@0 778 int indexCount() const { return fIndexCount; }
michael@0 779 int verticesPerInstance() const { return fVerticesPerInstance; }
michael@0 780 int indicesPerInstance() const { return fIndicesPerInstance; }
michael@0 781 int instanceCount() const { return fInstanceCount; }
michael@0 782
michael@0 783 bool isIndexed() const { return fIndexCount > 0; }
michael@0 784 #ifdef SK_DEBUG
michael@0 785 bool isInstanced() const; // this version is longer because of asserts
michael@0 786 #else
michael@0 787 bool isInstanced() const { return fInstanceCount > 0; }
michael@0 788 #endif
michael@0 789
michael@0 790 // adds or remove instances
michael@0 791 void adjustInstanceCount(int instanceOffset);
michael@0 792 // shifts the start vertex
michael@0 793 void adjustStartVertex(int vertexOffset);
michael@0 794 // shifts the start index
michael@0 795 void adjustStartIndex(int indexOffset);
michael@0 796
michael@0 797 void setDevBounds(const SkRect& bounds) {
michael@0 798 fDevBoundsStorage = bounds;
michael@0 799 fDevBounds = &fDevBoundsStorage;
michael@0 800 }
michael@0 801 const SkRect* getDevBounds() const { return fDevBounds; }
michael@0 802
michael@0 803 // NULL if no copy of the dst is needed for the draw.
michael@0 804 const GrDeviceCoordTexture* getDstCopy() const {
michael@0 805 if (NULL != fDstCopy.texture()) {
michael@0 806 return &fDstCopy;
michael@0 807 } else {
michael@0 808 return NULL;
michael@0 809 }
michael@0 810 }
michael@0 811
michael@0 812 private:
michael@0 813 DrawInfo() { fDevBounds = NULL; }
michael@0 814
michael@0 815 friend class GrDrawTarget;
michael@0 816
michael@0 817 GrPrimitiveType fPrimitiveType;
michael@0 818
michael@0 819 int fStartVertex;
michael@0 820 int fStartIndex;
michael@0 821 int fVertexCount;
michael@0 822 int fIndexCount;
michael@0 823
michael@0 824 int fInstanceCount;
michael@0 825 int fVerticesPerInstance;
michael@0 826 int fIndicesPerInstance;
michael@0 827
michael@0 828 SkRect fDevBoundsStorage;
michael@0 829 SkRect* fDevBounds;
michael@0 830
michael@0 831 GrDeviceCoordTexture fDstCopy;
michael@0 832 };
michael@0 833
michael@0 834 private:
michael@0 835 // A subclass can optionally overload this function to be notified before
michael@0 836 // vertex and index space is reserved.
michael@0 837 virtual void willReserveVertexAndIndexSpace(int vertexCount, int indexCount) {}
michael@0 838
michael@0 839 // implemented by subclass to allocate space for reserved geom
michael@0 840 virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) = 0;
michael@0 841 virtual bool onReserveIndexSpace(int indexCount, void** indices) = 0;
michael@0 842 // implemented by subclass to handle release of reserved geom space
michael@0 843 virtual void releaseReservedVertexSpace() = 0;
michael@0 844 virtual void releaseReservedIndexSpace() = 0;
michael@0 845 // subclass must consume array contents when set
michael@0 846 virtual void onSetVertexSourceToArray(const void* vertexArray, int vertexCount) = 0;
michael@0 847 virtual void onSetIndexSourceToArray(const void* indexArray, int indexCount) = 0;
michael@0 848 // subclass is notified that geom source will be set away from an array
michael@0 849 virtual void releaseVertexArray() = 0;
michael@0 850 virtual void releaseIndexArray() = 0;
michael@0 851 // subclass overrides to be notified just before geo src state is pushed/popped.
michael@0 852 virtual void geometrySourceWillPush() = 0;
michael@0 853 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
michael@0 854 // subclass called to perform drawing
michael@0 855 virtual void onDraw(const DrawInfo&) = 0;
michael@0 856 // Implementation of drawRect. The geometry src and vertex attribs will already
michael@0 857 // be saved before this is called and restored afterwards. A subclass may override
michael@0 858 // this to perform more optimal rect rendering. Its draws should be funneled through
michael@0 859 // one of the public GrDrawTarget draw methods (e.g. drawNonIndexed,
michael@0 860 // drawIndexedInstances, ...). The base class draws a two triangle fan using
michael@0 861 // drawNonIndexed from reserved vertex space.
michael@0 862 virtual void onDrawRect(const SkRect& rect,
michael@0 863 const SkMatrix* matrix,
michael@0 864 const SkRect* localRect,
michael@0 865 const SkMatrix* localMatrix);
michael@0 866
michael@0 867 virtual void onStencilPath(const GrPath*, SkPath::FillType) = 0;
michael@0 868 virtual void onDrawPath(const GrPath*, SkPath::FillType,
michael@0 869 const GrDeviceCoordTexture* dstCopy) = 0;
michael@0 870
michael@0 871 virtual void onInstantGpuTraceEvent(const char* marker) = 0;
michael@0 872 virtual void onPushGpuTraceEvent(const char* marker) = 0;
michael@0 873 virtual void onPopGpuTraceEvent() = 0;
michael@0 874
michael@0 875 // helpers for reserving vertex and index space.
michael@0 876 bool reserveVertexSpace(size_t vertexSize,
michael@0 877 int vertexCount,
michael@0 878 void** vertices);
michael@0 879 bool reserveIndexSpace(int indexCount, void** indices);
michael@0 880
michael@0 881 // called by drawIndexed and drawNonIndexed. Use a negative indexCount to
michael@0 882 // indicate non-indexed drawing.
michael@0 883 bool checkDraw(GrPrimitiveType type, int startVertex,
michael@0 884 int startIndex, int vertexCount,
michael@0 885 int indexCount) const;
michael@0 886 // called when setting a new vert/idx source to unref prev vb/ib
michael@0 887 void releasePreviousVertexSource();
michael@0 888 void releasePreviousIndexSource();
michael@0 889
michael@0 890 // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
michael@0 891 // but couldn't be made. Otherwise, returns true.
michael@0 892 bool setupDstReadIfNecessary(DrawInfo* info) {
michael@0 893 return this->setupDstReadIfNecessary(&info->fDstCopy, info->getDevBounds());
michael@0 894 }
michael@0 895 bool setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds);
michael@0 896
michael@0 897 // Check to see if this set of draw commands has been sent out
michael@0 898 virtual bool isIssued(uint32_t drawID) { return true; }
michael@0 899
michael@0 900 enum {
michael@0 901 kPreallocGeoSrcStateStackCnt = 4,
michael@0 902 };
michael@0 903 SkSTArray<kPreallocGeoSrcStateStackCnt, GeometrySrcState, true> fGeoSrcStateStack;
michael@0 904 const GrClipData* fClip;
michael@0 905 GrDrawState* fDrawState;
michael@0 906 GrDrawState fDefaultDrawState;
michael@0 907 // The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget.
michael@0 908 GrContext* fContext;
michael@0 909 // To keep track that we always have at least as many debug marker pushes as pops
michael@0 910 int fPushGpuTraceCount;
michael@0 911
michael@0 912 typedef SkRefCnt INHERITED;
michael@0 913 };
michael@0 914
michael@0 915 #endif

mercurial