FramebufferImpl *DXGISwapChainWindowSurfaceWGL::createDefaultFramebuffer( const gl::Context *context, const gl::FramebufferState &data) { const FunctionsGL *functions = GetFunctionsGL(context); StateManagerGL *stateManager = GetStateManagerGL(context); GLuint framebufferID = 0; functions->genFramebuffers(1, &framebufferID); stateManager->bindFramebuffer(GL_FRAMEBUFFER, framebufferID); functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbufferID); if (mDepthBufferFormat != GL_NONE) { const gl::InternalFormat &depthStencilFormatInfo = gl::GetSizedInternalFormatInfo(mDepthBufferFormat); if (depthStencilFormatInfo.depthBits > 0) { functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbufferID); } if (depthStencilFormatInfo.stencilBits > 0) { functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbufferID); } } return new FramebufferGL(data, framebufferID, true); }
TextureImpl *ContextGL::createTexture(const gl::TextureState &state) { const FunctionsGL *functions = getFunctions(); StateManagerGL *stateManager = getStateManager(); GLuint texture = 0; functions->genTextures(1, &texture); stateManager->bindTexture(state.getType(), texture); return new TextureGL(state, texture); }
angle::Result ImageEGL::setRenderbufferStorage(const gl::Context *context, RenderbufferGL *renderbuffer, GLenum *outInternalFormat) { const FunctionsGL *functionsGL = GetFunctionsGL(context); StateManagerGL *stateManager = GetStateManagerGL(context); // Make sure this renderbuffer is bound stateManager->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer->getRenderbufferID()); // Bind the image to the renderbuffer functionsGL->eGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage); *outInternalFormat = mNativeInternalFormat; return angle::Result::Continue; }
GLuint DisplayOzone::Buffer::getTexture() { // TODO(fjhenigman) Try not to create a new texture every time. That already works on Intel // and should work on Mali with proper fences. FunctionsGL *gl = mDisplay->mFunctionsGL; StateManagerGL *sm = mDisplay->getRenderer()->getStateManager(); gl->genTextures(1, &mTexture); sm->bindTexture(GL_TEXTURE_2D, mTexture); gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ASSERT(mImage != EGL_NO_IMAGE_KHR); gl->eglImageTargetTexture2DOES(GL_TEXTURE_2D, mImage); return mTexture; }
angle::Result ImageEGL::setTexture2D(const gl::Context *context, gl::TextureType type, TextureGL *texture, GLenum *outInternalFormat) { const FunctionsGL *functionsGL = GetFunctionsGL(context); StateManagerGL *stateManager = GetStateManagerGL(context); // Make sure this texture is bound stateManager->bindTexture(type, texture->getTextureID()); // Bind the image to the texture functionsGL->eGLImageTargetTexture2DOES(ToGLenum(type), mImage); *outInternalFormat = mNativeInternalFormat; return angle::Result::Continue; }
void DisplayOzone::drawBuffer(Buffer *buffer) { if (!mDrawing) { // get buffer on which to draw window if (mUnused) { mDrawing = mUnused; mUnused = nullptr; } else { mDrawing = new Buffer(this, GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT, GBM_FORMAT_ARGB8888, DRM_FORMAT_ARGB8888, DRM_FORMAT_XRGB8888, true, true); // XXX shouldn't need stencil if (!mDrawing || !mDrawing->initialize(mWidth, mHeight)) { return; } } StateManagerGL *sm = getRenderer()->getStateManager(); sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB()); sm->setClearColor(gl::ColorF(0, 0, 0, 1)); sm->setClearDepth(1); sm->setScissorTestEnabled(false); sm->setColorMask(true, true, true, true); sm->setDepthMask(true); mFunctionsGL->clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } drawWithTexture(buffer); presentScreen(); }
void DisplayOzone::drawWithTexture(Buffer *buffer) { FunctionsGL *gl = mFunctionsGL; StateManagerGL *sm = getRenderer()->getStateManager(); if (!mProgram) { const GLchar *vertexSource = "#version 100\n" "attribute vec3 vertex;\n" "uniform vec2 center;\n" "uniform vec2 windowSize;\n" "uniform vec2 borderSize;\n" "uniform float depth;\n" "varying vec3 texCoord;\n" "void main()\n" "{\n" " vec2 pos = vertex.xy * (windowSize + borderSize * vertex.z);\n" " gl_Position = vec4(center + pos, depth, 1);\n" " texCoord = vec3(pos / windowSize * vec2(.5, -.5) + vec2(.5, .5), vertex.z);\n" "}\n"; const GLchar *fragmentSource = "#version 100\n" "precision mediump float;\n" "uniform sampler2D tex;\n" "varying vec3 texCoord;\n" "void main()\n" "{\n" " if (texCoord.z > 0.)\n" " {\n" " float c = abs((texCoord.z * 2.) - 1.);\n" " gl_FragColor = vec4(c, c, c, 1);\n" " }\n" " else\n" " {\n" " gl_FragColor = texture2D(tex, texCoord.xy);\n" " }\n" "}\n"; mVertexShader = makeShader(GL_VERTEX_SHADER, vertexSource); mFragmentShader = makeShader(GL_FRAGMENT_SHADER, fragmentSource); mProgram = gl->createProgram(); gl->attachShader(mProgram, mVertexShader); gl->attachShader(mProgram, mFragmentShader); gl->bindAttribLocation(mProgram, 0, "vertex"); gl->linkProgram(mProgram); GLint linked; gl->getProgramiv(mProgram, GL_LINK_STATUS, &linked); ASSERT(linked); mCenterUniform = gl->getUniformLocation(mProgram, "center"); mWindowSizeUniform = gl->getUniformLocation(mProgram, "windowSize"); mBorderSizeUniform = gl->getUniformLocation(mProgram, "borderSize"); mDepthUniform = gl->getUniformLocation(mProgram, "depth"); GLint texUniform = gl->getUniformLocation(mProgram, "tex"); sm->useProgram(mProgram); gl->uniform1i(texUniform, 0); // clang-format off const GLfloat vertices[] = { // window corners, and window border inside corners 1, -1, 0, -1, -1, 0, 1, 1, 0, -1, 1, 0, // window border outside corners 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, }; // clang-format on gl->genBuffers(1, &mVertexBuffer); sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); gl->bufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // window border triangle strip const GLuint borderStrip[] = {5, 0, 4, 2, 6, 3, 7, 1, 5, 0}; gl->genBuffers(1, &mIndexBuffer); sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); gl->bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(borderStrip), borderStrip, GL_STATIC_DRAW); } else { sm->useProgram(mProgram); sm->bindBuffer(GL_ARRAY_BUFFER, mVertexBuffer); sm->bindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer); } // convert from pixels to "-1 to 1" space const NativeWindow *n = buffer->getNative(); double x = n->x * 2. / mWidth - 1; double y = n->y * 2. / mHeight - 1; double halfw = n->width * 1. / mWidth; double halfh = n->height * 1. / mHeight; double borderw = n->borderWidth * 2. / mWidth; double borderh = n->borderHeight * 2. / mHeight; gl->uniform2f(mCenterUniform, x + halfw, y + halfh); gl->uniform2f(mWindowSizeUniform, halfw, halfh); gl->uniform2f(mBorderSizeUniform, borderw, borderh); gl->uniform1f(mDepthUniform, n->depth / 1e6); sm->setBlendEnabled(false); sm->setCullFaceEnabled(false); sm->setStencilTestEnabled(false); sm->setScissorTestEnabled(false); sm->setDepthTestEnabled(true); sm->setColorMask(true, true, true, true); sm->setDepthMask(true); sm->setDepthRange(0, 1); sm->setDepthFunc(GL_LESS); sm->setViewport(gl::Rectangle(0, 0, mWidth, mHeight)); sm->activeTexture(0); GLuint tex = buffer->getTexture(); sm->bindTexture(GL_TEXTURE_2D, tex); gl->vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); gl->enableVertexAttribArray(0); sm->bindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawing->getGLFB()); gl->drawArrays(GL_TRIANGLE_STRIP, 0, 4); gl->drawElements(GL_TRIANGLE_STRIP, 10, GL_UNSIGNED_INT, 0); sm->deleteTexture(tex); }
bool DisplayOzone::Buffer::resize(int32_t width, int32_t height) { if (mWidth == width && mHeight == height) { return true; } reset(); if (width <= 0 || height <= 0) { return true; } mBO = gbm_bo_create(mDisplay->mGBM, width, height, mGBMFormat, mUseFlags); if (!mBO) { return false; } mDMABuf = gbm_bo_get_fd(mBO); if (mDMABuf < 0) { return false; } // clang-format off const EGLint attr[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_LINUX_DRM_FOURCC_EXT, UnsignedToSigned(mDRMFormat), EGL_DMA_BUF_PLANE0_FD_EXT, mDMABuf, EGL_DMA_BUF_PLANE0_PITCH_EXT, UnsignedToSigned(gbm_bo_get_stride(mBO)), EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_NONE, }; // clang-format on mImage = mDisplay->mEGL->createImageKHR(EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attr); if (mImage == EGL_NO_IMAGE_KHR) { return false; } FunctionsGL *gl = mDisplay->mFunctionsGL; StateManagerGL *sm = mDisplay->getRenderer()->getStateManager(); gl->genRenderbuffers(1, &mColorBuffer); sm->bindRenderbuffer(GL_RENDERBUFFER, mColorBuffer); gl->eglImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, mImage); sm->bindFramebuffer(GL_FRAMEBUFFER, mGLFB); gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER, mColorBuffer); if (mDepthBits || mStencilBits) { gl->genRenderbuffers(1, &mDSBuffer); sm->bindRenderbuffer(GL_RENDERBUFFER, mDSBuffer); gl->renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height); } if (mDepthBits) { gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDSBuffer); } if (mStencilBits) { gl->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDSBuffer); } mWidth = width; mHeight = height; return true; }