| /* |
| * gl_buffer.cpp - GL buffer |
| * |
| * Copyright (c) 2018 Intel Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * Author: Wind Yuan <[email protected]> |
| */ |
| |
| #include "gl_buffer.h" |
| |
| namespace XCam { |
| |
| GLBufferDesc::GLBufferDesc () |
| : format (V4L2_PIX_FMT_NV12) |
| , width (0) |
| , height (0) |
| , aligned_width (0) |
| , aligned_height (0) |
| , size (0) |
| { |
| xcam_mem_clear (strides); |
| xcam_mem_clear (slice_size); |
| xcam_mem_clear (offsets); |
| } |
| |
| GLBuffer::MapRange::MapRange () |
| : offset (0) |
| , len (0) |
| , flags (0) |
| , ptr (0) |
| { |
| } |
| |
| void |
| GLBuffer::MapRange::clear () |
| { |
| offset = 0; |
| len = 0; |
| flags = 0; |
| ptr = NULL; |
| } |
| |
| bool |
| GLBuffer::MapRange::is_mapped () const |
| { |
| return ptr; |
| } |
| |
| GLBuffer::GLBuffer (GLuint id, GLenum target, GLenum usage, uint32_t size) |
| : _target (target) |
| , _usage (usage) |
| , _buf_id (id) |
| , _size (size) |
| { |
| } |
| |
| XCamReturn |
| GLBuffer::bind () |
| { |
| glBindBuffer (_target, _buf_id); |
| GLenum error = gl_error (); |
| XCAM_FAIL_RETURN ( |
| ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES, |
| "GL bind buffer:%d failed, error flag: %s", _buf_id, gl_error_string (error)); |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| GLBuffer::~GLBuffer () |
| { |
| if (_buf_id) { |
| glDeleteBuffers (1, &_buf_id); |
| |
| GLenum error = gl_error (); |
| if (error != GL_NO_ERROR) { |
| XCAM_LOG_WARNING ( |
| "GL Buffer delete buffer failed, error flag: %s", gl_error_string (error)); |
| } |
| } |
| } |
| |
| SmartPtr<GLBuffer> |
| GLBuffer::create_buffer ( |
| GLenum target, |
| const GLvoid *data, uint32_t size, |
| GLenum usage) |
| { |
| XCAM_ASSERT (size > 0); |
| |
| GLuint buf_id = 0; |
| glGenBuffers (1, &buf_id); |
| GLenum error = gl_error (); |
| XCAM_FAIL_RETURN ( |
| ERROR, buf_id && (error == GL_NO_ERROR), NULL, |
| "GL buffer creation failed, error flag: %s", gl_error_string (error)); |
| |
| glBindBuffer (target, buf_id); |
| XCAM_FAIL_RETURN ( |
| ERROR, (error = gl_error ()) == GL_NO_ERROR, NULL, |
| "GL buffer creation failed when bind buffer:%d, error flag: %s", |
| buf_id, gl_error_string (error)); |
| |
| glBufferData (target, size, data, usage); |
| XCAM_FAIL_RETURN ( |
| ERROR, (error = gl_error ()) == GL_NO_ERROR, NULL, |
| "GL buffer creation failed in glBufferData, id:%d, error flag: %s", |
| buf_id, gl_error_string (error)); |
| |
| SmartPtr<GLBuffer> buf_obj = |
| new GLBuffer (buf_id, target, usage, size); |
| |
| return buf_obj; |
| } |
| |
| void * |
| GLBuffer::map_range (uint32_t offset, uint32_t length, GLbitfield flags) |
| { |
| if (length == 0) |
| length = _size; |
| |
| if (_mapped_range.is_mapped () && |
| _mapped_range.flags == flags && |
| _mapped_range.offset == offset && |
| _mapped_range.len == length) { |
| return _mapped_range.ptr; |
| } |
| _mapped_range.clear (); |
| |
| XCamReturn ret = bind (); |
| XCAM_FAIL_RETURN ( |
| ERROR, xcam_ret_is_ok (ret), NULL, |
| "GL bind buffer failed, buf_id:%d", _buf_id); |
| |
| void *ptr = glMapBufferRange (_target, offset, length, flags); |
| GLenum error = gl_error (); |
| XCAM_FAIL_RETURN ( |
| ERROR, ptr && (error == GL_NO_ERROR), NULL, |
| "GL buffer map range failed, buf_id:%d, offset:%d, len:%d, flags:%d, error flag: %s", |
| _buf_id, offset, length, flags, gl_error_string (error)); |
| |
| _mapped_range.offset = offset; |
| _mapped_range.len = length; |
| _mapped_range.flags = flags; |
| _mapped_range.ptr = ptr; |
| |
| return ptr; |
| } |
| |
| XCamReturn |
| GLBuffer::flush_map () |
| { |
| if (!_mapped_range.is_mapped ()) |
| return XCAM_RETURN_ERROR_ORDER; |
| |
| XCAM_FAIL_RETURN ( |
| ERROR, _mapped_range.flags & GL_MAP_FLUSH_EXPLICIT_BIT, |
| XCAM_RETURN_ERROR_GLES, |
| "GL buffer flush_map buf:%d failed, invalid flags(:%d)", |
| _buf_id, _mapped_range.flags); |
| |
| XCamReturn ret = bind (); |
| XCAM_FAIL_RETURN ( |
| ERROR, xcam_ret_is_ok (ret), ret, |
| "GL bind buffer failed, buf_id:%d", _buf_id); |
| |
| glFlushMappedBufferRange (_target, _mapped_range.offset, _mapped_range.len); |
| GLenum error = gl_error (); |
| XCAM_FAIL_RETURN ( |
| ERROR, error == GL_NO_ERROR, |
| XCAM_RETURN_ERROR_GLES, |
| "GL buffer flush_map buf:%d failed, error flag: %s", |
| _buf_id, gl_error_string (error)); |
| |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| XCamReturn |
| GLBuffer::unmap () |
| { |
| if (!_mapped_range.is_mapped ()) |
| return XCAM_RETURN_ERROR_ORDER; |
| |
| XCamReturn ret = bind (); |
| XCAM_FAIL_RETURN ( |
| ERROR, xcam_ret_is_ok (ret), ret, |
| "GL bind buffer failed, buf_id:%d", _buf_id); |
| |
| XCAM_FAIL_RETURN ( |
| ERROR, glUnmapBuffer (_target), XCAM_RETURN_ERROR_GLES, |
| "GL buffer unmap buf:%d failed, error flag: %s", |
| _buf_id, gl_error_string (gl_error ())); |
| |
| _mapped_range.clear (); |
| |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| XCamReturn |
| GLBuffer::bind_buffer_base (uint32_t index) |
| { |
| XCamReturn ret = bind (); |
| XCAM_FAIL_RETURN ( |
| ERROR, xcam_ret_is_ok (ret), ret, |
| "GL bind buffer failed, buf_id:%d", _buf_id); |
| |
| glBindBufferBase (_target, index, _buf_id); |
| GLenum error = gl_error (); |
| XCAM_FAIL_RETURN ( |
| ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES, |
| "GL bind buffer base failed. buf_id:%d failed, idx:%d, error flag: %s", |
| _buf_id, index, gl_error_string (error)); |
| |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| XCamReturn |
| GLBuffer::bind_buffer_range (uint32_t index, uint32_t offset, uint32_t size) |
| { |
| XCamReturn ret = bind (); |
| XCAM_FAIL_RETURN ( |
| ERROR, xcam_ret_is_ok (ret), ret, |
| "GL bind buffer failed, buf_id:%d", _buf_id); |
| |
| glBindBufferRange (_target, index, _buf_id, offset, size); |
| GLenum error = gl_error (); |
| XCAM_FAIL_RETURN ( |
| ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES, |
| "GL bind buffer range failed. buf_id:%d failed, idx:%d, error flag: %s", |
| _buf_id, index, gl_error_string (error)); |
| |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| } |
| |