15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/compiler_specific.h"
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/client/ring_buffer.h"
1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/common/buffer.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h"
1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "gpu/gpu_export.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CommandBufferHelper;
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wraps RingBufferWrapper to provide aligned allocations.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AlignedRingBuffer : public RingBufferWrapper {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AlignedRingBuffer(
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int alignment,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int32 shm_id,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      RingBuffer::Offset base_offset,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int size,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CommandBufferHelper* helper,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      void* base)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : RingBufferWrapper(base_offset, size, helper, base),
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        alignment_(alignment),
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shm_id_(shm_id) {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~AlignedRingBuffer();
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hiding Alloc from RingBufferWrapper
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* Alloc(unsigned int size) {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RingBufferWrapper::Alloc(RoundToAlignment(size));
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 GetShmId() const {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return shm_id_;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int RoundToAlignment(unsigned int size) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (size + alignment_ - 1) & ~(alignment_ - 1);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int alignment_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 shm_id_;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Interface for managing the transfer buffer.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GPU_EXPORT TransferBufferInterface {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransferBufferInterface() { }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TransferBufferInterface() { }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Initialize(
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int buffer_size,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int result_size,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int min_buffer_size,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int max_buffer_size,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int alignment,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int size_to_flush) = 0;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetShmId() = 0;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* GetResultBuffer() = 0;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetResultOffset() = 0;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Free() = 0;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HaveBuffer() const = 0;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocates up to size bytes.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* AllocUpTo(unsigned int size, unsigned int* size_allocated) = 0;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allocates size bytes.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: Alloc will fail if it can not return size bytes.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* Alloc(unsigned int size) = 0;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual RingBuffer::Offset GetOffset(void* pointer) const = 0;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void FreePendingToken(void* p, unsigned int token) = 0;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Class that manages the transfer buffer.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GPU_EXPORT TransferBuffer : public TransferBufferInterface {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransferBuffer(CommandBufferHelper* helper);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TransferBuffer();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from TransferBufferInterface.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool Initialize(
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int default_buffer_size,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int result_size,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int min_buffer_size,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int max_buffer_size,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int alignment,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int size_to_flush) OVERRIDE;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetShmId() OVERRIDE;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* GetResultBuffer() OVERRIDE;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int GetResultOffset() OVERRIDE;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Free() OVERRIDE;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HaveBuffer() const OVERRIDE;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* AllocUpTo(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int size, unsigned int* size_allocated) OVERRIDE;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void* Alloc(unsigned int size) OVERRIDE;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void FreePendingToken(void* p, unsigned int token) OVERRIDE;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These are for testing.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int GetCurrentMaxAllocationWithoutRealloc() const;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int GetMaxAllocation() const;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tries to reallocate the ring buffer if it's not large enough for size.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReallocateRingBuffer(unsigned int size);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AllocateRingBuffer(unsigned int size);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferHelper* helper_;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<AlignedRingBuffer> ring_buffer_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // size reserved for results
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int result_size_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default size. Size we want when starting or re-allocating
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int default_buffer_size_;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // min size we'll consider successful
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int min_buffer_size_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // max size we'll let the buffer grow
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int max_buffer_size_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // alignment for allocations
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int alignment_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Size at which to do an async flush. 0 = never.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int size_to_flush_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Number of bytes since we last flushed.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int bytes_since_last_flush_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the current buffer.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gpu::Buffer buffer_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // id of buffer. -1 = no buffer
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 buffer_id_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // address of result area
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* result_buffer_;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // offset to result area
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 result_shm_offset_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // false if we failed to allocate min_buffer_size
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool usable_;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A class that will manage the lifetime of a transferbuffer allocation.
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GPU_EXPORT ScopedTransferBufferPtr {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedTransferBufferPtr(
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int size,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CommandBufferHelper* helper,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      TransferBufferInterface* transfer_buffer)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : buffer_(NULL),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        size_(0),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        helper_(helper),
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        transfer_buffer_(transfer_buffer) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Reset(size);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ScopedTransferBufferPtr() {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Release();
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool valid() const {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return buffer_ != NULL;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int size() const {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return size_;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int shm_id() const {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return transfer_buffer_->GetShmId();
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RingBuffer::Offset offset() const {
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return transfer_buffer_->GetOffset(buffer_);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* address() const {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return buffer_;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Release();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset(unsigned int new_size);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* buffer_;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int size_;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandBufferHelper* helper_;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransferBufferInterface* transfer_buffer_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedTransferBufferPtr);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T>
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ScopedTransferBufferArray : public ScopedTransferBufferPtr {
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedTransferBufferArray(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned int num_elements,
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CommandBufferHelper* helper, TransferBufferInterface* transfer_buffer)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ScopedTransferBufferPtr(
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          num_elements * sizeof(T), helper, transfer_buffer) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  T* elements() {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<T*>(address());
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unsigned int num_elements() const {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return size() / sizeof(T);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gpu
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GPU_COMMAND_BUFFER_CLIENT_TRANSFER_BUFFER_H_
234