Add transfer buffer to GLCaps
Adds a check for PBO/transfer buffer support to GrGLCaps, and uses that to pick the correct buffer type. BUG=skia:4604 Review URL: https://codereview.chromium.org/1503593002
This commit is contained in:
parent
776d49b41b
commit
d7a2c1f5fd
@ -111,7 +111,9 @@ bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInB
|
||||
|
||||
void GrGLBufferImpl::validate() const {
|
||||
SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType ||
|
||||
GR_GL_PIXEL_PACK_BUFFER == fBufferType || GR_GL_PIXEL_UNPACK_BUFFER == fBufferType);
|
||||
GR_GL_PIXEL_PACK_BUFFER == fBufferType || GR_GL_PIXEL_UNPACK_BUFFER == fBufferType ||
|
||||
GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM == fBufferType ||
|
||||
GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == fBufferType);
|
||||
// The following assert isn't valid when the buffer has been abandoned:
|
||||
// SkASSERT((0 == fDesc.fID) == (fCPUData));
|
||||
SkASSERT(nullptr == fCPUData || 0 == fGLSizeInBytes);
|
||||
|
@ -23,6 +23,7 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
|
||||
fInvalidateFBType = kNone_InvalidateFBType;
|
||||
fLATCAlias = kLATC_LATCAlias;
|
||||
fMapBufferType = kNone_MapBufferType;
|
||||
fTransferBufferType = kNone_TransferBufferType;
|
||||
fMaxFragmentUniformVectors = 0;
|
||||
fMaxVertexAttributes = 0;
|
||||
fMaxFragmentTextureUnits = 0;
|
||||
@ -370,6 +371,18 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
|
||||
}
|
||||
}
|
||||
|
||||
if (kGL_GrGLStandard == standard) {
|
||||
if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_ARB_pixel_buffer_object")) {
|
||||
fTransferBufferType = kPBO_TransferBufferType;
|
||||
}
|
||||
} else {
|
||||
if (version >= GR_GL_VER(3, 0) || ctxInfo.hasExtension("GL_NV_pixel_buffer_object")) {
|
||||
fTransferBufferType = kPBO_TransferBufferType;
|
||||
} else if (ctxInfo.hasExtension("GL_CHROMIUM_pixel_transfer_buffer_object")) {
|
||||
fTransferBufferType = kChromium_TransferBufferType;
|
||||
}
|
||||
}
|
||||
|
||||
// On many GPUs, map memory is very expensive, so we effectively disable it here by setting the
|
||||
// threshold to the maximum unless the client gives us a hint that map memory is cheap.
|
||||
if (fGeometryBufferMapThreshold < 0) {
|
||||
|
@ -90,6 +90,14 @@ public:
|
||||
kLast_MapBufferType = kChromium_MapBufferType,
|
||||
};
|
||||
|
||||
enum TransferBufferType {
|
||||
kNone_TransferBufferType,
|
||||
kPBO_TransferBufferType, // ARB_pixel_buffer_object
|
||||
kChromium_TransferBufferType, // CHROMIUM_pixel_transfer_buffer_object
|
||||
|
||||
kLast_TransferBufferType = kChromium_TransferBufferType,
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the GrGLCaps to the set of features supported in the current
|
||||
* OpenGL context accessible via ctxInfo.
|
||||
@ -143,6 +151,9 @@ public:
|
||||
/// What type of buffer mapping is supported?
|
||||
MapBufferType mapBufferType() const { return fMapBufferType; }
|
||||
|
||||
/// What type of transfer buffer is supported?
|
||||
TransferBufferType transferBufferType() const { return fTransferBufferType; }
|
||||
|
||||
/**
|
||||
* Gets an array of legal stencil formats. These formats are not guaranteed
|
||||
* to be supported by the driver but are legal GLenum names given the GL
|
||||
@ -337,6 +348,7 @@ private:
|
||||
MSFBOType fMSFBOType;
|
||||
InvalidateFBType fInvalidateFBType;
|
||||
MapBufferType fMapBufferType;
|
||||
TransferBufferType fTransferBufferType;
|
||||
LATCAlias fLATCAlias;
|
||||
|
||||
bool fRGBA8RenderbufferSupport : 1;
|
||||
|
@ -113,6 +113,9 @@
|
||||
#define GR_GL_PIXEL_PACK_BUFFER 0x88EB
|
||||
#define GR_GL_PIXEL_UNPACK_BUFFER 0x88EC
|
||||
|
||||
#define GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM 0x78EC
|
||||
#define GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM 0x78ED
|
||||
|
||||
#define GR_GL_STREAM_DRAW 0x88E0
|
||||
#define GR_GL_STREAM_READ 0x88E1
|
||||
#define GR_GL_STATIC_DRAW 0x88E4
|
||||
@ -705,7 +708,8 @@
|
||||
#define GR_GL_T2F_C4F_N3F_V3F 0x2A2C
|
||||
#define GR_GL_T4F_C4F_N3F_V4F 0x2A2D
|
||||
|
||||
/* Vertex Buffer Object */
|
||||
/* Buffer Object */
|
||||
#define GR_GL_READ_ONLY 0x88B8
|
||||
#define GR_GL_WRITE_ONLY 0x88B9
|
||||
#define GR_GL_BUFFER_MAPPED 0x88BC
|
||||
|
||||
|
@ -1479,19 +1479,30 @@ GrIndexBuffer* GrGLGpu::onCreateIndexBuffer(size_t size, bool dynamic) {
|
||||
}
|
||||
}
|
||||
|
||||
GrTransferBuffer* GrGLGpu::onCreateTransferBuffer(size_t size, TransferType type) {
|
||||
GrTransferBuffer* GrGLGpu::onCreateTransferBuffer(size_t size, TransferType xferType) {
|
||||
GrGLCaps::TransferBufferType xferBufferType = this->ctxInfo().caps()->transferBufferType();
|
||||
if (GrGLCaps::kNone_TransferBufferType == xferBufferType) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrGLTransferBuffer::Desc desc;
|
||||
bool toGpu = (kCpuToGpu_TransferType == type);
|
||||
bool toGpu = (kCpuToGpu_TransferType == xferType);
|
||||
desc.fUsage = toGpu ? GrGLBufferImpl::kStreamDraw_Usage : GrGLBufferImpl::kStreamRead_Usage;
|
||||
|
||||
desc.fSizeInBytes = size;
|
||||
|
||||
// TODO: check caps to see if we can create a PBO, and which kind
|
||||
GL_CALL(GenBuffers(1, &desc.fID));
|
||||
if (desc.fID) {
|
||||
CLEAR_ERROR_BEFORE_ALLOC(this->glInterface());
|
||||
// make sure driver can allocate memory for this buffer
|
||||
GrGLenum type = toGpu ? GR_GL_PIXEL_UNPACK_BUFFER : GR_GL_PIXEL_PACK_BUFFER;
|
||||
// make sure driver can allocate memory for this bmapuffer
|
||||
GrGLenum type;
|
||||
if (GrGLCaps::kChromium_TransferBufferType == xferBufferType) {
|
||||
type = toGpu ? GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM
|
||||
: GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM;
|
||||
} else {
|
||||
SkASSERT(GrGLCaps::kPBO_TransferBufferType == xferBufferType);
|
||||
type = toGpu ? GR_GL_PIXEL_UNPACK_BUFFER : GR_GL_PIXEL_PACK_BUFFER;
|
||||
}
|
||||
GL_ALLOC_CALL(this->glInterface(),
|
||||
BufferData(type,
|
||||
(GrGLsizeiptr) desc.fSizeInBytes,
|
||||
@ -1650,6 +1661,8 @@ void GrGLGpu::bindBuffer(GrGLuint id, GrGLenum type) {
|
||||
this->bindVertexBuffer(id);
|
||||
} else if (GR_GL_ELEMENT_ARRAY_BUFFER == type) {
|
||||
this->bindIndexBufferAndDefaultVertexArray(id);
|
||||
} else {
|
||||
GR_GL_CALL(this->glInterface(), BindBuffer(type, id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1679,6 +1692,8 @@ void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage
|
||||
size_t currentSize, size_t requestedSize) {
|
||||
void* mapPtr = nullptr;
|
||||
GrGLenum glUsage = get_gl_usage(usage);
|
||||
bool readOnly = (GrGLBufferImpl::kStreamRead_Usage == usage);
|
||||
|
||||
// Handling dirty context is done in the bindBuffer call
|
||||
switch (this->glCaps().mapBufferType()) {
|
||||
case GrGLCaps::kNone_MapBufferType:
|
||||
@ -1689,7 +1704,7 @@ void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage
|
||||
if (GR_GL_USE_BUFFER_DATA_NULL_HINT || currentSize != requestedSize) {
|
||||
GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
|
||||
}
|
||||
GL_CALL_RET(mapPtr, MapBuffer(type, GR_GL_WRITE_ONLY));
|
||||
GL_CALL_RET(mapPtr, MapBuffer(type, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
|
||||
break;
|
||||
case GrGLCaps::kMapBufferRange_MapBufferType: {
|
||||
this->bindBuffer(id, type);
|
||||
@ -1697,9 +1712,11 @@ void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage
|
||||
if (currentSize != requestedSize) {
|
||||
GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
|
||||
}
|
||||
static const GrGLbitfield kAccess = GR_GL_MAP_INVALIDATE_BUFFER_BIT |
|
||||
GR_GL_MAP_WRITE_BIT;
|
||||
GL_CALL_RET(mapPtr, MapBufferRange(type, 0, requestedSize, kAccess));
|
||||
static const GrGLbitfield kWriteAccess = GR_GL_MAP_INVALIDATE_BUFFER_BIT |
|
||||
GR_GL_MAP_WRITE_BIT;
|
||||
GL_CALL_RET(mapPtr, MapBufferRange(type, 0, requestedSize, readOnly ?
|
||||
GR_GL_MAP_READ_BIT :
|
||||
kWriteAccess));
|
||||
break;
|
||||
}
|
||||
case GrGLCaps::kChromium_MapBufferType:
|
||||
@ -1708,7 +1725,9 @@ void* GrGLGpu::mapBuffer(GrGLuint id, GrGLenum type, GrGLBufferImpl::Usage usage
|
||||
if (currentSize != requestedSize) {
|
||||
GL_CALL(BufferData(type, requestedSize, nullptr, glUsage));
|
||||
}
|
||||
GL_CALL_RET(mapPtr, MapBufferSubData(type, 0, requestedSize, GR_GL_WRITE_ONLY));
|
||||
GL_CALL_RET(mapPtr, MapBufferSubData(type, 0, requestedSize, readOnly ?
|
||||
GR_GL_READ_ONLY :
|
||||
GR_GL_WRITE_ONLY));
|
||||
break;
|
||||
}
|
||||
return mapPtr;
|
||||
|
Loading…
Reference in New Issue
Block a user