SHARE
TWEET
Texture.hpp
a guest
Jan 29th, 2020
97
in 198 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
- /*
- * A VCOS shared memory render target with one RGBA buffer (read-write)
- * VCOS only support POT textures, so only a part will be used
- */
- class VCSMRenderTarget : public RenderTarget
- {
- public:
- int bufferWidth, bufferHeight;
- VCSMRenderTarget (int Width, int Height, EGLDisplay Display);
- ~VCSMRenderTarget (void);
- void setTarget (void) override;
- void setSource (ShaderProgram *shader, int slot) override;
- uint8_t* lock(void);
- void unlock(void);
- private:
- GLuint TEX_ID;
- struct egl_image_brcm_vcsm_info VCSM;
- EGLImageKHR eglImg;
- uint8_t *vcsmBuffer;
- EGLDisplay eglDisplay;
- };
- static int nextPOT (int NPOT)
- {
- NPOT--;
- NPOT |= NPOT >> 1;
- NPOT |= NPOT >> 2;
- NPOT |= NPOT >> 4;
- NPOT |= NPOT >> 8;
- NPOT++;
- return std::max(64, NPOT);
- }
- VCSMRenderTarget::VCSMRenderTarget (int Width, int Height, EGLDisplay Display)
- {
- width = Width;
- height = Height;
- bufferWidth = nextPOT(width);
- bufferHeight = nextPOT(height);
- std::cout << "Texture Size " << width << "x" << height << std::endl;
- std::cout << "Buffer Size " << bufferWidth << "x" << bufferHeight << std::endl;
- eglDisplay = Display;
- // Framebuffer
- glGenFramebuffers(1, &FBO_ID);
- glBindFramebuffer(GL_FRAMEBUFFER, FBO_ID);
- // Create texture handle
- glGenTextures(1, &TEX_ID);
- glBindTexture(GL_TEXTURE_2D, TEX_ID);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR / GL_NEAREST
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR / GL_NEAREST
- // Allocate VCOS Shared Memory and assign to texture
- VCSM.width = bufferWidth;
- VCSM.height = bufferHeight;
- eglImg = eglCreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_IMAGE_BRCM_VCSM, &VCSM, NULL);
- CHECK_GL();
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, eglImg);
- CHECK_GL();
- // Bind texture to framebuffer
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, TEX_ID, 0);
- if (eglImg == EGL_NO_IMAGE_KHR || VCSM.vcsm_handle == 0)
- {
- std::cout << VCOS_FUNCTION << ": Failed to create EGL VCSM image\n";
- return;
- }
- CHECK_GL();
- // Check
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- {
- std::cout << "Error: Framebuffer not complete: " << glCheckFramebufferStatus(GL_FRAMEBUFFER) << "\n";
- }
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
- }
- VCSMRenderTarget::~VCSMRenderTarget (void)
- {
- glDeleteTextures(1, &TEX_ID);
- glDeleteFramebuffers(1, &FBO_ID);
- eglDestroyImageKHR(eglDisplay, eglImg);
- }
- void VCSMRenderTarget::setTarget (void)
- {
- glViewport(0, 0, width, height); // Important: only the actual texture, not full buffer
- glBindFramebuffer(GL_FRAMEBUFFER, FBO_ID);
- }
- void VCSMRenderTarget::setSource (ShaderProgram *shader, int slot)
- {
- glUniform1i(shader->uWidthAdr, bufferWidth);
- glUniform1i(shader->uHeightAdr, bufferHeight);
- glUniform1i(shader->uImageAdr, slot);
- glActiveTexture(GL_TEXTURE0 + slot);
- glBindTexture(GL_TEXTURE_2D, TEX_ID);
- }
- uint8_t* VCSMRenderTarget::lock (void)
- {
- VCSM_CACHE_TYPE_T cacheType;
- vcsmBuffer = (uint8_t*)vcsm_lock_cache(VCSM.vcsm_handle, VCSM_CACHE_TYPE_HOST, &cacheType);
- if (!vcsmBuffer) std::cout << "Failed to lock VCSM buffer!\n";
- return vcsmBuffer;
- }
- void VCSMRenderTarget::unlock (void)
- {
- vcsm_unlock_ptr(vcsmBuffer);
- }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy.
