SurfaceFlinger now uses GLES 2.x when available
Bug: 8679321
Change-Id: I2b152d01fb4e2de2ea9fe87f1ddbd6826d7520d7
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b76cde7..68b9950 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -23,8 +23,6 @@
#include <dlfcn.h>
#include <EGL/egl.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
#include <cutils/log.h>
#include <cutils/properties.h>
@@ -72,6 +70,7 @@
#include "RenderEngine/RenderEngine.h"
+
#define DISPLAY_COUNT 1
/*
@@ -268,19 +267,20 @@
property_set("service.bootanim.exit", "1");
}
-void SurfaceFlinger::deleteTextureAsync(GLuint texture) {
+void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
class MessageDestroyGLTexture : public MessageBase {
- GLuint texture;
+ RenderEngine& engine;
+ uint32_t texture;
public:
- MessageDestroyGLTexture(GLuint texture)
- : texture(texture) {
+ MessageDestroyGLTexture(RenderEngine& engine, uint32_t texture)
+ : engine(engine), texture(texture) {
}
virtual bool handler() {
- glDeleteTextures(1, &texture);
+ engine.deleteTextures(1, &texture);
return true;
}
};
- postMessageAsync(new MessageDestroyGLTexture(texture));
+ postMessageAsync(new MessageDestroyGLTexture(getRenderEngine(), texture));
}
status_t SurfaceFlinger::selectConfigForAttribute(
@@ -750,24 +750,10 @@
doComposeSurfaces(hw, Region(hw->bounds()));
// and draw the dirty region
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glColor4f(1, 0, 1, 1);
const int32_t height = hw->getHeight();
- Region::const_iterator it = dirtyRegion.begin();
- Region::const_iterator const end = dirtyRegion.end();
- while (it != end) {
- const Rect& r = *it++;
- GLfloat vertices[][2] = {
- { (GLfloat) r.left, (GLfloat) (height - r.top) },
- { (GLfloat) r.left, (GLfloat) (height - r.bottom) },
- { (GLfloat) r.right, (GLfloat) (height - r.bottom) },
- { (GLfloat) r.right, (GLfloat) (height - r.top) }
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
+ RenderEngine& engine(getRenderEngine());
+ engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
+
hw->compositionComplete();
hw->swapBuffers(getHwComposer());
}
@@ -1512,6 +1498,7 @@
void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
{
+ RenderEngine& engine(getRenderEngine());
const int32_t id = hw->getHwcDisplayId();
HWComposer& hwc(getHwComposer());
HWComposer::LayerListIterator cur = hwc.begin(id);
@@ -1525,20 +1512,15 @@
return;
}
- // set the frame buffer
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
// Never touch the framebuffer if we don't have any framebuffer layers
const bool hasHwcComposition = hwc.hasHwcComposition(id);
if (hasHwcComposition) {
// when using overlays, we assume a fully transparent framebuffer
// NOTE: we could reduce how much we need to clear, for instance
// remove where there are opaque FB layers. however, on some
- // GPUs doing a "clean slate" glClear might be more efficient.
+ // GPUs doing a "clean slate" clear might be more efficient.
// We'll revisit later if needed.
- glClearColor(0, 0, 0, 0);
- glClear(GL_COLOR_BUFFER_BIT);
+ engine.clearWithColor(0, 0, 0, 0);
} else {
// we start with the whole screen area
const Region bounds(hw->getBounds());
@@ -1571,11 +1553,11 @@
// scissor doesn't match the screen's dimensions, so we
// need to clear everything outside of it and enable
// the GL scissor so we don't draw anything where we shouldn't
- const GLint height = hw->getHeight();
- glScissor(scissor.left, height - scissor.bottom,
- scissor.getWidth(), scissor.getHeight());
+
// enable scissor for this frame
- glEnable(GL_SCISSOR_TEST);
+ const uint32_t height = hw->getHeight();
+ engine.setScissor(scissor.left, height - scissor.bottom,
+ scissor.getWidth(), scissor.getHeight());
}
}
}
@@ -1632,31 +1614,13 @@
}
// disable scissor at the end of the frame
- glDisable(GL_SCISSOR_TEST);
+ engine.disableScissor();
}
-void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw,
- const Region& region) const
-{
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glColor4f(0,0,0,0);
-
+void SurfaceFlinger::drawWormhole(const sp<const DisplayDevice>& hw, const Region& region) const {
const int32_t height = hw->getHeight();
- Region::const_iterator it = region.begin();
- Region::const_iterator const end = region.end();
- while (it != end) {
- const Rect& r = *it++;
- GLfloat vertices[][2] = {
- { (GLfloat) r.left, (GLfloat) (height - r.top) },
- { (GLfloat) r.left, (GLfloat) (height - r.bottom) },
- { (GLfloat) r.right, (GLfloat) (height - r.bottom) },
- { (GLfloat) r.right, (GLfloat) (height - r.top) }
- };
- glVertexPointer(2, GL_FLOAT, 0, vertices);
- glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
- }
+ RenderEngine& engine(getRenderEngine());
+ engine.fillRegionWithColor(region, height, 0, 0, 0, 0);
}
void SurfaceFlinger::addClientLayer(const sp<Client>& client,
@@ -1673,8 +1637,7 @@
mGraphicBufferProducerList.add(gbc->asBinder());
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer)
-{
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
Mutex::Autolock _l(mStateLock);
ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
if (index >= 0) {
@@ -1686,18 +1649,15 @@
return status_t(index);
}
-uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags)
-{
+uint32_t SurfaceFlinger::peekTransactionFlags(uint32_t flags) {
return android_atomic_release_load(&mTransactionFlags);
}
-uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
-{
+uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
return android_atomic_and(~flags, &mTransactionFlags) & flags;
}
-uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
-{
+uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
if ((old & flags)==0) { // wake the server up
signalTransaction();
@@ -2739,31 +2699,22 @@
bool yswap)
{
ATRACE_CALL();
+ RenderEngine& engine(getRenderEngine());
// get screen geometry
const uint32_t hw_w = hw->getWidth();
const uint32_t hw_h = hw->getHeight();
-
const bool filtering = reqWidth != hw_w || reqWidth != hw_h;
// make sure to clear all GL error flags
- while ( glGetError() != GL_NO_ERROR ) ;
+ engine.checkErrors();
// set-up our viewport
- glViewport(0, 0, reqWidth, reqHeight);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- if (yswap) glOrthof(0, hw_w, hw_h, 0, 0, 1);
- else glOrthof(0, hw_w, 0, hw_h, 0, 1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
+ engine.setViewportAndProjection(reqWidth, reqHeight, hw_w, hw_h, yswap);
+ engine.disableTexturing();
// redraw the screen entirely...
- glDisable(GL_SCISSOR_TEST);
- glClearColor(0,0,0,1);
- glClear(GL_COLOR_BUFFER_BIT);
- glDisable(GL_TEXTURE_EXTERNAL_OES);
- glDisable(GL_TEXTURE_2D);
+ engine.clearWithColor(0, 0, 0, 1);
const LayerVector& layers( mDrawingState.layersSortedByZ );
const size_t count = layers.size();
@@ -2834,20 +2785,10 @@
EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
if (image != EGL_NO_IMAGE_KHR) {
- GLuint tname, name;
-
- // turn our EGLImage into a texture
- glGenTextures(1, &tname);
- glBindTexture(GL_TEXTURE_2D, tname);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
- // create a Framebuffer Object to render into
- glGenFramebuffersOES(1, &name);
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
- glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
- GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
-
- GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
- if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
+ // this binds the given EGLImage as a framebuffer for the
+ // duration of this scope.
+ RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
+ if (imageBond.getStatus() == NO_ERROR) {
// this will in fact render into our dequeued buffer
// via an FBO, which means we didn't have to create
// an EGLSurface and therefore we're not
@@ -2858,12 +2799,6 @@
ALOGE("got GL_FRAMEBUFFER_COMPLETE_OES error while taking screenshot");
result = INVALID_OPERATION;
}
-
- // back to main framebuffer
- glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
- glDeleteFramebuffersOES(1, &name);
- glDeleteTextures(1, &tname);
-
// destroy our image
eglDestroyImageKHR(mEGLDisplay, image);
} else {
@@ -2955,3 +2890,12 @@
// ---------------------------------------------------------------------------
}; // namespace android
+
+
+#if defined(__gl_h_)
+#error "don't include gl/gl.h in this file"
+#endif
+
+#if defined(__gl2_h_)
+#error "don't include gl2/gl2.h in this file"
+#endif