1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef C2BUFFER_H_ 18#define C2BUFFER_H_ 19 20#include <C2.h> 21#include <C2Param.h> // for C2Info 22 23#include <list> 24#include <memory> 25 26typedef int C2Fence; 27 28#ifdef __ANDROID__ 29 30// #include <system/window.h> 31#include <cutils/native_handle.h> 32#include <hardware/gralloc.h> // TODO: remove 33 34typedef native_handle_t C2Handle; 35 36#else 37 38typedef void* C2Handle; 39 40#endif 41 42namespace android { 43 44/// \defgroup buffer Buffers 45/// @{ 46 47/// \defgroup buffer_sync Synchronization 48/// @{ 49 50/** 51 * Synchronization is accomplished using event and fence objects. 52 * 53 * These are cross-process extensions of promise/future infrastructure. 54 * Events are analogous to std::promise<void>, whereas fences are to std::shared_future<void>. 55 * 56 * Fences and events are shareable/copyable. 57 * 58 * Fences are used in two scenarios, and all copied instances refer to the same event. 59 * \todo do events need to be copyable or should they be unique? 60 * 61 * acquire sync fence object: signaled when it is safe for the component or client to access 62 * (the contents of) an object. 63 * 64 * release sync fence object: \todo 65 * 66 * Fences can be backed by hardware. Hardware fences are guaranteed to signal NO MATTER WHAT within 67 * a short (platform specific) amount of time; this guarantee is usually less than 15 msecs. 68 */ 69 70/** 71 * Fence object used by components and the framework. 72 * 73 * Implements the waiting for an event, analogous to a 'future'. 74 * 75 * To be implemented by vendors if using HW fences. 76 */ 77class C2Fence { 78public: 79 /** 80 * Waits for a fence to be signaled with a timeout. 81 * 82 * \todo a mechanism to cancel a wait - for now the only way to do this is to abandon the 83 * event, but fences are shared so canceling a wait will cancel all waits. 84 * 85 * \param timeoutNs the maximum time to wait in nsecs 86 * 87 * \retval C2_OK the fence has been signaled 88 * \retval C2_TIMED_OUT the fence has not been signaled within the timeout 89 * \retval C2_BAD_STATE the fence has been abandoned without being signaled (it will never 90 * be signaled) 91 * \retval C2_NO_PERMISSION no permission to wait for the fence (unexpected - system) 92 * \retval C2_CORRUPTED some unknown error prevented waiting for the fence (unexpected) 93 */ 94 C2Error wait(nsecs_t timeoutNs); 95 96 /** 97 * Used to check if this fence is valid (if there is a chance for it to be signaled.) 98 * A fence becomes invalid if the controling event is destroyed without it signaling the fence. 99 * 100 * \return whether this fence is valid 101 */ 102 bool valid() const; 103 104 /** 105 * Used to check if this fence has been signaled (is ready). 106 * 107 * \return whether this fence has been signaled 108 */ 109 bool ready() const; 110 111 /** 112 * Returns a file descriptor that can be used to wait for this fence in a select system call. 113 * \note The returned file descriptor, if valid, must be closed by the caller. 114 * 115 * This can be used in e.g. poll() system calls. This file becomes readable (POLLIN) when the 116 * fence is signaled, and bad (POLLERR) if the fence is abandoned. 117 * 118 * \return a file descriptor representing this fence (with ownership), or -1 if the fence 119 * has already been signaled (\todo or abandoned). 120 * 121 * \todo this must be compatible with fences used by gralloc 122 */ 123 int fd() const; 124 125 /** 126 * Returns whether this fence is a hardware-backed fence. 127 * \return whether this is a hardware fence 128 */ 129 bool isHW() const; 130 131private: 132 class Impl; 133 std::shared_ptr<Impl> mImpl; 134}; 135 136/** 137 * Event object used by components and the framework. 138 * 139 * Implements the signaling of an event, analogous to a 'promise'. 140 * 141 * Hardware backed events do not go through this object, and must be exposed directly as fences 142 * by vendors. 143 */ 144class C2Event { 145public: 146 /** 147 * Returns a fence for this event. 148 */ 149 C2Fence fence() const; 150 151 /** 152 * Signals (all) associated fence(s). 153 * This has no effect no effect if the event was already signaled or abandoned. 154 * 155 * \retval C2_OK the fence(s) were successfully signaled 156 * \retval C2_BAD_STATE the fence(s) have already been abandoned or merged (caller error) 157 * \retval C2_ALREADY_EXISTS the fence(s) have already been signaled (caller error) 158 * \retval C2_NO_PERMISSION no permission to signal the fence (unexpected - system) 159 * \retval C2_CORRUPTED some unknown error prevented signaling the fence(s) (unexpected) 160 */ 161 C2Error fire(); 162 163 /** 164 * Trigger this event from the merging of the supplied fences. This means that it will be 165 * abandoned if any of these fences have been abandoned, and it will be fired if all of these 166 * fences have been signaled. 167 * 168 * \retval C2_OK the merging was successfully done 169 * \retval C2_NO_MEMORY not enough memory to perform the merging 170 * \retval C2_ALREADY_EXISTS the fence have already been merged (caller error) 171 * \retval C2_BAD_STATE the fence have already been signaled or abandoned (caller error) 172 * \retval C2_NO_PERMISSION no permission to merge the fence (unexpected - system) 173 * \retval C2_CORRUPTED some unknown error prevented merging the fence(s) (unexpected) 174 */ 175 C2Error merge(std::vector<C2Fence> fences); 176 177 /** 178 * Abandons the event and any associated fence(s). 179 * \note Call this to explicitly abandon an event before it is destructed to avoid a warning. 180 * 181 * This has no effect no effect if the event was already signaled or abandoned. 182 * 183 * \retval C2_OK the fence(s) were successfully signaled 184 * \retval C2_BAD_STATE the fence(s) have already been signaled or merged (caller error) 185 * \retval C2_ALREADY_EXISTS the fence(s) have already been abandoned (caller error) 186 * \retval C2_NO_PERMISSION no permission to abandon the fence (unexpected - system) 187 * \retval C2_CORRUPTED some unknown error prevented signaling the fence(s) (unexpected) 188 */ 189 C2Error abandon(); 190 191private: 192 class Impl; 193 std::shared_ptr<Impl> mImpl; 194}; 195 196/// \addtogroup buf_internal Internal 197/// @{ 198 199/** 200 * Interface for objects that encapsulate an updatable error value. 201 */ 202struct _C2InnateError { 203 inline C2Error error() const { return mError; } 204 205protected: 206 _C2InnateError(C2Error error) : mError(error) { } 207 208 C2Error mError; // this error is updatable by the object 209}; 210 211/// @} 212 213/** 214 * This is a utility template for objects protected by an acquire fence, so that errors during 215 * acquiring the object are propagated to the object itself. 216 */ 217template<typename T> 218class C2Acquirable : public C2Fence { 219public: 220 /** 221 * Acquires the object protected by an acquire fence. Any errors during the mapping will be 222 * passed to the object. 223 * 224 * \return acquired object potentially invalidated if waiting for the fence failed. 225 */ 226 T get(); 227 228protected: 229 C2Acquirable(C2Error error, C2Fence fence, T t) : C2Fence(fence), mInitialError(error), mT(t) { } 230 231private: 232 C2Error mInitialError; 233 T mT; // TODO: move instead of copy 234}; 235 236/// @} 237 238/// \defgroup linear Linear Data Blocks 239/// @{ 240 241/************************************************************************************************** 242 LINEAR ASPECTS, BLOCKS AND VIEWS 243**************************************************************************************************/ 244 245/** 246 * Common aspect for all objects that have a linear capacity. 247 */ 248class _C2LinearCapacityAspect { 249/// \name Linear capacity interface 250/// @{ 251public: 252 inline uint32_t capacity() const { return mCapacity; } 253 254protected: 255 256#if UINTPTR_MAX == 0xffffffff 257 static_assert(sizeof(size_t) == sizeof(uint32_t), "size_t is too big"); 258#else 259 static_assert(sizeof(size_t) > sizeof(uint32_t), "size_t is too small"); 260 // explicitly disable construction from size_t 261 inline explicit _C2LinearCapacityAspect(size_t capacity) = delete; 262#endif 263 264 inline explicit _C2LinearCapacityAspect(uint32_t capacity) 265 : mCapacity(capacity) { } 266 267 inline explicit _C2LinearCapacityAspect(const _C2LinearCapacityAspect *parent) 268 : mCapacity(parent == nullptr ? 0 : parent->capacity()) { } 269 270private: 271 const uint32_t mCapacity; 272/// @} 273}; 274 275/** 276 * Aspect for objects that have a linear range. 277 * 278 * This class is copiable. 279 */ 280class _C2LinearRangeAspect : public _C2LinearCapacityAspect { 281/// \name Linear range interface 282/// @{ 283public: 284 inline uint32_t offset() const { return mOffset; } 285 inline uint32_t size() const { return mSize; } 286 287protected: 288 inline explicit _C2LinearRangeAspect(const _C2LinearCapacityAspect *parent) 289 : _C2LinearCapacityAspect(parent), 290 mOffset(0), 291 mSize(capacity()) { } 292 293 inline _C2LinearRangeAspect(const _C2LinearCapacityAspect *parent, size_t offset, size_t size) 294 : _C2LinearCapacityAspect(parent), 295 mOffset(c2_min(offset, capacity())), 296 mSize(c2_min(size, capacity() - mOffset)) { } 297 298 // subsection of the two [offset, offset + size] ranges 299 inline _C2LinearRangeAspect(const _C2LinearRangeAspect *parent, size_t offset, size_t size) 300 : _C2LinearCapacityAspect(parent == nullptr ? 0 : parent->capacity()), 301 mOffset(c2_min(c2_max(offset, parent == nullptr ? 0 : parent->offset()), capacity())), 302 mSize(c2_min(c2_min(size, parent == nullptr ? 0 : parent->size()), capacity() - mOffset)) { } 303 304private: 305 friend class _C2EditableLinearRange; 306 // invariants 0 <= mOffset <= mOffset + mSize <= capacity() 307 uint32_t mOffset; 308 uint32_t mSize; 309/// @} 310}; 311 312/** 313 * Aspect for objects that have an editable linear range. 314 * 315 * This class is copiable. 316 */ 317class _C2EditableLinearRange : public _C2LinearRangeAspect { 318protected: 319 inline explicit _C2EditableLinearRange(const _C2LinearCapacityAspect *parent) 320 : _C2LinearRangeAspect(parent) { } 321 322 inline _C2EditableLinearRange(const _C2LinearCapacityAspect *parent, size_t offset, size_t size) 323 : _C2LinearRangeAspect(parent, offset, size) { } 324 325 // subsection of the two [offset, offset + size] ranges 326 inline _C2EditableLinearRange(const _C2LinearRangeAspect *parent, size_t offset, size_t size) 327 : _C2LinearRangeAspect(parent, offset, size) { } 328 329/// \name Editable linear range interface 330/// @{ 331 332 /** 333 * Sets the offset to |offset|, while trying to keep the end of the buffer unchanged (e.g. 334 * size will grow if offset is decreased, and may shrink if offset is increased.) Returns 335 * true if successful, which is equivalent to if 0 <= |offset| <= capacity(). 336 * 337 * Note: setting offset and size will yield different result depending on the order of the 338 * operations. Always set offset first to ensure proper size. 339 */ 340 inline bool setOffset(uint32_t offset) { 341 if (offset > capacity()) { 342 return false; 343 } 344 345 if (offset > mOffset + mSize) { 346 mSize = 0; 347 } else { 348 mSize = mOffset + mSize - offset; 349 } 350 mOffset = offset; 351 return true; 352 } 353 /** 354 * Sets the size to |size|. Returns true if successful, which is equivalent to 355 * if 0 <= |size| <= capacity() - offset(). 356 * 357 * Note: setting offset and size will yield different result depending on the order of the 358 * operations. Always set offset first to ensure proper size. 359 */ 360 inline bool setSize(uint32_t size) { 361 if (size > capacity() - mOffset) { 362 return false; 363 } else { 364 mSize = size; 365 return true; 366 } 367 } 368 /** 369 * Sets the offset to |offset| with best effort. Same as setOffset() except that offset will 370 * be clamped to the buffer capacity. 371 * 372 * Note: setting offset and size (even using best effort) will yield different result depending 373 * on the order of the operations. Always set offset first to ensure proper size. 374 */ 375 inline void setOffset_be(uint32_t offset) { 376 if (offset > capacity()) { 377 offset = capacity(); 378 } 379 if (offset > mOffset + mSize) { 380 mSize = 0; 381 } else { 382 mSize = mOffset + mSize - offset; 383 } 384 mOffset = offset; 385 } 386 /** 387 * Sets the size to |size| with best effort. Same as setSize() except that the selected region 388 * will be clamped to the buffer capacity (e.g. size is clamped to [0, capacity() - offset()]). 389 * 390 * Note: setting offset and size (even using best effort) will yield different result depending 391 * on the order of the operations. Always set offset first to ensure proper size. 392 */ 393 inline void setSize_be(uint32_t size) { 394 mSize = std::min(size, capacity() - mOffset); 395 } 396/// @} 397}; 398 399// ================================================================================================ 400// BLOCKS 401// ================================================================================================ 402 403/** 404 * Blocks are sections of allocations. They can be either 1D or 2D. 405 */ 406 407class C2LinearAllocation; 408 409class C2Block1D : public _C2LinearRangeAspect { 410public: 411 const C2Handle *handle() const; 412 413protected: 414 C2Block1D(std::shared_ptr<C2LinearAllocation> alloc); 415 C2Block1D(std::shared_ptr<C2LinearAllocation> alloc, size_t offset, size_t size); 416 417private: 418 class Impl; 419 std::shared_ptr<Impl> mImpl; 420}; 421 422/** 423 * Read view provides read-only access for a linear memory segment. 424 * 425 * This class is copiable. 426 */ 427class C2ReadView : public _C2LinearCapacityAspect { 428public: 429 /** 430 * \return pointer to the start of the block or nullptr on error. 431 */ 432 const uint8_t *data(); 433 434 /** 435 * Returns a portion of this view. 436 * 437 * \param offset the start offset of the portion. \note This is clamped to the capacity of this 438 * view. 439 * \param size the size of the portion. \note This is clamped to the remaining data from offset. 440 * 441 * \return a read view containing a portion of this view 442 */ 443 C2ReadView subView(size_t offset, size_t size) const; 444 445 /** 446 * \return error during the creation/mapping of this view. 447 */ 448 C2Error error(); 449 450private: 451 class Impl; 452 std::shared_ptr<Impl> mImpl; 453}; 454 455/** 456 * Write view provides read/write access for a linear memory segment. 457 * 458 * This class is copiable. \todo movable only? 459 */ 460class C2WriteView : public _C2EditableLinearRange { 461public: 462 /** 463 * Start of the block. 464 * 465 * \return pointer to the start of the block or nullptr on error. 466 */ 467 uint8_t *base(); 468 469 /** 470 * \return pointer to the block at the current offset or nullptr on error. 471 */ 472 uint8_t *data(); 473 474 /** 475 * \return error during the creation/mapping of this view. 476 */ 477 C2Error error(); 478 479private: 480 class Impl; 481 /// \todo should this be unique_ptr to make this movable only - to avoid inconsistent regions 482 /// between copies. 483 std::shared_ptr<Impl> mImpl; 484}; 485 486/** 487 * A constant (read-only) linear block (portion of an allocation) with an acquire fence. 488 * Blocks are unmapped when created, and can be mapped into a read view on demand. 489 * 490 * This class is copiable and contains a reference to the allocation that it is based on. 491 */ 492class C2ConstLinearBlock : public C2Block1D { 493public: 494 /** 495 * Maps this block into memory and returns a read view for it. 496 * 497 * \return a read view for this block. 498 */ 499 C2Acquirable<C2ReadView> map() const; 500 501 /** 502 * Returns a portion of this block. 503 * 504 * \param offset the start offset of the portion. \note This is clamped to the capacity of this 505 * block. 506 * \param size the size of the portion. \note This is clamped to the remaining data from offset. 507 * 508 * \return a constant linear block containing a portion of this block 509 */ 510 C2ConstLinearBlock subBlock(size_t offset, size_t size) const; 511 512 /** 513 * Returns the acquire fence for this block. 514 * 515 * \return a fence that must be waited on before reading the block. 516 */ 517 C2Fence fence() const { return mFence; } 518 519private: 520 C2Fence mFence; 521}; 522 523/** 524 * Linear block is a writeable 1D block. Once written, it can be shared in whole or in parts with 525 * consumers/readers as read-only const linear block(s). 526 */ 527class C2LinearBlock : public C2Block1D { 528public: 529 /** 530 * Maps this block into memory and returns a write view for it. 531 * 532 * \return a write view for this block. 533 */ 534 C2Acquirable<C2WriteView> map(); 535 536 /** 537 * Creates a read-only const linear block for a portion of this block; optionally protected 538 * by an acquire fence. There are two ways to use this: 539 * 540 * 1) share ready block after writing data into the block. In this case no fence shall be 541 * supplied, and the block shall not be modified after calling this method. 542 * 2) share block metadata before actually (finishing) writing the data into the block. In 543 * this case a fence must be supplied that will be triggered when the data is written. 544 * The block shall be modified only until firing the event for the fence. 545 */ 546 C2ConstLinearBlock share(size_t offset, size_t size, C2Fence fence); 547}; 548 549/// @} 550 551/************************************************************************************************** 552 CIRCULAR BLOCKS AND VIEWS 553**************************************************************************************************/ 554 555/// \defgroup circular Circular buffer support 556/// @{ 557 558/** 559 * Circular blocks can be used to share data between a writer and a reader (and/or other consumers)- 560 * in a memory-efficient way by reusing a section of memory. Circular blocks are a bit more complex 561 * than single reader/single writer schemes to facilitate block-based consuming of data. 562 * 563 * They can operate in two modes: 564 * 565 * 1) one writer that creates blocks to be consumed (this model can be used by components) 566 * 567 * 2) one writer that writes continuously, and one reader that can creates blocks to be consumed 568 * by further recipients (this model is used by the framework, and cannot be used by components.) 569 * 570 * Circular blocks have four segments with running pointers: 571 * - reserved: data reserved and available for the writer 572 * - committed: data committed by the writer and available to the reader (if present) 573 * - used: data used by consumers (if present) 574 * - available: unused data available to be reserved 575 */ 576class C2CircularBlock : public C2Block1D { 577 // TODO: add methods 578 579private: 580 size_t mReserved __unused; // end of reserved section 581 size_t mCommitted __unused; // end of committed section 582 size_t mUsed __unused; // end of used section 583 size_t mFree __unused; // end of free section 584}; 585 586class _C2CircularBlockSegment : public _C2LinearCapacityAspect { 587public: 588 /** 589 * Returns the available size for this segment. 590 * 591 * \return currently available size for this segment 592 */ 593 size_t available() const; 594 595 /** 596 * Reserve some space for this segment from its current start. 597 * 598 * \param size desired space in bytes 599 * \param fence a pointer to an acquire fence. If non-null, the reservation is asynchronous and 600 * a fence will be stored here that will be signaled when the reservation is 601 * complete. If null, the reservation is synchronous. 602 * 603 * \retval C2_OK the space was successfully reserved 604 * \retval C2_NO_MEMORY the space requested cannot be reserved 605 * \retval C2_TIMED_OUT the reservation timed out \todo when? 606 * \retval C2_CORRUPTED some unknown error prevented reserving space. (unexpected) 607 */ 608 C2Error reserve(size_t size, C2Fence *fence /* nullable */); 609 610 /** 611 * Abandons a portion of this segment. This will move to the beginning of this segment. 612 * 613 * \note This methods is only allowed if this segment is producing blocks. 614 * 615 * \param size number of bytes to abandon 616 * 617 * \retval C2_OK the data was successfully abandoned 618 * \retval C2_TIMED_OUT the operation timed out (unexpected) 619 * \retval C2_CORRUPTED some unknown error prevented abandoning the data (unexpected) 620 */ 621 C2Error abandon(size_t size); 622 623 /** 624 * Share a portion as block(s) with consumers (these are moved to the used section). 625 * 626 * \note This methods is only allowed if this segment is producing blocks. 627 * \note Share does not move the beginning of the segment. (\todo add abandon/offset?) 628 * 629 * \param size number of bytes to share 630 * \param fence fence to be used for the section 631 * \param blocks list where the blocks of the section are appended to 632 * 633 * \retval C2_OK the portion was successfully shared 634 * \retval C2_NO_MEMORY not enough memory to share the portion 635 * \retval C2_TIMED_OUT the operation timed out (unexpected) 636 * \retval C2_CORRUPTED some unknown error prevented sharing the data (unexpected) 637 */ 638 C2Error share(size_t size, C2Fence fence, std::list<C2ConstLinearBlock> &blocks); 639 640 /** 641 * Returns the beginning offset of this segment from the start of this circular block. 642 * 643 * @return beginning offset 644 */ 645 size_t begin(); 646 647 /** 648 * Returns the end offset of this segment from the start of this circular block. 649 * 650 * @return end offset 651 */ 652 size_t end(); 653}; 654 655/** 656 * A circular write-view is a dynamic mapped view for a segment of a circular block. Care must be 657 * taken when using this view so that only the section owned by the segment is modified. 658 */ 659class C2CircularWriteView : public _C2LinearCapacityAspect { 660public: 661 /** 662 * Start of the circular block. 663 * \note the segment does not own this pointer. 664 * 665 * \return pointer to the start of the circular block or nullptr on error. 666 */ 667 uint8_t *base(); 668 669 /** 670 * \return error during the creation/mapping of this view. 671 */ 672 C2Error error(); 673}; 674 675/** 676 * The writer of a circular buffer. 677 * 678 * Can commit data to a reader (not supported for components) OR share data blocks directly with a 679 * consumer. 680 * 681 * If a component supports outputting data into circular buffers, it must allocate a circular 682 * block and use a circular writer. 683 */ 684class C2CircularWriter : public _C2CircularBlockSegment { 685public: 686 /** 687 * Commits a portion of this segment to the next segment. This moves the beginning of the 688 * segment. 689 * 690 * \param size number of bytes to commit to the next segment 691 * \param fence fence used for the commit (the fence must signal before the data is committed) 692 */ 693 C2Error commit(size_t size, C2Fence fence); 694 695 /** 696 * Maps this block into memory and returns a write view for it. 697 * 698 * \return a write view for this block. 699 */ 700 C2Acquirable<C2CircularWriteView> map(); 701}; 702 703/// @} 704 705/// \defgroup graphic Graphic Data Blocks 706/// @{ 707 708/** 709 * Interface for objects that have a width and height (planar capacity). 710 */ 711class _C2PlanarCapacityAspect { 712/// \name Planar capacity interface 713/// @{ 714public: 715 inline uint32_t width() const { return mWidth; } 716 inline uint32_t height() const { return mHeight; } 717 718protected: 719 inline _C2PlanarCapacityAspect(uint32_t width, uint32_t height) 720 : mWidth(width), mHeight(height) { } 721 722 inline _C2PlanarCapacityAspect(const _C2PlanarCapacityAspect *parent) 723 : mWidth(parent == nullptr ? 0 : parent->width()), 724 mHeight(parent == nullptr ? 0 : parent->height()) { } 725 726private: 727 const uint32_t mWidth; 728 const uint32_t mHeight; 729/// @} 730}; 731 732/** 733 * C2Rect: rectangle type with non-negative coordinates. 734 * 735 * \note This struct has public fields without getters/setters. All methods are inline. 736 */ 737struct C2Rect { 738// public: 739 uint32_t mLeft; 740 uint32_t mTop; 741 uint32_t mWidth; 742 uint32_t mHeight; 743 744 inline C2Rect(uint32_t width, uint32_t height) 745 : C2Rect(width, height, 0, 0) { } 746 747 inline C2Rect(uint32_t width, uint32_t height, uint32_t left, uint32_t top) 748 : mLeft(left), mTop(top), mWidth(width), mHeight(height) { } 749 750 // utility methods 751 752 inline bool isEmpty() const { 753 return mWidth == 0 || mHeight == 0; 754 } 755 756 inline bool isValid() const { 757 return mLeft <= ~mWidth && mTop <= ~mHeight; 758 } 759 760 inline operator bool() const { 761 return isValid() && !isEmpty(); 762 } 763 764 inline bool operator!() const { 765 return !bool(*this); 766 } 767 768 inline bool contains(const C2Rect &other) const { 769 if (!isValid() || !other.isValid()) { 770 return false; 771 } else if (other.isEmpty()) { 772 return true; 773 } else { 774 return mLeft <= other.mLeft && mTop <= other.mTop 775 && mLeft + mWidth >= other.mLeft + other.mWidth 776 && mTop + mHeight >= other.mTop + other.mHeight; 777 } 778 } 779 780 inline bool operator==(const C2Rect &other) const { 781 if (!isValid()) { 782 return !other.isValid(); 783 } else if (isEmpty()) { 784 return other.isEmpty(); 785 } else { 786 return mLeft == other.mLeft && mTop == other.mTop 787 && mWidth == other.mWidth && mHeight == other.mHeight; 788 } 789 } 790 791 inline bool operator!=(const C2Rect &other) const { 792 return !operator==(other); 793 } 794 795 inline bool operator>=(const C2Rect &other) const { 796 return contains(other); 797 } 798 799 inline bool operator>(const C2Rect &other) const { 800 return contains(other) && !operator==(other); 801 } 802 803 inline bool operator<=(const C2Rect &other) const { 804 return other.contains(*this); 805 } 806 807 inline bool operator<(const C2Rect &other) const { 808 return other.contains(*this) && !operator==(other); 809 } 810}; 811 812/** 813 * C2PlaneInfo: information on the layout of flexible planes. 814 * 815 * Public fields without getters/setters. 816 */ 817struct C2PlaneInfo { 818// public: 819 enum Channel : uint32_t { 820 Y, 821 R, 822 G, 823 B, 824 A, 825 Cr, 826 Cb, 827 } mChannel; 828 829 int32_t mColInc; // column increment in bytes. may be negative 830 int32_t mRowInc; // row increment in bytes. may be negative 831 uint32_t mHorizSubsampling; // subsampling compared to width 832 uint32_t mVertSubsampling; // subsampling compared to height 833 834 uint32_t mBitDepth; 835 uint32_t mAllocatedDepth; 836 837 inline ssize_t minOffset(uint32_t width, uint32_t height) { 838 ssize_t offs = 0; 839 if (width > 0 && mColInc < 0) { 840 offs += mColInc * (ssize_t)(width - 1); 841 } 842 if (height > 0 && mRowInc < 0) { 843 offs += mRowInc * (ssize_t)(height - 1); 844 } 845 return offs; 846 } 847 848 inline ssize_t maxOffset(uint32_t width, uint32_t height, uint32_t allocatedDepth) { 849 ssize_t offs = (allocatedDepth + 7) >> 3; 850 if (width > 0 && mColInc > 0) { 851 offs += mColInc * (ssize_t)(width - 1); 852 } 853 if (height > 0 && mRowInc > 0) { 854 offs += mRowInc * (ssize_t)(height - 1); 855 } 856 return offs; 857 } 858}; 859 860struct C2PlaneLayout { 861public: 862 enum Type : uint32_t { 863 MEDIA_IMAGE_TYPE_UNKNOWN = 0, 864 MEDIA_IMAGE_TYPE_YUV = 0x100, 865 MEDIA_IMAGE_TYPE_YUVA, 866 MEDIA_IMAGE_TYPE_RGB, 867 MEDIA_IMAGE_TYPE_RGBA, 868 }; 869 870 Type mType; 871 uint32_t mNumPlanes; // number of planes 872 873 enum PlaneIndex : uint32_t { 874 Y = 0, 875 U = 1, 876 V = 2, 877 R = 0, 878 G = 1, 879 B = 2, 880 A = 3, 881 MAX_NUM_PLANES = 4, 882 }; 883 884 C2PlaneInfo mPlanes[MAX_NUM_PLANES]; 885}; 886 887/** 888 * Aspect for objects that have a planar section (crop rectangle). 889 * 890 * This class is copiable. 891 */ 892class _C2PlanarSection : public _C2PlanarCapacityAspect { 893/// \name Planar section interface 894/// @{ 895public: 896 // crop can be an empty rect, does not have to line up with subsampling 897 // NOTE: we do not support floating-point crop 898 inline const C2Rect crop() { return mCrop; } 899 900 /** 901 * Sets crop to crop intersected with [(0,0) .. (width, height)] 902 */ 903 inline void setCrop_be(const C2Rect &crop); 904 905 /** 906 * If crop is within the dimensions of this object, it sets crop to it. 907 * 908 * \return true iff crop is within the dimensions of this object 909 */ 910 inline bool setCrop(const C2Rect &crop); 911 912private: 913 C2Rect mCrop; 914/// @} 915}; 916 917class C2Block2D : public _C2PlanarSection { 918public: 919 const C2Handle *handle() const; 920 921private: 922 class Impl; 923 std::shared_ptr<Impl> mImpl; 924}; 925 926/** 927 * Graphic view provides read or read-write access for a graphic block. 928 * 929 * This class is copiable. 930 * 931 * \note Due to the subsampling of graphic buffers, a read view must still contain a crop rectangle 932 * to ensure subsampling is followed. This results in nearly identical interface between read and 933 * write views, so C2GraphicView can encompass both of them. 934 */ 935class C2GraphicView : public _C2PlanarSection { 936public: 937 /** 938 * \return pointer to the start of the block or nullptr on error. 939 */ 940 const uint8_t *data() const; 941 942 /** 943 * \return pointer to the start of the block or nullptr on error. 944 */ 945 uint8_t *data(); 946 947 /** 948 * Returns a section of this view. 949 * 950 * \param rect the dimension of the section. \note This is clamped to the crop of this view. 951 * 952 * \return a read view containing the requested section of this view 953 */ 954 const C2GraphicView subView(const C2Rect &rect) const; 955 C2GraphicView subView(const C2Rect &rect); 956 957 /** 958 * \return error during the creation/mapping of this view. 959 */ 960 C2Error error() const; 961 962private: 963 class Impl; 964 std::shared_ptr<Impl> mImpl; 965}; 966 967/** 968 * A constant (read-only) graphic block (portion of an allocation) with an acquire fence. 969 * Blocks are unmapped when created, and can be mapped into a read view on demand. 970 * 971 * This class is copiable and contains a reference to the allocation that it is based on. 972 */ 973class C2ConstGraphicBlock : public C2Block2D { 974public: 975 /** 976 * Maps this block into memory and returns a read view for it. 977 * 978 * \return a read view for this block. 979 */ 980 C2Acquirable<const C2GraphicView> map() const; 981 982 /** 983 * Returns a section of this block. 984 * 985 * \param rect the coordinates of the section. \note This is clamped to the crop rectangle of 986 * this block. 987 * 988 * \return a constant graphic block containing a portion of this block 989 */ 990 C2ConstGraphicBlock subBlock(const C2Rect &rect) const; 991 992 /** 993 * Returns the acquire fence for this block. 994 * 995 * \return a fence that must be waited on before reading the block. 996 */ 997 C2Fence fence() const { return mFence; } 998 999private: 1000 C2Fence mFence; 1001}; 1002 1003/** 1004 * Graphic block is a writeable 2D block. Once written, it can be shared in whole or in part with 1005 * consumers/readers as read-only const graphic block. 1006 */ 1007class C2GraphicBlock : public C2Block2D { 1008public: 1009 /** 1010 * Maps this block into memory and returns a write view for it. 1011 * 1012 * \return a write view for this block. 1013 */ 1014 C2Acquirable<C2GraphicView> map(); 1015 1016 /** 1017 * Creates a read-only const linear block for a portion of this block; optionally protected 1018 * by an acquire fence. There are two ways to use this: 1019 * 1020 * 1) share ready block after writing data into the block. In this case no fence shall be 1021 * supplied, and the block shall not be modified after calling this method. 1022 * 2) share block metadata before actually (finishing) writing the data into the block. In 1023 * this case a fence must be supplied that will be triggered when the data is written. 1024 * The block shall be modified only until firing the event for the fence. 1025 */ 1026 C2ConstGraphicBlock share(const C2Rect &crop, C2Fence fence); 1027}; 1028 1029/// @} 1030 1031/// \defgroup buffer_onj Buffer objects 1032/// @{ 1033 1034// ================================================================================================ 1035// BUFFERS 1036// ================================================================================================ 1037 1038/// \todo: Do we still need this? 1039/// 1040// There are 2 kinds of buffers: linear or graphic. Linear buffers can contain a single block, or 1041// a list of blocks (LINEAR_CHUNKS). Support for list of blocks is optional, and can allow consuming 1042// data from circular buffers or scattered data sources without extra memcpy. Currently, list of 1043// graphic blocks is not supported. 1044 1045class C2LinearBuffer; // read-write buffer 1046class C2GraphicBuffer; // read-write buffer 1047class C2LinearChunksBuffer; 1048 1049/** 1050 * C2BufferData: the main, non-meta data of a buffer. A buffer can contain either linear blocks 1051 * or graphic blocks, and can contain either a single block or multiple blocks. This is determined 1052 * by its type. 1053 */ 1054class C2BufferData { 1055public: 1056 /** 1057 * The type of buffer data. 1058 */ 1059 enum Type : uint32_t { 1060 LINEAR, ///< the buffer contains a single linear block 1061 LINEAR_CHUNKS, ///< the buffer contains one or more linear blocks 1062 GRAPHIC, ///< the buffer contains a single graphic block 1063 GRAPHIC_CHUNKS, ///< the buffer contains one of more graphic blocks 1064 }; 1065 1066 /** 1067 * Gets the type of this buffer (data). 1068 * \return the type of this buffer data. 1069 */ 1070 Type type() const; 1071 1072 /** 1073 * Gets the linear blocks of this buffer. 1074 * \return a constant list of const linear blocks of this buffer. 1075 * \retval empty list if this buffer does not contain linear block(s). 1076 */ 1077 const std::list<C2ConstLinearBlock> linearBlocks() const; 1078 1079 /** 1080 * Gets the graphic blocks of this buffer. 1081 * \return a constant list of const graphic blocks of this buffer. 1082 * \retval empty list if this buffer does not contain graphic block(s). 1083 */ 1084 const std::list<C2ConstGraphicBlock> graphicBlocks() const; 1085 1086private: 1087 class Impl; 1088 std::shared_ptr<Impl> mImpl; 1089 1090protected: 1091 // no public constructor 1092 // C2BufferData(const std::shared_ptr<const Impl> &impl) : mImpl(impl) {} 1093}; 1094 1095/** 1096 * C2Buffer: buffer base class. These are always used as shared_ptrs. Though the underlying buffer 1097 * objects (native buffers, ion buffers, or dmabufs) are reference-counted by the system, 1098 * C2Buffers hold only a single reference. 1099 * 1100 * These objects cannot be used on the stack. 1101 */ 1102class C2Buffer { 1103public: 1104 /** 1105 * Gets the buffer's data. 1106 * 1107 * \return the buffer's data. 1108 */ 1109 const C2BufferData data() const; 1110 1111 /** 1112 * These will still work if used in onDeathNotify. 1113 */ 1114#if 0 1115 inline std::shared_ptr<C2LinearBuffer> asLinearBuffer() const { 1116 return mType == LINEAR ? std::shared_ptr::reinterpret_cast<C2LinearBuffer>(this) : nullptr; 1117 } 1118 1119 inline std::shared_ptr<C2GraphicBuffer> asGraphicBuffer() const { 1120 return mType == GRAPHIC ? std::shared_ptr::reinterpret_cast<C2GraphicBuffer>(this) : nullptr; 1121 } 1122 1123 inline std::shared_ptr<C2CircularBuffer> asCircularBuffer() const { 1124 return mType == CIRCULAR ? std::shared_ptr::reinterpret_cast<C2CircularBuffer>(this) : nullptr; 1125 } 1126#endif 1127 1128 ///@name Pre-destroy notification handling 1129 ///@{ 1130 1131 /** 1132 * Register for notification just prior to the destruction of this object. 1133 */ 1134 typedef void (*OnDestroyNotify) (const C2Buffer *buf, void *arg); 1135 1136 /** 1137 * Registers for a pre-destroy notification. This is called just prior to the destruction of 1138 * this buffer (when this buffer is no longer valid.) 1139 * 1140 * \param onDestroyNotify the notification callback 1141 * \param arg an arbitrary parameter passed to the callback 1142 * 1143 * \retval C2_OK the registration was successful. 1144 * \retval C2_DUPLICATE a notification was already registered for this callback and argument 1145 * \retval C2_NO_MEMORY not enough memory to register for this callback 1146 * \retval C2_CORRUPTED an unknown error prevented the registration (unexpected) 1147 */ 1148 C2Error registerOnDestroyNotify(OnDestroyNotify *onDestroyNotify, void *arg = nullptr); 1149 1150 /** 1151 * Unregisters a previously registered pre-destroy notification. 1152 * 1153 * \param onDestroyNotify the notification callback 1154 * \param arg an arbitrary parameter passed to the callback 1155 * 1156 * \retval C2_OK the unregistration was successful. 1157 * \retval C2_NOT_FOUND the notification was not found 1158 * \retval C2_CORRUPTED an unknown error prevented the registration (unexpected) 1159 */ 1160 C2Error unregisterOnDestroyNotify(OnDestroyNotify *onDestroyNotify, void *arg = nullptr); 1161 1162 ///@} 1163 1164 virtual ~C2Buffer() = default; 1165 1166 ///@name Buffer-specific arbitrary metadata handling 1167 ///@{ 1168 1169 /** 1170 * Gets the list of metadata associated with this buffer. 1171 * 1172 * \return a constant list of info objects associated with this buffer. 1173 */ 1174 const std::list<std::shared_ptr<const C2Info>> infos() const; 1175 1176 /** 1177 * Attaches (or updates) an (existing) metadata for this buffer. 1178 * If the metadata is stream specific, the stream information will be reset. 1179 * 1180 * \param info Metadata to update 1181 * 1182 * \retval C2_OK the metadata was successfully attached/updated. 1183 * \retval C2_NO_MEMORY not enough memory to attach the metadata (this return value is not 1184 * used if the same kind of metadata is already attached to the buffer). 1185 */ 1186 C2Error setInfo(const std::shared_ptr<C2Info> &info); 1187 1188 /** 1189 * Checks if there is a certain type of metadata attached to this buffer. 1190 * 1191 * \param index the parameter type of the metadata 1192 * 1193 * \return true iff there is a metadata with the parameter type attached to this buffer. 1194 */ 1195 bool hasInfo(C2Param::Type index) const; 1196 std::shared_ptr<C2Info> removeInfo(C2Param::Type index) const; 1197 ///@} 1198 1199protected: 1200 // no public constructor 1201 inline C2Buffer() = default; 1202 1203private: 1204// Type _mType; 1205}; 1206 1207/** 1208 * An extension of C2Info objects that can contain arbitrary buffer data. 1209 * 1210 * \note This object is not describable and contains opaque data. 1211 */ 1212class C2InfoBuffer { 1213public: 1214 /** 1215 * Gets the index of this info object. 1216 * 1217 * \return the parameter index. 1218 */ 1219 const C2Param::Index index() const; 1220 1221 /** 1222 * Gets the buffer's data. 1223 * 1224 * \return the buffer's data. 1225 */ 1226 const C2BufferData data() const; 1227}; 1228 1229/// @} 1230 1231/************************************************************************************************** 1232 ALLOCATIONS 1233**************************************************************************************************/ 1234 1235/// \defgroup allocator Allocation and memory placement 1236/// @{ 1237 1238/** 1239 * Buffer/memory usage bits. These are used by the allocators to select optimal memory type/pool and 1240 * buffer layout. 1241 * 1242 * \note This struct has public fields without getters/setters. All methods are inline. 1243 */ 1244struct C2MemoryUsage { 1245// public: 1246 // TODO: match these to gralloc1.h 1247 enum Consumer : uint64_t { 1248 kSoftwareRead = GRALLOC_USAGE_SW_READ_OFTEN, 1249 kRenderScriptRead = GRALLOC_USAGE_RENDERSCRIPT, 1250 kTextureRead = GRALLOC_USAGE_HW_TEXTURE, 1251 kHardwareComposer = GRALLOC_USAGE_HW_COMPOSER, 1252 kHardwareEncoder = GRALLOC_USAGE_HW_VIDEO_ENCODER, 1253 kProtectedRead = GRALLOC_USAGE_PROTECTED, 1254 }; 1255 1256 enum Producer : uint64_t { 1257 kSoftwareWrite = GRALLOC_USAGE_SW_WRITE_OFTEN, 1258 kRenderScriptWrite = GRALLOC_USAGE_RENDERSCRIPT, 1259 kTextureWrite = GRALLOC_USAGE_HW_RENDER, 1260 kCompositionTarget = GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER, 1261 kHardwareDecoder = GRALLOC_USAGE_HW_VIDEO_ENCODER, 1262 kProtectedWrite = GRALLOC_USAGE_PROTECTED, 1263 }; 1264 1265 uint64_t mConsumer; // e.g. input 1266 uint64_t mProducer; // e.g. output 1267}; 1268 1269/** 1270 * \ingroup linear allocator 1271 * 1D allocation interface. 1272 */ 1273class C2LinearAllocation : public _C2LinearCapacityAspect { 1274public: 1275 /** 1276 * Maps a portion of an allocation starting from |offset| with |size| into local process memory. 1277 * Stores the starting address into |addr|, or NULL if the operation was unsuccessful. 1278 * |fenceFd| is a file descriptor referring to an acquire sync fence object. If it is already 1279 * safe to access the buffer contents, then -1. 1280 * 1281 * \param offset starting position of the portion to be mapped (this does not have to 1282 * be page aligned) 1283 * \param size size of the portion to be mapped (this does not have to be page 1284 * aligned) 1285 * \param usage the desired usage. \todo this must be kSoftwareRead and/or 1286 * kSoftwareWrite. 1287 * \param fenceFd a pointer to a file descriptor if an async mapping is requested. If 1288 * not-null, and acquire fence FD will be stored here on success, or -1 1289 * on failure. If null, the mapping will be synchronous. 1290 * \param addr a pointer to where the starting address of the mapped portion will be 1291 * stored. On failure, nullptr will be stored here. 1292 * 1293 * \todo Only one portion can be mapped at the same time - this is true for gralloc, but there 1294 * is no need for this for 1D buffers. 1295 * \todo Do we need to support sync operation as we could just wait for the fence? 1296 * 1297 * \retval C2_OK the operation was successful 1298 * \retval C2_NO_PERMISSION no permission to map the portion 1299 * \retval C2_TIMED_OUT the operation timed out 1300 * \retval C2_NO_MEMORY not enough memory to complete the operation 1301 * \retval C2_BAD_VALUE the parameters (offset/size) are invalid or outside the allocation, or 1302 * the usage flags are invalid (caller error) 1303 * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected) 1304 */ 1305 virtual C2Error map( 1306 size_t offset, size_t size, C2MemoryUsage usage, int *fenceFd /* nullable */, 1307 void **addr /* nonnull */) = 0; 1308 1309 /** 1310 * Unmaps a portion of an allocation at |addr| with |size|. These must be parameters previously 1311 * passed to |map|; otherwise, this operation is a no-op. 1312 * 1313 * \param addr starting address of the mapped region 1314 * \param size size of the mapped region 1315 * \param fenceFd a pointer to a file descriptor if an async unmapping is requested. If 1316 * not-null, a release fence FD will be stored here on success, or -1 1317 * on failure. This fence signals when the original allocation contains 1318 * any changes that happened to the mapped region. If null, the unmapping 1319 * will be synchronous. 1320 * 1321 * \retval C2_OK the operation was successful 1322 * \retval C2_TIMED_OUT the operation timed out 1323 * \retval C2_BAD_VALUE the parameters (addr/size) do not correspond to previously mapped 1324 * regions (caller error) 1325 * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected) 1326 * \retval C2_NO_PERMISSION no permission to unmap the portion (unexpected - system) 1327 */ 1328 virtual C2Error unmap(void *addr, size_t size, int *fenceFd /* nullable */) = 0; 1329 1330 /** 1331 * Returns true if this is a valid allocation. 1332 * 1333 * \todo remove? 1334 */ 1335 virtual bool isValid() const = 0; 1336 1337 /** 1338 * Returns a pointer to the allocation handle. 1339 */ 1340 virtual const C2Handle *handle() const = 0; 1341 1342 /** 1343 * Returns true if this is the same allocation as |other|. 1344 */ 1345 virtual bool equals(const std::shared_ptr<C2LinearAllocation> &other) const = 0; 1346 1347protected: 1348 // \todo should we limit allocation directly? 1349 C2LinearAllocation(size_t capacity) : _C2LinearCapacityAspect(c2_min(capacity, UINT32_MAX)) {} 1350 virtual ~C2LinearAllocation() = default; 1351}; 1352 1353/** 1354 * \ingroup graphic allocator 1355 * 2D allocation interface. 1356 */ 1357class C2GraphicAllocation : public _C2PlanarCapacityAspect { 1358public: 1359 /** 1360 * Maps a rectangular section (as defined by |rect|) of a 2D allocation into local process 1361 * memory for flexible access. On success, it fills out |layout| with the plane specifications 1362 * and fills the |addr| array with pointers to the first byte of the top-left pixel of each 1363 * plane used. Otherwise, it leaves |layout| and |addr| untouched. |fenceFd| is a file 1364 * descriptor referring to an acquire sync fence object. If it is already safe to access the 1365 * buffer contents, then -1. 1366 * 1367 * \note Only one portion of the graphic allocation can be mapped at the same time. (This is 1368 * from gralloc1 limitation.) 1369 * 1370 * \param rect section to be mapped (this does not have to be aligned) 1371 * \param usage the desired usage. \todo this must be kSoftwareRead and/or 1372 * kSoftwareWrite. 1373 * \param fenceFd a pointer to a file descriptor if an async mapping is requested. If 1374 * not-null, and acquire fence FD will be stored here on success, or -1 1375 * on failure. If null, the mapping will be synchronous. 1376 * \param layout a pointer to where the mapped planes' descriptors will be 1377 * stored. On failure, nullptr will be stored here. 1378 * 1379 * \todo Do we need to support sync operation as we could just wait for the fence? 1380 * 1381 * \retval C2_OK the operation was successful 1382 * \retval C2_NO_PERMISSION no permission to map the section 1383 * \retval C2_ALREADY_EXISTS there is already a mapped region (caller error) 1384 * \retval C2_TIMED_OUT the operation timed out 1385 * \retval C2_NO_MEMORY not enough memory to complete the operation 1386 * \retval C2_BAD_VALUE the parameters (rect) are invalid or outside the allocation, or the 1387 * usage flags are invalid (caller error) 1388 * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected) 1389 1390 */ 1391 virtual C2Error map( 1392 C2Rect rect, C2MemoryUsage usage, int *fenceFd, 1393 // TODO: return <addr, size> buffers with plane sizes 1394 C2PlaneLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) = 0; 1395 1396 /** 1397 * Unmaps the last mapped rectangular section. 1398 * 1399 * \param fenceFd a pointer to a file descriptor if an async unmapping is requested. If 1400 * not-null, a release fence FD will be stored here on success, or -1 1401 * on failure. This fence signals when the original allocation contains 1402 * any changes that happened to the mapped section. If null, the unmapping 1403 * will be synchronous. 1404 * 1405 * \retval C2_OK the operation was successful 1406 * \retval C2_TIMED_OUT the operation timed out 1407 * \retval C2_NOT_FOUND there is no mapped region (caller error) 1408 * \retval C2_CORRUPTED some unknown error prevented the operation from completing (unexpected) 1409 * \retval C2_NO_PERMISSION no permission to unmap the section (unexpected - system) 1410 */ 1411 virtual C2Error unmap(C2Fence *fenceFd /* nullable */) = 0; 1412 1413 /** 1414 * Returns true if this is a valid allocation. 1415 * 1416 * \todo remove? 1417 */ 1418 virtual bool isValid() const = 0; 1419 1420 /** 1421 * Returns a pointer to the allocation handle. 1422 */ 1423 virtual const C2Handle *handle() const = 0; 1424 1425 /** 1426 * Returns true if this is the same allocation as |other|. 1427 */ 1428 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) = 0; 1429 1430protected: 1431 virtual ~C2GraphicAllocation(); 1432}; 1433 1434/** 1435 * Allocators are used by the framework to allocate memory (allocations) for buffers. They can 1436 * support either 1D or 2D allocations. 1437 * 1438 * \note In theory they could support both, but in practice, we will use only one or the other. 1439 * 1440 * Never constructed on stack. 1441 * 1442 * Allocators are provided by vendors. 1443 */ 1444class C2Allocator { 1445public: 1446 /** 1447 * Allocates a 1D allocation of given |capacity| and |usage|. If successful, the allocation is 1448 * stored in |allocation|. Otherwise, |allocation| is set to 'nullptr'. 1449 * 1450 * \param capacity the size of requested allocation (the allocation could be slightly 1451 * larger, e.g. to account for any system-required alignment) 1452 * \param usage the memory usage info for the requested allocation. \note that the 1453 * returned allocation may be later used/mapped with different usage. 1454 * The allocator should layout the buffer to be optimized for this usage, 1455 * but must support any usage. One exception: protected buffers can 1456 * only be used in a protected scenario. 1457 * \param allocation pointer to where the allocation shall be stored on success. nullptr 1458 * will be stored here on failure 1459 * 1460 * \retval C2_OK the allocation was successful 1461 * \retval C2_NO_MEMORY not enough memory to complete the allocation 1462 * \retval C2_TIMED_OUT the allocation timed out 1463 * \retval C2_NO_PERMISSION no permission to complete the allocation 1464 * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error) 1465 * \retval C2_UNSUPPORTED this allocator does not support 1D allocations 1466 * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected) 1467 */ 1468 virtual C2Error allocateLinearBuffer( 1469 uint32_t capacity __unused, C2MemoryUsage usage __unused, 1470 std::shared_ptr<C2LinearAllocation> *allocation /* nonnull */) { 1471 *allocation = nullptr; 1472 return C2_UNSUPPORTED; 1473 } 1474 1475 /** 1476 * (Re)creates a 1D allocation from a native |handle|. If successful, the allocation is stored 1477 * in |allocation|. Otherwise, |allocation| is set to 'nullptr'. 1478 * 1479 * \param handle the handle for the existing allocation 1480 * \param allocation pointer to where the allocation shall be stored on success. nullptr 1481 * will be stored here on failure 1482 * 1483 * \retval C2_OK the allocation was recreated successfully 1484 * \retval C2_NO_MEMORY not enough memory to recreate the allocation 1485 * \retval C2_TIMED_OUT the recreation timed out (unexpected) 1486 * \retval C2_NO_PERMISSION no permission to recreate the allocation 1487 * \retval C2_BAD_VALUE invalid handle (caller error) 1488 * \retval C2_UNSUPPORTED this allocator does not support 1D allocations 1489 * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected) 1490 */ 1491 virtual C2Error recreateLinearBuffer( 1492 const C2Handle *handle __unused, 1493 std::shared_ptr<C2LinearAllocation> *allocation /* nonnull */) { 1494 *allocation = nullptr; 1495 return C2_UNSUPPORTED; 1496 } 1497 1498 /** 1499 * Allocates a 2D allocation of given |width|, |height|, |format| and |usage|. If successful, 1500 * the allocation is stored in |allocation|. Otherwise, |allocation| is set to 'nullptr'. 1501 * 1502 * \param width the width of requested allocation (the allocation could be slightly 1503 * larger, e.g. to account for any system-required alignment) 1504 * \param height the height of requested allocation (the allocation could be slightly 1505 * larger, e.g. to account for any system-required alignment) 1506 * \param format the pixel format of requested allocation. This could be a vendor 1507 * specific format. 1508 * \param usage the memory usage info for the requested allocation. \note that the 1509 * returned allocation may be later used/mapped with different usage. 1510 * The allocator should layout the buffer to be optimized for this usage, 1511 * but must support any usage. One exception: protected buffers can 1512 * only be used in a protected scenario. 1513 * \param allocation pointer to where the allocation shall be stored on success. nullptr 1514 * will be stored here on failure 1515 * 1516 * \retval C2_OK the allocation was successful 1517 * \retval C2_NO_MEMORY not enough memory to complete the allocation 1518 * \retval C2_TIMED_OUT the allocation timed out 1519 * \retval C2_NO_PERMISSION no permission to complete the allocation 1520 * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller error) 1521 * \retval C2_UNSUPPORTED this allocator does not support 2D allocations 1522 * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected) 1523 */ 1524 virtual C2Error allocateGraphicBuffer( 1525 uint32_t width __unused, uint32_t height __unused, uint32_t format __unused, 1526 C2MemoryUsage usage __unused, 1527 std::shared_ptr<C2GraphicAllocation> *allocation /* nonnull */) { 1528 *allocation = nullptr; 1529 return C2_UNSUPPORTED; 1530 } 1531 1532 /** 1533 * (Re)creates a 2D allocation from a native handle. If successful, the allocation is stored 1534 * in |allocation|. Otherwise, |allocation| is set to 'nullptr'. 1535 * 1536 * \param handle the handle for the existing allocation 1537 * \param allocation pointer to where the allocation shall be stored on success. nullptr 1538 * will be stored here on failure 1539 * 1540 * \retval C2_OK the allocation was recreated successfully 1541 * \retval C2_NO_MEMORY not enough memory to recreate the allocation 1542 * \retval C2_TIMED_OUT the recreation timed out (unexpected) 1543 * \retval C2_NO_PERMISSION no permission to recreate the allocation 1544 * \retval C2_BAD_VALUE invalid handle (caller error) 1545 * \retval C2_UNSUPPORTED this allocator does not support 2D allocations 1546 * \retval C2_CORRUPTED some unknown, unrecoverable error occured during recreation (unexpected) 1547 */ 1548 virtual C2Error recreateGraphicBuffer( 1549 const C2Handle *handle __unused, 1550 std::shared_ptr<C2GraphicAllocation> *allocation /* nonnull */) { 1551 *allocation = nullptr; 1552 return C2_UNSUPPORTED; 1553 } 1554 1555protected: 1556 C2Allocator() = default; 1557 1558 virtual ~C2Allocator() = default; 1559}; 1560 1561/** 1562 * Block allocators are used by components to allocate memory for output buffers. They can 1563 * support either linear (1D), circular (1D) or graphic (2D) allocations. 1564 * 1565 * Never constructed on stack. 1566 * 1567 * Block allocators are provided by the framework. 1568 */ 1569class C2BlockAllocator { 1570public: 1571 /** 1572 * Allocates a linear writeable block of given |capacity| and |usage|. If successful, the 1573 * block is stored in |block|. Otherwise, |block| is set to 'nullptr'. 1574 * 1575 * \param capacity the size of requested block. 1576 * \param usage the memory usage info for the requested allocation. \note that the 1577 * returned allocation may be later used/mapped with different usage. 1578 * The allocator shall lay out the buffer to be optimized for this usage, 1579 * but must support any usage. One exception: protected buffers can 1580 * only be used in a protected scenario. 1581 * \param block pointer to where the allocated block shall be stored on success. nullptr 1582 * will be stored here on failure 1583 * 1584 * \retval C2_OK the allocation was successful 1585 * \retval C2_NO_MEMORY not enough memory to complete the allocation 1586 * \retval C2_TIMED_OUT the allocation timed out 1587 * \retval C2_NO_PERMISSION no permission to complete the allocation 1588 * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error) 1589 * \retval C2_UNSUPPORTED this allocator does not support linear allocations 1590 * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected) 1591 */ 1592 virtual C2Error allocateLinearBlock( 1593 uint32_t capacity __unused, C2MemoryUsage usage __unused, 1594 std::shared_ptr<C2LinearBlock> *block /* nonnull */) { 1595 *block = nullptr; 1596 return C2_UNSUPPORTED; 1597 } 1598 1599 /** 1600 * Allocates a circular writeable block of given |capacity| and |usage|. If successful, the 1601 * block is stored in |block|. Otherwise, |block| is set to 'nullptr'. 1602 * 1603 * \param capacity the size of requested circular block. (the allocation could be slightly 1604 * larger, e.g. to account for any system-required alignment) 1605 * \param usage the memory usage info for the requested allocation. \note that the 1606 * returned allocation may be later used/mapped with different usage. 1607 * The allocator shall lay out the buffer to be optimized for this usage, 1608 * but must support any usage. One exception: protected buffers can 1609 * only be used in a protected scenario. 1610 * \param block pointer to where the allocated block shall be stored on success. nullptr 1611 * will be stored here on failure 1612 * 1613 * \retval C2_OK the allocation was successful 1614 * \retval C2_NO_MEMORY not enough memory to complete the allocation 1615 * \retval C2_TIMED_OUT the allocation timed out 1616 * \retval C2_NO_PERMISSION no permission to complete the allocation 1617 * \retval C2_BAD_VALUE capacity or usage are not supported (invalid) (caller error) 1618 * \retval C2_UNSUPPORTED this allocator does not support circular allocations 1619 * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected) 1620 */ 1621 virtual C2Error allocateCircularBlock( 1622 uint32_t capacity __unused, C2MemoryUsage usage __unused, 1623 std::shared_ptr<C2CircularBlock> *block /* nonnull */) { 1624 *block = nullptr; 1625 return C2_UNSUPPORTED; 1626 } 1627 1628 /** 1629 * Allocates a 2D graphic block of given |width|, |height|, |format| and |usage|. If successful, 1630 * the allocation is stored in |block|. Otherwise, |block| is set to 'nullptr'. 1631 * 1632 * \param width the width of requested allocation (the allocation could be slightly 1633 * larger, e.g. to account for any system-required alignment) 1634 * \param height the height of requested allocation (the allocation could be slightly 1635 * larger, e.g. to account for any system-required alignment) 1636 * \param format the pixel format of requested allocation. This could be a vendor 1637 * specific format. 1638 * \param usage the memory usage info for the requested allocation. \note that the 1639 * returned allocation may be later used/mapped with different usage. 1640 * The allocator should layout the buffer to be optimized for this usage, 1641 * but must support any usage. One exception: protected buffers can 1642 * only be used in a protected scenario. 1643 * \param block pointer to where the allocation shall be stored on success. nullptr 1644 * will be stored here on failure 1645 * 1646 * \retval C2_OK the allocation was successful 1647 * \retval C2_NO_MEMORY not enough memory to complete the allocation 1648 * \retval C2_TIMED_OUT the allocation timed out 1649 * \retval C2_NO_PERMISSION no permission to complete the allocation 1650 * \retval C2_BAD_VALUE width, height, format or usage are not supported (invalid) (caller error) 1651 * \retval C2_UNSUPPORTED this allocator does not support 2D allocations 1652 * \retval C2_CORRUPTED some unknown, unrecoverable error occured during allocation (unexpected) 1653 */ 1654 virtual C2Error allocateGraphicBlock( 1655 uint32_t width __unused, uint32_t height __unused, uint32_t format __unused, 1656 C2MemoryUsage usage __unused, 1657 std::shared_ptr<C2GraphicBlock> *block /* nonnull */) { 1658 *block = nullptr; 1659 return C2_UNSUPPORTED; 1660 } 1661 1662protected: 1663 C2BlockAllocator() = default; 1664 1665 virtual ~C2BlockAllocator() = default; 1666}; 1667 1668/// @} 1669 1670/// \cond INTERNAL 1671 1672/// \todo These are no longer used 1673 1674/// \addtogroup linear 1675/// @{ 1676 1677/** \deprecated */ 1678class C2LinearBuffer 1679 : public C2Buffer, public _C2LinearRangeAspect, 1680 public std::enable_shared_from_this<C2LinearBuffer> { 1681public: 1682 /** \todo what is this? */ 1683 const C2Handle *handle() const; 1684 1685protected: 1686 inline C2LinearBuffer(const C2ConstLinearBlock &block); 1687 1688private: 1689 class Impl; 1690 Impl *mImpl; 1691}; 1692 1693class C2ReadCursor; 1694 1695class C2WriteCursor { 1696public: 1697 uint32_t remaining() const; // remaining data to be read 1698 void commit(); // commits the current position. discard data before current position 1699 void reset() const; // resets position to the last committed position 1700 // slices off at most |size| bytes, and moves cursor ahead by the number of bytes 1701 // sliced off. 1702 C2ReadCursor slice(uint32_t size) const; 1703 // slices off at most |size| bytes, and moves cursor ahead by the number of bytes 1704 // sliced off. 1705 C2WriteCursor reserve(uint32_t size); 1706 // bool read(T&); 1707 // bool write(T&); 1708 C2Fence waitForSpace(uint32_t size); 1709}; 1710 1711/// @} 1712 1713/// \addtogroup graphic 1714/// @{ 1715 1716struct C2ColorSpace { 1717//public: 1718 enum Standard { 1719 BT601, 1720 BT709, 1721 BT2020, 1722 // TODO 1723 }; 1724 1725 enum Range { 1726 LIMITED, 1727 FULL, 1728 // TODO 1729 }; 1730 1731 enum TransferFunction { 1732 BT709Transfer, 1733 BT2020Transfer, 1734 HybridLogGamma2, 1735 HybridLogGamma4, 1736 // TODO 1737 }; 1738}; 1739 1740/** \deprecated */ 1741class C2GraphicBuffer : public C2Buffer { 1742public: 1743 // constant attributes 1744 inline uint32_t width() const { return mWidth; } 1745 inline uint32_t height() const { return mHeight; } 1746 inline uint32_t format() const { return mFormat; } 1747 inline const C2MemoryUsage usage() const { return mUsage; } 1748 1749 // modifiable attributes 1750 1751 1752 virtual const C2ColorSpace colorSpace() const = 0; 1753 // best effort 1754 virtual void setColorSpace_be(const C2ColorSpace &colorSpace) = 0; 1755 virtual bool setColorSpace(const C2ColorSpace &colorSpace) = 0; 1756 1757 const C2Handle *handle() const; 1758 1759protected: 1760 uint32_t mWidth; 1761 uint32_t mHeight; 1762 uint32_t mFormat; 1763 C2MemoryUsage mUsage; 1764 1765 class Impl; 1766 Impl *mImpl; 1767}; 1768 1769/// @} 1770 1771/// \endcond 1772 1773/// @} 1774 1775} // namespace android 1776 1777#endif // C2BUFFER_H_ 1778