OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrDrawState_DEFINED | 8 #ifndef GrDrawState_DEFINED |
9 #define GrDrawState_DEFINED | 9 #define GrDrawState_DEFINED |
10 | 10 |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 | 250 |
251 /// @} | 251 /// @} |
252 | 252 |
253 /////////////////////////////////////////////////////////////////////////// | 253 /////////////////////////////////////////////////////////////////////////// |
254 /// @name Attribute Bindings | 254 /// @name Attribute Bindings |
255 //// | 255 //// |
256 | 256 |
257 /** | 257 /** |
258 * The vertex data used by the current program is represented as a bitfield | 258 * The vertex data used by the current program is represented as a bitfield |
259 * of flags. Programs always use positions and may also use texture | 259 * of flags. Programs always use positions and may also use texture |
260 * coordinates, per-vertex colors, per-vertex coverage and edge data. Each | 260 * coordinates, per-vertex colors, per-vertex coverage and edge data. The |
261 * stage can use the explicit texture coordinates as its input texture | 261 * local coords accessible by effects may either come from positions or |
262 * coordinates or it may use the positions as texture coordinates. | 262 * be specified explicitly. |
263 */ | 263 */ |
264 | 264 |
265 /** | 265 /** |
266 * Generates a bit indicating that a texture stage uses texture coordinates | |
267 * | |
268 * @param stageIdx the stage that will use texture coordinates. | |
269 * | |
270 * @return the bit to add to a GrAttribBindings bitfield. | |
271 */ | |
272 static int ExplicitTexCoordAttribBindingsBit(int stageIdx) { | |
273 GrAssert(stageIdx < kNumStages); | |
274 return (1 << stageIdx); | |
275 } | |
276 | |
277 static bool StageBindsExplicitTexCoords(GrAttribBindings bindings, int stage Idx); | |
278 | |
279 /** | |
280 * Additional Bits that can be specified in GrAttribBindings. | 266 * Additional Bits that can be specified in GrAttribBindings. |
281 */ | 267 */ |
282 enum AttribBindingsBits { | 268 enum AttribBindingsBits { |
269 /** explicit local coords are provided (instead of using pre-view-matrix positions) */ | |
jvanverth1
2013/03/19 15:11:59
It may not matter, but for consistency's sake it'd
bsalomon
2013/03/19 15:22:25
Can do... but if we're about to get rid of them is
jvanverth1
2013/03/19 15:36:51
Well, like I said, it may not matter... :)
| |
270 kLocalCoords_AttribBindingsBit = 0x1, | |
283 /* program uses colors (GrColor) */ | 271 /* program uses colors (GrColor) */ |
284 kColor_AttribBindingsBit = 1 << (kNumStages + 0), | 272 kColor_AttribBindingsBit = 0x2, |
285 /* program uses coverage (GrColor) | 273 /* program uses coverage (GrColor) |
286 */ | 274 */ |
287 kCoverage_AttribBindingsBit = 1 << (kNumStages + 1), | 275 kCoverage_AttribBindingsBit = 0x4, |
288 /* program uses edge data. Distance to the edge is used to | 276 /* program uses edge data. Distance to the edge is used to |
289 * compute a coverage. See GrDrawState::setVertexEdgeType(). | 277 * compute a coverage. See GrDrawState::setVertexEdgeType(). |
290 */ | 278 */ |
291 kEdge_AttribBindingsBit = 1 << (kNumStages + 2), | 279 kEdge_AttribBindingsBit = 0x8, |
292 // for below assert | 280 // for below assert |
293 kDummyAttribBindingsBit, | 281 kDummyAttribBindingsBit, |
294 kHighAttribBindingsBit = kDummyAttribBindingsBit - 1 | 282 kHighAttribBindingsBit = kDummyAttribBindingsBit - 1 |
295 }; | 283 }; |
296 // make sure we haven't exceeded the number of bits in GrAttribBindings. | 284 // make sure we haven't exceeded the number of bits in GrAttribBindings. |
297 GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribB indings))); | 285 GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribB indings))); |
298 | 286 |
299 enum AttribBindings { | 287 enum AttribBindings { |
300 kDefault_AttribBindings = 0 | 288 kDefault_AttribBindings = 0 |
301 }; | 289 }; |
302 | 290 |
303 /** | 291 /** |
304 * Sets attribute bindings for next draw. | 292 * Sets attribute bindings for next draw. |
305 * | 293 * |
306 * @param bindings the attribute bindings to set. | 294 * @param bindings the attribute bindings to set. |
307 */ | 295 */ |
308 void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; } | 296 void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; } |
309 | 297 |
310 GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; } | 298 GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; } |
311 | 299 |
312 //////////////////////////////////////////////////////////////////////////// | 300 //////////////////////////////////////////////////////////////////////////// |
313 // Helpers for picking apart attribute bindings | 301 // Helpers for picking apart attribute bindings |
314 | 302 |
315 /** | 303 /** |
316 * Helper function to determine if program uses explicit texture | |
317 * coordinates. | |
318 * | |
319 * @param bindings attribute bindings to query | |
320 * | |
321 * @return true if program uses texture coordinates, | |
322 * false otherwise. | |
323 */ | |
324 static bool AttributesBindExplicitTexCoords(GrAttribBindings bindings); | |
325 | |
326 /** | |
327 * Determines whether src alpha is guaranteed to be one for all src pixels | 304 * Determines whether src alpha is guaranteed to be one for all src pixels |
328 */ | 305 */ |
329 bool srcAlphaWillBeOne(GrAttribBindings) const; | 306 bool srcAlphaWillBeOne(GrAttribBindings) const; |
330 | 307 |
331 /** | 308 /** |
332 * Determines whether the output coverage is guaranteed to be one for all pi xels hit by a draw. | 309 * Determines whether the output coverage is guaranteed to be one for all pi xels hit by a draw. |
333 */ | 310 */ |
334 bool hasSolidCoverage(GrAttribBindings) const; | 311 bool hasSolidCoverage(GrAttribBindings) const; |
335 | 312 |
336 static void VertexAttributesUnitTest(); | 313 static void VertexAttributesUnitTest(); |
(...skipping 12 matching lines...) Expand all Loading... | |
349 * attribute index if we're binding attributes in GL. | 326 * attribute index if we're binding attributes in GL. |
350 * | 327 * |
351 * Indices which do not have active attribute bindings will be ignored. | 328 * Indices which do not have active attribute bindings will be ignored. |
352 */ | 329 */ |
353 | 330 |
354 enum AttribIndex { | 331 enum AttribIndex { |
355 kPosition_AttribIndex = 0, | 332 kPosition_AttribIndex = 0, |
356 kColor_AttribIndex, | 333 kColor_AttribIndex, |
357 kCoverage_AttribIndex, | 334 kCoverage_AttribIndex, |
358 kEdge_AttribIndex, | 335 kEdge_AttribIndex, |
359 kTexCoord_AttribIndex, | 336 kLocalCoords_AttribIndex, |
360 | 337 |
361 kLast_AttribIndex = kTexCoord_AttribIndex | 338 kLast_AttribIndex = kLocalCoords_AttribIndex |
362 }; | 339 }; |
363 static const int kAttribIndexCount = kLast_AttribIndex + 1; | 340 static const int kAttribIndexCount = kLast_AttribIndex + 1; |
364 | 341 |
365 // these are used when vertex color and coverage isn't set | 342 // these are used when vertex color and coverage isn't set |
366 enum { | 343 enum { |
367 kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt, | 344 kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt, |
368 kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1, | 345 kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1, |
369 }; | 346 }; |
370 | 347 |
371 //////////////////////////////////////////////////////////////////////////// | 348 //////////////////////////////////////////////////////////////////////////// |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
403 * (r,g,b,a) = (alpha, alpha, alpha, alpha). | 380 * (r,g,b,a) = (alpha, alpha, alpha, alpha). |
404 * | 381 * |
405 * @param alpha The alpha value to set as the color. | 382 * @param alpha The alpha value to set as the color. |
406 */ | 383 */ |
407 void setAlpha(uint8_t a) { | 384 void setAlpha(uint8_t a) { |
408 this->setColor((a << 24) | (a << 16) | (a << 8) | a); | 385 this->setColor((a << 24) | (a << 16) | (a << 8) | a); |
409 } | 386 } |
410 | 387 |
411 /** | 388 /** |
412 * Add a color filter that can be represented by a color and a mode. Applied | 389 * Add a color filter that can be represented by a color and a mode. Applied |
413 * after color-computing texture stages. | 390 * after color-computing effect stages. |
414 */ | 391 */ |
415 void setColorFilter(GrColor c, SkXfermode::Mode mode) { | 392 void setColorFilter(GrColor c, SkXfermode::Mode mode) { |
416 fCommon.fColorFilterColor = c; | 393 fCommon.fColorFilterColor = c; |
417 fCommon.fColorFilterMode = mode; | 394 fCommon.fColorFilterMode = mode; |
418 } | 395 } |
419 | 396 |
420 GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; } | 397 GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; } |
421 SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMod e; } | 398 SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMod e; } |
422 | 399 |
423 /** | 400 /** |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
485 /// @name Effect Stages | 462 /// @name Effect Stages |
486 //// | 463 //// |
487 | 464 |
488 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect, | 465 const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect, |
489 const int* indices = NULL) { | 466 const int* indices = NULL) { |
490 fStages[stageIdx].setEffect(effect, indices); | 467 fStages[stageIdx].setEffect(effect, indices); |
491 return effect; | 468 return effect; |
492 } | 469 } |
493 | 470 |
494 /** | 471 /** |
495 * Creates a GrSimpleTextureEffect. | 472 * Creates a GrSimpleTextureEffect that uses local coords as texture coordin ates. |
496 */ | 473 */ |
497 void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& m atrix) { | 474 void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& m atrix) { |
498 GrAssert(!this->getStage(stageIdx).getEffect()); | 475 GrAssert(!this->getStage(stageIdx).getEffect()); |
499 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); | 476 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); |
500 this->setEffect(stageIdx, effect)->unref(); | 477 this->setEffect(stageIdx, effect)->unref(); |
501 } | 478 } |
502 void createTextureEffect(int stageIdx, | 479 void createTextureEffect(int stageIdx, |
503 GrTexture* texture, | 480 GrTexture* texture, |
504 const SkMatrix& matrix, | 481 const SkMatrix& matrix, |
505 const GrTextureParams& params) { | 482 const GrTextureParams& params) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
544 | 521 |
545 /** | 522 /** |
546 * Returns the current stage by index. | 523 * Returns the current stage by index. |
547 */ | 524 */ |
548 const GrEffectStage& getStage(int stageIdx) const { | 525 const GrEffectStage& getStage(int stageIdx) const { |
549 GrAssert((unsigned)stageIdx < kNumStages); | 526 GrAssert((unsigned)stageIdx < kNumStages); |
550 return fStages[stageIdx]; | 527 return fStages[stageIdx]; |
551 } | 528 } |
552 | 529 |
553 /** | 530 /** |
554 * Called when the source coord system is changing. preConcat gives the tran sformation from the | 531 * Called when the source coord system is changing. This ensures that effect s will see the |
555 * old coord system to the new coord system. | 532 * correct local coordinates. oldToNew gives the transformation from the old coord system in |
533 * which the geometry was specified to the new coordinate system from which it will be rendered. | |
556 */ | 534 */ |
557 void preConcatStageMatrices(const SkMatrix& preConcat) { | 535 void localCoordChange(const SkMatrix& oldToNew) { |
558 this->preConcatStageMatrices(~0U, preConcat); | |
559 } | |
560 /** | |
561 * Version of above that applies the update matrix selectively to stages via a mask. | |
562 */ | |
563 void preConcatStageMatrices(uint32_t stageMask, const SkMatrix& preConcat) { | |
564 for (int i = 0; i < kNumStages; ++i) { | 536 for (int i = 0; i < kNumStages; ++i) { |
565 if (((1 << i) & stageMask) && this->isStageEnabled(i)) { | 537 if (this->isStageEnabled(i)) { |
566 fStages[i].preConcatCoordChange(preConcat); | 538 fStages[i].localCoordChange(oldToNew); |
567 } | 539 } |
568 } | 540 } |
569 } | 541 } |
570 | 542 |
571 /** | |
572 * Called when the source coord system is changing. preConcatInverse is the inverse of the | |
573 * transformation from the old coord system to the new coord system. Returns false if the matrix | |
574 * cannot be inverted. | |
575 */ | |
576 bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) { | |
577 SkMatrix inv; | |
578 bool computed = false; | |
579 for (int i = 0; i < kNumStages; ++i) { | |
580 if (this->isStageEnabled(i)) { | |
581 if (!computed && !preConcatInverse.invert(&inv)) { | |
582 return false; | |
583 } else { | |
584 computed = true; | |
585 } | |
586 fStages[i].preConcatCoordChange(preConcatInverse); | |
587 } | |
588 } | |
589 return true; | |
590 } | |
591 | |
592 /// @} | 543 /// @} |
593 | 544 |
594 /////////////////////////////////////////////////////////////////////////// | 545 /////////////////////////////////////////////////////////////////////////// |
595 /// @name Coverage / Color Stages | 546 /// @name Coverage / Color Stages |
596 //// | 547 //// |
597 | 548 |
598 /** | 549 /** |
599 * A common pattern is to compute a color with the initial stages and then | 550 * A common pattern is to compute a color with the initial stages and then |
600 * modulate that color by a coverage value in later stage(s) (AA, mask- | 551 * modulate that color by a coverage value in later stage(s) (AA, mask- |
601 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be | 552 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
820 //////////////////////////////////////////////////////////////////////////// | 771 //////////////////////////////////////////////////////////////////////////// |
821 | 772 |
822 /** | 773 /** |
823 * Preconcats the current view matrix and restores the previous view matrix in the destructor. | 774 * Preconcats the current view matrix and restores the previous view matrix in the destructor. |
824 * Effect matrices are automatically adjusted to compensate. | 775 * Effect matrices are automatically adjusted to compensate. |
825 */ | 776 */ |
826 class AutoViewMatrixRestore : public ::GrNoncopyable { | 777 class AutoViewMatrixRestore : public ::GrNoncopyable { |
827 public: | 778 public: |
828 AutoViewMatrixRestore() : fDrawState(NULL) {} | 779 AutoViewMatrixRestore() : fDrawState(NULL) {} |
829 | 780 |
830 AutoViewMatrixRestore(GrDrawState* ds, | 781 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) { |
831 const SkMatrix& preconcatMatrix, | |
832 uint32_t explicitCoordStageMask = 0) { | |
833 fDrawState = NULL; | 782 fDrawState = NULL; |
834 this->set(ds, preconcatMatrix, explicitCoordStageMask); | 783 this->set(ds, preconcatMatrix); |
835 } | 784 } |
836 | 785 |
837 ~AutoViewMatrixRestore() { this->restore(); } | 786 ~AutoViewMatrixRestore() { this->restore(); } |
838 | 787 |
839 /** | 788 /** |
840 * Can be called prior to destructor to restore the original matrix. | 789 * Can be called prior to destructor to restore the original matrix. |
841 */ | 790 */ |
842 void restore(); | 791 void restore(); |
843 | 792 |
844 void set(GrDrawState* drawState, | 793 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix); |
845 const SkMatrix& preconcatMatrix, | |
846 uint32_t explicitCoordStageMask = 0); | |
847 | 794 |
848 bool isSet() const { return NULL != fDrawState; } | 795 bool isSet() const { return NULL != fDrawState; } |
849 | 796 |
850 private: | 797 private: |
851 GrDrawState* fDrawState; | 798 GrDrawState* fDrawState; |
852 SkMatrix fViewMatrix; | 799 SkMatrix fViewMatrix; |
853 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNum Stages]; | 800 GrEffectStage::SavedCoordChange fSavedCoordChanges[GrDrawState::kNum Stages]; |
854 uint32_t fRestoreMask; | 801 uint32_t fRestoreMask; |
855 }; | 802 }; |
856 | 803 |
857 //////////////////////////////////////////////////////////////////////////// | 804 //////////////////////////////////////////////////////////////////////////// |
858 | 805 |
859 /** | 806 /** |
860 * This sets the view matrix to identity and adjusts stage matrices to compe nsate. The | 807 * This sets the view matrix to identity and adjusts stage matrices to compe nsate. The |
861 * destructor undoes the changes, restoring the view matrix that was set bef ore the | 808 * destructor undoes the changes, restoring the view matrix that was set bef ore the |
862 * constructor. It is similar to passing the inverse of the current view mat rix to | 809 * constructor. It is similar to passing the inverse of the current view mat rix to |
863 * AutoViewMatrixRestore, but lazily computes the inverse only if necessary. | 810 * AutoViewMatrixRestore, but lazily computes the inverse only if necessary. |
864 */ | 811 */ |
865 class AutoDeviceCoordDraw : ::GrNoncopyable { | 812 class AutoDeviceCoordDraw : ::GrNoncopyable { |
866 public: | 813 public: |
867 AutoDeviceCoordDraw() : fDrawState(NULL) {} | 814 AutoDeviceCoordDraw() : fDrawState(NULL) {} |
868 /** | 815 /** |
869 * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to | 816 * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to |
870 * positions, then we don't want to modify its matrix. The explicitCoord StageMask is used | 817 * positions, then we don't want to modify its matrix. The explicitCoord StageMask is used |
871 * to specify such stages. | 818 * to specify such stages. |
872 */ | 819 */ |
873 AutoDeviceCoordDraw(GrDrawState* drawState, | 820 AutoDeviceCoordDraw(GrDrawState* drawState) { |
874 uint32_t explicitCoordStageMask = 0) { | |
875 fDrawState = NULL; | 821 fDrawState = NULL; |
876 this->set(drawState, explicitCoordStageMask); | 822 this->set(drawState); |
877 } | 823 } |
878 | 824 |
879 ~AutoDeviceCoordDraw() { this->restore(); } | 825 ~AutoDeviceCoordDraw() { this->restore(); } |
880 | 826 |
881 bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0); | 827 bool set(GrDrawState* drawState); |
882 | 828 |
883 /** | 829 /** |
884 * Returns true if this object was successfully initialized on to a GrDr awState. It may | 830 * Returns true if this object was successfully initialized on to a GrDr awState. It may |
885 * return false because a non-default constructor or set() were never ca lled or because | 831 * return false because a non-default constructor or set() were never ca lled or because |
886 * the view matrix was not invertible. | 832 * the view matrix was not invertible. |
887 */ | 833 */ |
888 bool succeeded() const { return NULL != fDrawState; } | 834 bool succeeded() const { return NULL != fDrawState; } |
889 | 835 |
890 /** | 836 /** |
891 * Returns the matrix that was set previously set on the drawState. This is only valid | 837 * Returns the matrix that was set previously set on the drawState. This is only valid |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1188 } | 1134 } |
1189 | 1135 |
1190 bool operator ==(const GrDrawState& s) const { | 1136 bool operator ==(const GrDrawState& s) const { |
1191 if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon ) { | 1137 if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon ) { |
1192 return false; | 1138 return false; |
1193 } | 1139 } |
1194 if (fVertexAttribs != s.fVertexAttribs) { | 1140 if (fVertexAttribs != s.fVertexAttribs) { |
1195 return false; | 1141 return false; |
1196 } | 1142 } |
1197 for (int i = 0; i < kAttribIndexCount; ++i) { | 1143 for (int i = 0; i < kAttribIndexCount; ++i) { |
1198 if ((i == kPosition_AttribIndex || | 1144 if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) && |
1199 s.fCommon.fAttribBindings & kAttribIndexMasks[i]) && | |
jvanverth1
2013/03/19 15:11:59
Can we get rid of kAttribIndexMasks now? It was on
bsalomon
2013/03/19 15:22:25
Yes, I was planning to do that in a follow-up chan
| |
1200 fAttribIndices[i] != s.fAttribIndices[i]) { | 1145 fAttribIndices[i] != s.fAttribIndices[i]) { |
1201 return false; | 1146 return false; |
1202 } | 1147 } |
1203 } | 1148 } |
1204 for (int i = 0; i < kNumStages; i++) { | 1149 for (int i = 0; i < kNumStages; i++) { |
1205 bool enabled = this->isStageEnabled(i); | 1150 bool enabled = this->isStageEnabled(i); |
1206 if (enabled != s.isStageEnabled(i)) { | 1151 if (enabled != s.isStageEnabled(i)) { |
1207 return false; | 1152 return false; |
1208 } | 1153 } |
1209 if (enabled && this->fStages[i] != s.fStages[i]) { | 1154 if (enabled && this->fStages[i] != s.fStages[i]) { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1363 int fAttribIndices[kAttribIndexCount]; | 1308 int fAttribIndices[kAttribIndexCount]; |
1364 GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs; | 1309 GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs; |
1365 GrEffectStage fStages[kNumStages]; | 1310 GrEffectStage fStages[kNumStages]; |
1366 | 1311 |
1367 typedef GrRefCnt INHERITED; | 1312 typedef GrRefCnt INHERITED; |
1368 }; | 1313 }; |
1369 | 1314 |
1370 GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags); | 1315 GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags); |
1371 | 1316 |
1372 #endif | 1317 #endif |
OLD | NEW |