refactor compositing code to avoid multiple eglMakeCurrent() calls
when multiple displays are connected, we ended-up having to call eglMakeCurrent() twice per display due to a limitation in EGL. this fixes that. Change-Id: I11e4584df50f8c24bbecee74e37b28b3ee031d2f
This commit is contained in:
parent
5f20e2d446
commit
cd60f99aba
@ -218,6 +218,18 @@ bool DisplayDevice::getSecureLayerVisible() const {
|
|||||||
return mSecureLayerVisible;
|
return mSecureLayerVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
|
||||||
|
Region dirty;
|
||||||
|
const Transform& planeTransform(mGlobalTransform);
|
||||||
|
if (repaintEverything) {
|
||||||
|
dirty.set(getBounds());
|
||||||
|
} else {
|
||||||
|
dirty = planeTransform.transform(this->dirtyRegion);
|
||||||
|
dirty.andSelf(getBounds());
|
||||||
|
}
|
||||||
|
return dirty;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
bool DisplayDevice::canDraw() const {
|
bool DisplayDevice::canDraw() const {
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
void setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers);
|
void setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers);
|
||||||
Vector< sp<LayerBase> > getVisibleLayersSortedByZ() const;
|
Vector< sp<LayerBase> > getVisibleLayersSortedByZ() const;
|
||||||
bool getSecureLayerVisible() const;
|
bool getSecureLayerVisible() const;
|
||||||
|
Region getDirtyRegion(bool repaintEverything) const;
|
||||||
|
|
||||||
status_t setOrientation(int orientation);
|
status_t setOrientation(int orientation);
|
||||||
void setLayerStack(uint32_t stack);
|
void setLayerStack(uint32_t stack);
|
||||||
|
@ -649,20 +649,101 @@ void SurfaceFlinger::handleMessageTransaction() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handleMessageInvalidate() {
|
void SurfaceFlinger::handleMessageInvalidate() {
|
||||||
|
ATRACE_CALL();
|
||||||
handlePageFlip();
|
handlePageFlip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handleMessageRefresh() {
|
void SurfaceFlinger::handleMessageRefresh() {
|
||||||
handleRefresh();
|
ATRACE_CALL();
|
||||||
|
preComposition();
|
||||||
|
rebuildLayerStacks();
|
||||||
|
setUpHWComposer();
|
||||||
|
doDebugFlashRegions();
|
||||||
|
doComposition();
|
||||||
|
postComposition();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::doDebugFlashRegions()
|
||||||
|
{
|
||||||
|
// is debugging enabled
|
||||||
|
if (CC_LIKELY(!mDebugRegion))
|
||||||
|
return;
|
||||||
|
|
||||||
|
const bool repaintEverything = mRepaintEverything;
|
||||||
|
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
||||||
|
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
||||||
|
if (hw->canDraw()) {
|
||||||
|
// transform the dirty region into this screen's coordinate space
|
||||||
|
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
|
||||||
|
if (!dirtyRegion.isEmpty()) {
|
||||||
|
// redraw the whole screen
|
||||||
|
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] = {
|
||||||
|
{ r.left, height - r.top },
|
||||||
|
{ r.left, height - r.bottom },
|
||||||
|
{ r.right, height - r.bottom },
|
||||||
|
{ r.right, height - r.top }
|
||||||
|
};
|
||||||
|
glVertexPointer(2, GL_FLOAT, 0, vertices);
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
}
|
||||||
|
hw->compositionComplete();
|
||||||
|
// FIXME
|
||||||
|
if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
|
||||||
|
eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
postFramebuffer();
|
||||||
|
|
||||||
|
if (mDebugRegion > 1) {
|
||||||
|
usleep(mDebugRegion * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::preComposition()
|
||||||
|
{
|
||||||
|
bool needExtraInvalidate = false;
|
||||||
|
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
||||||
|
const size_t count = currentLayers.size();
|
||||||
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
|
if (currentLayers[i]->onPreComposition()) {
|
||||||
|
needExtraInvalidate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (needExtraInvalidate) {
|
||||||
|
signalLayerUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::postComposition()
|
||||||
|
{
|
||||||
|
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
||||||
|
const size_t count = currentLayers.size();
|
||||||
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
|
currentLayers[i]->onPostComposition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::rebuildLayerStacks() {
|
||||||
|
// rebuild the visible layer list per screen
|
||||||
if (CC_UNLIKELY(mVisibleRegionsDirty)) {
|
if (CC_UNLIKELY(mVisibleRegionsDirty)) {
|
||||||
|
ATRACE_CALL();
|
||||||
mVisibleRegionsDirty = false;
|
mVisibleRegionsDirty = false;
|
||||||
invalidateHwcGeometry();
|
invalidateHwcGeometry();
|
||||||
|
|
||||||
/*
|
|
||||||
* rebuild the visible layer list per screen
|
|
||||||
*/
|
|
||||||
|
|
||||||
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
||||||
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
||||||
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
||||||
@ -684,10 +765,13 @@ void SurfaceFlinger::handleMessageRefresh() {
|
|||||||
}
|
}
|
||||||
hw->setVisibleLayersSortedByZ(layersSortedByZ);
|
hw->setVisibleLayersSortedByZ(layersSortedByZ);
|
||||||
hw->undefinedRegion.set(hw->getBounds());
|
hw->undefinedRegion.set(hw->getBounds());
|
||||||
hw->undefinedRegion.subtractSelf(hw->getTransform().transform(opaqueRegion));
|
hw->undefinedRegion.subtractSelf(
|
||||||
|
hw->getTransform().transform(opaqueRegion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::setUpHWComposer() {
|
||||||
HWComposer& hwc(getHwComposer());
|
HWComposer& hwc(getHwComposer());
|
||||||
if (hwc.initCheck() == NO_ERROR) {
|
if (hwc.initCheck() == NO_ERROR) {
|
||||||
// build the h/w work list
|
// build the h/w work list
|
||||||
@ -695,7 +779,8 @@ void SurfaceFlinger::handleMessageRefresh() {
|
|||||||
mHwWorkListDirty = false;
|
mHwWorkListDirty = false;
|
||||||
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
||||||
sp<const DisplayDevice> hw(mDisplays[dpy]);
|
sp<const DisplayDevice> hw(mDisplays[dpy]);
|
||||||
const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
|
const Vector< sp<LayerBase> >& currentLayers(
|
||||||
|
hw->getVisibleLayersSortedByZ());
|
||||||
const size_t count = currentLayers.size();
|
const size_t count = currentLayers.size();
|
||||||
|
|
||||||
const int32_t id = hw->getDisplayId();
|
const int32_t id = hw->getDisplayId();
|
||||||
@ -723,32 +808,27 @@ void SurfaceFlinger::handleMessageRefresh() {
|
|||||||
status_t err = hwc.prepare();
|
status_t err = hwc.prepare();
|
||||||
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::doComposition() {
|
||||||
|
ATRACE_CALL();
|
||||||
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
|
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
|
||||||
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
||||||
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
||||||
|
if (hw->canDraw()) {
|
||||||
// transform the dirty region into this screen's coordinate space
|
// transform the dirty region into this screen's coordinate space
|
||||||
const Transform& planeTransform(hw->getTransform());
|
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
|
||||||
Region dirtyRegion;
|
if (!dirtyRegion.isEmpty()) {
|
||||||
if (repaintEverything) {
|
|
||||||
dirtyRegion.set(hw->bounds());
|
|
||||||
} else {
|
|
||||||
dirtyRegion = planeTransform.transform(hw->dirtyRegion);
|
|
||||||
dirtyRegion.andSelf(hw->bounds());
|
|
||||||
}
|
|
||||||
hw->dirtyRegion.clear();
|
|
||||||
|
|
||||||
if (!dirtyRegion.isEmpty()) {
|
|
||||||
if (hw->canDraw()) {
|
|
||||||
// repaint the framebuffer (if needed)
|
// repaint the framebuffer (if needed)
|
||||||
handleRepaint(hw, dirtyRegion);
|
doDisplayComposition(hw, dirtyRegion);
|
||||||
}
|
}
|
||||||
|
hw->dirtyRegion.clear();
|
||||||
|
hw->flip(hw->swapRegion);
|
||||||
|
hw->swapRegion.clear();
|
||||||
}
|
}
|
||||||
// inform the h/w that we're done compositing
|
// inform the h/w that we're done compositing
|
||||||
hw->compositionComplete();
|
hw->compositionComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
postFramebuffer();
|
postFramebuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -760,30 +840,13 @@ void SurfaceFlinger::postFramebuffer()
|
|||||||
mDebugInSwapBuffers = now;
|
mDebugInSwapBuffers = now;
|
||||||
|
|
||||||
HWComposer& hwc(getHwComposer());
|
HWComposer& hwc(getHwComposer());
|
||||||
|
|
||||||
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
|
||||||
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
|
||||||
if (hwc.initCheck() == NO_ERROR) {
|
|
||||||
const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
|
|
||||||
const size_t count = currentLayers.size();
|
|
||||||
const int32_t id = hw->getDisplayId();
|
|
||||||
HWComposer::LayerListIterator cur = hwc.begin(id);
|
|
||||||
const HWComposer::LayerListIterator end = hwc.end(id);
|
|
||||||
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
|
|
||||||
const sp<LayerBase>& layer(currentLayers[i]);
|
|
||||||
layer->setAcquireFence(hw, *cur);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hw->flip(hw->swapRegion);
|
|
||||||
hw->swapRegion.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hwc.initCheck() == NO_ERROR) {
|
if (hwc.initCheck() == NO_ERROR) {
|
||||||
// FIXME: eventually commit() won't take arguments
|
// FIXME: eventually commit() won't take arguments
|
||||||
// FIXME: EGL spec says:
|
// FIXME: EGL spec says:
|
||||||
// "surface must be bound to the calling thread's current context,
|
// "surface must be bound to the calling thread's current context,
|
||||||
// for the current rendering API."
|
// for the current rendering API."
|
||||||
DisplayDevice::makeCurrent(getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN), mEGLContext);
|
DisplayDevice::makeCurrent(
|
||||||
|
getDisplayDevice(DisplayDevice::DISPLAY_ID_MAIN), mEGLContext);
|
||||||
hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
|
hwc.commit(mEGLDisplay, getDefaultDisplayDevice()->getEGLSurface());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,18 +861,7 @@ void SurfaceFlinger::postFramebuffer()
|
|||||||
for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
|
for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
|
||||||
currentLayers[i]->onLayerDisplayed(hw, &*cur);
|
currentLayers[i]->onLayerDisplayed(hw, &*cur);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// FIXME: we need to call eglSwapBuffers() on displays that have
|
|
||||||
// GL composition and only on those.
|
|
||||||
// however, currently hwc.commit() already does that for the main
|
|
||||||
// display and never for the other ones
|
|
||||||
if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
|
|
||||||
// FIXME: EGL spec says:
|
|
||||||
// "surface must be bound to the calling thread's current context,
|
|
||||||
// for the current rendering API."
|
|
||||||
DisplayDevice::makeCurrent(hw, mEGLContext);
|
|
||||||
eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
for (size_t i = 0; i < count; i++) {
|
||||||
currentLayers[i]->onLayerDisplayed(hw, NULL);
|
currentLayers[i]->onLayerDisplayed(hw, NULL);
|
||||||
}
|
}
|
||||||
@ -944,7 +996,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
|||||||
* Perform our own transaction if needed
|
* Perform our own transaction if needed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
|
const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
|
||||||
|
if (currentLayers.size() > previousLayers.size()) {
|
||||||
// layers have been added
|
// layers have been added
|
||||||
mVisibleRegionsDirty = true;
|
mVisibleRegionsDirty = true;
|
||||||
}
|
}
|
||||||
@ -954,7 +1007,6 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
|
|||||||
if (mLayersRemoved) {
|
if (mLayersRemoved) {
|
||||||
mLayersRemoved = false;
|
mLayersRemoved = false;
|
||||||
mVisibleRegionsDirty = true;
|
mVisibleRegionsDirty = true;
|
||||||
const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
|
|
||||||
const size_t count = previousLayers.size();
|
const size_t count = previousLayers.size();
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
const sp<LayerBase>& layer(previousLayers[i]);
|
const sp<LayerBase>& layer(previousLayers[i]);
|
||||||
@ -1130,16 +1182,13 @@ void SurfaceFlinger::invalidateLayerStack(uint32_t layerStack,
|
|||||||
|
|
||||||
void SurfaceFlinger::handlePageFlip()
|
void SurfaceFlinger::handlePageFlip()
|
||||||
{
|
{
|
||||||
ATRACE_CALL();
|
|
||||||
Region dirtyRegion;
|
Region dirtyRegion;
|
||||||
|
|
||||||
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
|
||||||
|
|
||||||
bool visibleRegions = false;
|
bool visibleRegions = false;
|
||||||
|
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
||||||
const size_t count = currentLayers.size();
|
const size_t count = currentLayers.size();
|
||||||
sp<LayerBase> const* layers = currentLayers.array();
|
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
const sp<LayerBase>& layer(layers[i]);
|
const sp<LayerBase>& layer(currentLayers[i]);
|
||||||
const Region dirty(layer->latchBuffer(visibleRegions));
|
const Region dirty(layer->latchBuffer(visibleRegions));
|
||||||
Layer::State s(layer->drawingState());
|
Layer::State s(layer->drawingState());
|
||||||
invalidateLayerStack(s.layerStack, dirty);
|
invalidateLayerStack(s.layerStack, dirty);
|
||||||
@ -1153,36 +1202,15 @@ void SurfaceFlinger::invalidateHwcGeometry()
|
|||||||
mHwWorkListDirty = true;
|
mHwWorkListDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handleRefresh()
|
|
||||||
{
|
|
||||||
bool needInvalidate = false;
|
|
||||||
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
|
||||||
const size_t count = currentLayers.size();
|
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
|
||||||
const sp<LayerBase>& layer(currentLayers[i]);
|
|
||||||
if (layer->onPreComposition()) {
|
|
||||||
needInvalidate = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (needInvalidate) {
|
|
||||||
signalLayerUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SurfaceFlinger::handleRepaint(const sp<const DisplayDevice>& hw,
|
void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
|
||||||
const Region& inDirtyRegion)
|
const Region& inDirtyRegion)
|
||||||
{
|
{
|
||||||
ATRACE_CALL();
|
|
||||||
|
|
||||||
Region dirtyRegion(inDirtyRegion);
|
Region dirtyRegion(inDirtyRegion);
|
||||||
|
|
||||||
// compute the invalid region
|
// compute the invalid region
|
||||||
hw->swapRegion.orSelf(dirtyRegion);
|
hw->swapRegion.orSelf(dirtyRegion);
|
||||||
|
|
||||||
if (CC_UNLIKELY(mDebugRegion)) {
|
|
||||||
debugFlashRegions(hw, dirtyRegion);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t flags = hw->getFlags();
|
uint32_t flags = hw->getFlags();
|
||||||
if (flags & DisplayDevice::SWAP_RECTANGLE) {
|
if (flags & DisplayDevice::SWAP_RECTANGLE) {
|
||||||
// we can redraw only what's dirty, but since SWAP_RECTANGLE only
|
// we can redraw only what's dirty, but since SWAP_RECTANGLE only
|
||||||
@ -1203,19 +1231,24 @@ void SurfaceFlinger::handleRepaint(const sp<const DisplayDevice>& hw,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
composeSurfaces(hw, dirtyRegion);
|
doComposeSurfaces(hw, dirtyRegion);
|
||||||
|
|
||||||
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
// FIXME: we need to call eglSwapBuffers() on displays that have
|
||||||
const size_t count = currentLayers.size();
|
// GL composition and only on those.
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
// however, currently hwc.commit() already does that for the main
|
||||||
currentLayers[i]->onPostComposition();
|
// display and never for the other ones
|
||||||
|
if (hw->getDisplayId() >= DisplayDevice::DISPLAY_ID_COUNT) {
|
||||||
|
// FIXME: EGL spec says:
|
||||||
|
// "surface must be bound to the calling thread's current context,
|
||||||
|
// for the current rendering API."
|
||||||
|
eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the swap region and clear the dirty region
|
// update the swap region and clear the dirty region
|
||||||
hw->swapRegion.orSelf(dirtyRegion);
|
hw->swapRegion.orSelf(dirtyRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
|
void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
|
||||||
{
|
{
|
||||||
HWComposer& hwc(getHwComposer());
|
HWComposer& hwc(getHwComposer());
|
||||||
int32_t id = hw->getDisplayId();
|
int32_t id = hw->getDisplayId();
|
||||||
@ -1259,74 +1292,32 @@ void SurfaceFlinger::composeSurfaces(const sp<const DisplayDevice>& hw, const Re
|
|||||||
for (size_t i=0 ; i<count ; ++i) {
|
for (size_t i=0 ; i<count ; ++i) {
|
||||||
const sp<LayerBase>& layer(layers[i]);
|
const sp<LayerBase>& layer(layers[i]);
|
||||||
const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
|
const Region clip(dirty.intersect(tr.transform(layer->visibleRegion)));
|
||||||
if (!clip.isEmpty()) {
|
|
||||||
if (cur != end && cur->getCompositionType() == HWC_OVERLAY) {
|
|
||||||
if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
|
|
||||||
&& layer->isOpaque()) {
|
|
||||||
// never clear the very first layer since we're
|
|
||||||
// guaranteed the FB is already cleared
|
|
||||||
layer->clearWithOpenGL(hw, clip);
|
|
||||||
}
|
|
||||||
++cur;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// render the layer
|
|
||||||
layer->draw(hw, clip);
|
|
||||||
}
|
|
||||||
if (cur != end) {
|
if (cur != end) {
|
||||||
|
// we're using h/w composer
|
||||||
|
if (!clip.isEmpty()) {
|
||||||
|
if (cur->getCompositionType() == HWC_OVERLAY) {
|
||||||
|
if (i && (cur->getHints() & HWC_HINT_CLEAR_FB)
|
||||||
|
&& layer->isOpaque()) {
|
||||||
|
// never clear the very first layer since we're
|
||||||
|
// guaranteed the FB is already cleared
|
||||||
|
layer->clearWithOpenGL(hw, clip);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
layer->draw(hw, clip);
|
||||||
|
}
|
||||||
|
layer->setAcquireFence(hw, *cur);
|
||||||
|
}
|
||||||
++cur;
|
++cur;
|
||||||
|
} else {
|
||||||
|
// we're not using h/w composer
|
||||||
|
if (!clip.isEmpty()) {
|
||||||
|
layer->draw(hw, clip);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::debugFlashRegions(const sp<const DisplayDevice>& hw,
|
|
||||||
const Region& dirtyRegion)
|
|
||||||
{
|
|
||||||
const uint32_t flags = hw->getFlags();
|
|
||||||
const int32_t height = hw->getHeight();
|
|
||||||
if (hw->swapRegion.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(flags & DisplayDevice::SWAP_RECTANGLE)) {
|
|
||||||
const Region repaint((flags & DisplayDevice::PARTIAL_UPDATES) ?
|
|
||||||
dirtyRegion.bounds() : hw->bounds());
|
|
||||||
composeSurfaces(hw, repaint);
|
|
||||||
}
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
|
|
||||||
static int toggle = 0;
|
|
||||||
toggle = 1 - toggle;
|
|
||||||
if (toggle) {
|
|
||||||
glColor4f(1, 0, 1, 1);
|
|
||||||
} else {
|
|
||||||
glColor4f(1, 1, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Region::const_iterator it = dirtyRegion.begin();
|
|
||||||
Region::const_iterator const end = dirtyRegion.end();
|
|
||||||
while (it != end) {
|
|
||||||
const Rect& r = *it++;
|
|
||||||
GLfloat vertices[][2] = {
|
|
||||||
{ r.left, height - r.top },
|
|
||||||
{ r.left, height - r.bottom },
|
|
||||||
{ r.right, height - r.bottom },
|
|
||||||
{ r.right, height - r.top }
|
|
||||||
};
|
|
||||||
glVertexPointer(2, GL_FLOAT, 0, vertices);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
hw->flip(hw->swapRegion);
|
|
||||||
|
|
||||||
if (mDebugRegion > 1)
|
|
||||||
usleep(mDebugRegion * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SurfaceFlinger::drawWormhole(const Region& region) const
|
void SurfaceFlinger::drawWormhole(const Region& region) const
|
||||||
{
|
{
|
||||||
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
glDisable(GL_TEXTURE_EXTERNAL_OES);
|
||||||
|
@ -248,9 +248,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
void handlePageFlip();
|
void handlePageFlip();
|
||||||
|
|
||||||
void handleRefresh();
|
|
||||||
void handleRepaint(const sp<const DisplayDevice>& hw, const Region& dirtyRegion);
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
* Transactions
|
* Transactions
|
||||||
*/
|
*/
|
||||||
@ -348,8 +345,19 @@ private:
|
|||||||
void computeVisibleRegions(const LayerVector& currentLayers,
|
void computeVisibleRegions(const LayerVector& currentLayers,
|
||||||
uint32_t layerStack,
|
uint32_t layerStack,
|
||||||
Region& dirtyRegion, Region& opaqueRegion);
|
Region& dirtyRegion, Region& opaqueRegion);
|
||||||
|
|
||||||
|
void preComposition();
|
||||||
|
void postComposition();
|
||||||
|
void rebuildLayerStacks();
|
||||||
|
void setUpHWComposer();
|
||||||
|
void doComposition();
|
||||||
|
void doDebugFlashRegions();
|
||||||
|
void doDisplayComposition(const sp<const DisplayDevice>& hw,
|
||||||
|
const Region& dirtyRegion);
|
||||||
|
void doComposeSurfaces(const sp<const DisplayDevice>& hw,
|
||||||
|
const Region& dirty);
|
||||||
|
|
||||||
void postFramebuffer();
|
void postFramebuffer();
|
||||||
void composeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty);
|
|
||||||
void drawWormhole(const Region& region) const;
|
void drawWormhole(const Region& region) const;
|
||||||
GLuint getProtectedTexName() const {
|
GLuint getProtectedTexName() const {
|
||||||
return mProtectedTexName;
|
return mProtectedTexName;
|
||||||
@ -358,7 +366,6 @@ private:
|
|||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
* Debugging & dumpsys
|
* Debugging & dumpsys
|
||||||
*/
|
*/
|
||||||
void debugFlashRegions(const sp<const DisplayDevice>& hw, const Region& dirtyReg);
|
|
||||||
void listLayersLocked(const Vector<String16>& args, size_t& index,
|
void listLayersLocked(const Vector<String16>& args, size_t& index,
|
||||||
String8& result, char* buffer, size_t SIZE) const;
|
String8& result, char* buffer, size_t SIZE) const;
|
||||||
void dumpStatsLocked(const Vector<String16>& args, size_t& index,
|
void dumpStatsLocked(const Vector<String16>& args, size_t& index,
|
||||||
|
Loading…
Reference in New Issue
Block a user