SkRWBuffer.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright 2015 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef SkRWBuffer_DEFINED
  8. #define SkRWBuffer_DEFINED
  9. #include "include/core/SkRefCnt.h"
  10. struct SkBufferBlock;
  11. struct SkBufferHead;
  12. class SkRWBuffer;
  13. class SkStreamAsset;
  14. /**
  15. * Contains a read-only, thread-sharable block of memory. To access the memory, the caller must
  16. * instantiate a local iterator, as the memory is stored in 1 or more contiguous blocks.
  17. */
  18. class SK_API SkROBuffer : public SkRefCnt {
  19. public:
  20. /**
  21. * Return the logical length of the data owned/shared by this buffer. It may be stored in
  22. * multiple contiguous blocks, accessible via the iterator.
  23. */
  24. size_t size() const { return fAvailable; }
  25. class SK_API Iter {
  26. public:
  27. Iter(const SkROBuffer*);
  28. Iter(const sk_sp<SkROBuffer>&);
  29. void reset(const SkROBuffer*);
  30. /**
  31. * Return the current continuous block of memory, or nullptr if the iterator is exhausted
  32. */
  33. const void* data() const;
  34. /**
  35. * Returns the number of bytes in the current continguous block of memory, or 0 if the
  36. * iterator is exhausted.
  37. */
  38. size_t size() const;
  39. /**
  40. * Advance to the next contiguous block of memory, returning true if there is another
  41. * block, or false if the iterator is exhausted.
  42. */
  43. bool next();
  44. private:
  45. const SkBufferBlock* fBlock;
  46. size_t fRemaining;
  47. const SkROBuffer* fBuffer;
  48. };
  49. private:
  50. SkROBuffer(const SkBufferHead* head, size_t available, const SkBufferBlock* fTail);
  51. virtual ~SkROBuffer();
  52. const SkBufferHead* fHead;
  53. const size_t fAvailable;
  54. const SkBufferBlock* fTail;
  55. friend class SkRWBuffer;
  56. };
  57. /**
  58. * Accumulates bytes of memory that are "appended" to it, growing internal storage as needed.
  59. * The growth is done such that at any time in the writer's thread, an RBuffer or StreamAsset
  60. * can be snapped off (and safely passed to another thread). The RBuffer/StreamAsset snapshot
  61. * can see the previously stored bytes, but will be unaware of any future writes.
  62. */
  63. class SK_API SkRWBuffer {
  64. public:
  65. SkRWBuffer(size_t initialCapacity = 0);
  66. ~SkRWBuffer();
  67. size_t size() const { return fTotalUsed; }
  68. /**
  69. * Append |length| bytes from |buffer|.
  70. *
  71. * If the caller knows in advance how much more data they are going to append, they can
  72. * pass a |reserve| hint (representing the number of upcoming bytes *in addition* to the
  73. * current append), to minimize the number of internal allocations.
  74. */
  75. void append(const void* buffer, size_t length, size_t reserve = 0);
  76. sk_sp<SkROBuffer> makeROBufferSnapshot() const {
  77. return sk_sp<SkROBuffer>(new SkROBuffer(fHead, fTotalUsed, fTail));
  78. }
  79. std::unique_ptr<SkStreamAsset> makeStreamSnapshot() const;
  80. #ifdef SK_DEBUG
  81. void validate() const;
  82. #else
  83. void validate() const {}
  84. #endif
  85. private:
  86. SkBufferHead* fHead;
  87. SkBufferBlock* fTail;
  88. size_t fTotalUsed;
  89. };
  90. #endif