getting closer to final main composition loop
Change-Id: Icd63782366ffd11d9ea00c925ae5783ed7440cdb
This commit is contained in:
parent
87baae104a
commit
52bbb1ae23
|
@ -310,6 +310,14 @@ void DisplayHardware::dump(String8& res) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayHardware::makeCurrent(const DisplayHardware& hw, EGLContext ctx) {
|
||||||
|
EGLSurface sur = eglGetCurrentSurface(EGL_DRAW);
|
||||||
|
if (sur != hw.mSurface) {
|
||||||
|
EGLDisplay dpy = eglGetCurrentDisplay();
|
||||||
|
eglMakeCurrent(dpy, hw.mSurface, hw.mSurface, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
|
void DisplayHardware::setVisibleLayersSortedByZ(const Vector< sp<LayerBase> >& layers) {
|
||||||
|
|
|
@ -107,6 +107,8 @@ public:
|
||||||
}
|
}
|
||||||
inline Rect bounds() const { return getBounds(); }
|
inline Rect bounds() const { return getBounds(); }
|
||||||
|
|
||||||
|
static void makeCurrent(const DisplayHardware& hw, EGLContext ctx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(EGLConfig config);
|
void init(EGLConfig config);
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ void Layer::setPerFrameData(HWComposer::HWCLayerInterface& layer) {
|
||||||
|
|
||||||
void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) {
|
void Layer::setAcquireFence(HWComposer::HWCLayerInterface& layer) {
|
||||||
int fenceFd = -1;
|
int fenceFd = -1;
|
||||||
if (mNeedHwcFence) {
|
if (mNeedHwcFence && (layer.getCompositionType() == HWC_OVERLAY)) {
|
||||||
sp<Fence> fence = mSurfaceTexture->getCurrentFence();
|
sp<Fence> fence = mSurfaceTexture->getCurrentFence();
|
||||||
if (fence.get()) {
|
if (fence.get()) {
|
||||||
fenceFd = fence->dup();
|
fenceFd = fence->dup();
|
||||||
|
|
|
@ -82,6 +82,7 @@ SurfaceFlinger::SurfaceFlinger()
|
||||||
mTransactionFlags(0),
|
mTransactionFlags(0),
|
||||||
mTransationPending(false),
|
mTransationPending(false),
|
||||||
mLayersRemoved(false),
|
mLayersRemoved(false),
|
||||||
|
mRepaintEverything(0),
|
||||||
mBootTime(systemTime()),
|
mBootTime(systemTime()),
|
||||||
mVisibleRegionsDirty(false),
|
mVisibleRegionsDirty(false),
|
||||||
mHwWorkListDirty(false),
|
mHwWorkListDirty(false),
|
||||||
|
@ -577,7 +578,7 @@ void SurfaceFlinger::handleMessageInvalidate() {
|
||||||
void SurfaceFlinger::handleMessageRefresh() {
|
void SurfaceFlinger::handleMessageRefresh() {
|
||||||
handleRefresh();
|
handleRefresh();
|
||||||
|
|
||||||
if (mVisibleRegionsDirty) {
|
if (CC_UNLIKELY(mVisibleRegionsDirty)) {
|
||||||
mVisibleRegionsDirty = false;
|
mVisibleRegionsDirty = false;
|
||||||
invalidateHwcGeometry();
|
invalidateHwcGeometry();
|
||||||
|
|
||||||
|
@ -586,9 +587,8 @@ void SurfaceFlinger::handleMessageRefresh() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
|
||||||
// TODO: iterate through all displays
|
for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
|
||||||
{
|
DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
|
||||||
DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
|
|
||||||
|
|
||||||
Region opaqueRegion;
|
Region opaqueRegion;
|
||||||
Region dirtyRegion;
|
Region dirtyRegion;
|
||||||
|
@ -612,45 +612,70 @@ void SurfaceFlinger::handleMessageRefresh() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
|
HWComposer& hwc(getHwComposer());
|
||||||
|
if (hwc.initCheck() == NO_ERROR) {
|
||||||
|
// build the h/w work list
|
||||||
|
const bool workListsDirty = mHwWorkListDirty;
|
||||||
|
mHwWorkListDirty = false;
|
||||||
|
for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
|
||||||
|
DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
|
||||||
|
const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
|
||||||
|
const size_t count = currentLayers.size();
|
||||||
|
|
||||||
// TODO: iterate through all displays
|
hwc.createWorkList(count); // FIXME: the worklist should include enough space for all layer of all displays
|
||||||
for (int dpy=0 ; dpy<1 ; dpy++) {
|
|
||||||
DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(0)));
|
HWComposer::LayerListIterator cur = hwc.begin();
|
||||||
if (hw.dirtyRegion.isEmpty()) {
|
const HWComposer::LayerListIterator end = hwc.end();
|
||||||
continue;
|
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
|
||||||
|
const sp<LayerBase>& layer(currentLayers[i]);
|
||||||
|
|
||||||
|
if (CC_UNLIKELY(workListsDirty)) {
|
||||||
|
layer->setGeometry(hw, *cur);
|
||||||
|
if (mDebugDisableHWC || mDebugRegion) {
|
||||||
|
cur->setSkip(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* update the per-frame h/w composer data for each layer
|
||||||
|
* and build the transparent region of the FB
|
||||||
|
*/
|
||||||
|
layer->setPerFrameData(*cur);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
status_t err = hwc.prepare();
|
||||||
|
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
|
||||||
|
for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
|
||||||
|
DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
|
||||||
|
|
||||||
// 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 Transform& planeTransform(hw.getTransform());
|
||||||
Region dirtyRegion;
|
Region dirtyRegion;
|
||||||
if (repaintEverything) {
|
if (repaintEverything) {
|
||||||
|
dirtyRegion.set(hw.bounds());
|
||||||
|
} else {
|
||||||
dirtyRegion = planeTransform.transform(hw.dirtyRegion);
|
dirtyRegion = planeTransform.transform(hw.dirtyRegion);
|
||||||
dirtyRegion.andSelf(hw.bounds());
|
dirtyRegion.andSelf(hw.bounds());
|
||||||
} else {
|
|
||||||
dirtyRegion.set(hw.bounds());
|
|
||||||
}
|
}
|
||||||
hw.dirtyRegion.clear();
|
hw.dirtyRegion.clear();
|
||||||
|
|
||||||
// build the h/w work list
|
if (!dirtyRegion.isEmpty()) {
|
||||||
if (CC_UNLIKELY(mHwWorkListDirty)) {
|
if (hw.canDraw()) {
|
||||||
handleWorkList(hw);
|
// repaint the framebuffer (if needed)
|
||||||
}
|
handleRepaint(hw, dirtyRegion);
|
||||||
|
}
|
||||||
if (CC_LIKELY(hw.canDraw())) {
|
|
||||||
// repaint the framebuffer (if needed)
|
|
||||||
handleRepaint(hw, dirtyRegion);
|
|
||||||
// inform the h/w that we're done compositing
|
|
||||||
hw.compositionComplete();
|
|
||||||
postFramebuffer();
|
|
||||||
} else {
|
|
||||||
// pretend we did the post
|
|
||||||
hw.compositionComplete();
|
|
||||||
}
|
}
|
||||||
|
// inform the h/w that we're done compositing
|
||||||
|
hw.compositionComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postFramebuffer();
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
#if 1
|
||||||
// render to the external display if we have one
|
// render to the external display if we have one
|
||||||
EGLSurface externalDisplaySurface = getExternalDisplaySurface();
|
EGLSurface externalDisplaySurface = getExternalDisplaySurface();
|
||||||
if (externalDisplaySurface != EGL_NO_SURFACE) {
|
if (externalDisplaySurface != EGL_NO_SURFACE) {
|
||||||
|
@ -670,6 +695,7 @@ void SurfaceFlinger::handleMessageRefresh() {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
||||||
|
DisplayHardware& hw(const_cast<DisplayDevice&>(getDisplayHardware(0)));
|
||||||
const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
|
const Vector< sp<LayerBase> >& layers( hw.getVisibleLayersSortedByZ() );
|
||||||
const size_t count = layers.size();
|
const size_t count = layers.size();
|
||||||
for (size_t i=0 ; i<count ; ++i) {
|
for (size_t i=0 ; i<count ; ++i) {
|
||||||
|
@ -695,45 +721,51 @@ void SurfaceFlinger::handleMessageRefresh() {
|
||||||
void SurfaceFlinger::postFramebuffer()
|
void SurfaceFlinger::postFramebuffer()
|
||||||
{
|
{
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
// mSwapRegion can be empty here is some cases, for instance if a hidden
|
|
||||||
// or fully transparent window is updating.
|
|
||||||
// in that case, we need to flip anyways to not risk a deadlock with
|
|
||||||
// h/w composer.
|
|
||||||
|
|
||||||
const DisplayHardware& hw(getDefaultDisplayHardware());
|
|
||||||
HWComposer& hwc(getHwComposer());
|
|
||||||
const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
|
|
||||||
size_t numLayers = layers.size();
|
|
||||||
const nsecs_t now = systemTime();
|
const nsecs_t now = systemTime();
|
||||||
mDebugInSwapBuffers = now;
|
mDebugInSwapBuffers = now;
|
||||||
|
|
||||||
if (hwc.initCheck() == NO_ERROR) {
|
HWComposer& hwc(getHwComposer());
|
||||||
HWComposer::LayerListIterator cur = hwc.begin();
|
|
||||||
const HWComposer::LayerListIterator end = hwc.end();
|
for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
|
||||||
for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
|
DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
|
||||||
if (cur->getCompositionType() == HWC_OVERLAY) {
|
if (hwc.initCheck() == NO_ERROR) {
|
||||||
layers[i]->setAcquireFence(*cur);
|
const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
|
||||||
} else {
|
const size_t count = currentLayers.size();
|
||||||
cur->setAcquireFenceFd(-1);
|
HWComposer::LayerListIterator cur = hwc.begin();
|
||||||
|
const HWComposer::LayerListIterator end = hwc.end();
|
||||||
|
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
|
||||||
|
const sp<LayerBase>& layer(currentLayers[i]);
|
||||||
|
layer->setAcquireFence(*cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
hw.flip(hw.swapRegion);
|
||||||
|
hw.swapRegion.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
hw.flip(hw.swapRegion);
|
|
||||||
hw.swapRegion.clear();
|
|
||||||
|
|
||||||
if (hwc.initCheck() == NO_ERROR) {
|
if (hwc.initCheck() == NO_ERROR) {
|
||||||
hwc.commit(mEGLDisplay, hw.getEGLSurface());
|
// FIXME: eventually commit() won't take arguments
|
||||||
HWComposer::LayerListIterator cur = hwc.begin();
|
hwc.commit(mEGLDisplay, getDefaultDisplayHardware().getEGLSurface());
|
||||||
const HWComposer::LayerListIterator end = hwc.end();
|
}
|
||||||
for (size_t i = 0; cur != end && i < numLayers; ++i, ++cur) {
|
|
||||||
layers[i]->onLayerDisplayed(&*cur);
|
for (int dpy=0 ; dpy<1 ; dpy++) { // TODO: iterate through all displays
|
||||||
}
|
DisplayHardware& hw(const_cast<DisplayHardware&>(getDisplayHardware(dpy)));
|
||||||
} else {
|
const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
|
||||||
eglSwapBuffers(mEGLDisplay, hw.getEGLSurface());
|
const size_t count = currentLayers.size();
|
||||||
for (size_t i = 0; i < numLayers; i++) {
|
if (hwc.initCheck() == NO_ERROR) {
|
||||||
layers[i]->onLayerDisplayed(NULL);
|
HWComposer::LayerListIterator cur = hwc.begin();
|
||||||
|
const HWComposer::LayerListIterator end = hwc.end();
|
||||||
|
for (size_t i = 0; cur != end && i < count; ++i, ++cur) {
|
||||||
|
currentLayers[i]->onLayerDisplayed(&*cur);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eglSwapBuffers(mEGLDisplay, hw.getEGLSurface());
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
currentLayers[i]->onLayerDisplayed(NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: we need to call eglSwapBuffers() on displays that have GL composition
|
||||||
}
|
}
|
||||||
|
|
||||||
mLastSwapBufferTime = systemTime() - now;
|
mLastSwapBufferTime = systemTime() - now;
|
||||||
|
@ -1028,27 +1060,6 @@ void SurfaceFlinger::handleRefresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SurfaceFlinger::handleWorkList(const DisplayHardware& hw)
|
|
||||||
{
|
|
||||||
mHwWorkListDirty = false;
|
|
||||||
HWComposer& hwc(getHwComposer());
|
|
||||||
if (hwc.initCheck() == NO_ERROR) {
|
|
||||||
const Vector< sp<LayerBase> >& currentLayers(hw.getVisibleLayersSortedByZ());
|
|
||||||
const size_t count = currentLayers.size();
|
|
||||||
hwc.createWorkList(count);
|
|
||||||
|
|
||||||
HWComposer::LayerListIterator cur = hwc.begin();
|
|
||||||
const HWComposer::LayerListIterator end = hwc.end();
|
|
||||||
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
|
|
||||||
currentLayers[i]->setGeometry(hw, *cur);
|
|
||||||
if (mDebugDisableHWC || mDebugRegion) {
|
|
||||||
cur->setSkip(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SurfaceFlinger::handleRepaint(const DisplayHardware& hw,
|
void SurfaceFlinger::handleRepaint(const DisplayHardware& hw,
|
||||||
const Region& inDirtyRegion)
|
const Region& inDirtyRegion)
|
||||||
{
|
{
|
||||||
|
@ -1063,10 +1074,6 @@ void SurfaceFlinger::handleRepaint(const DisplayHardware& hw,
|
||||||
debugFlashRegions(hw, dirtyRegion);
|
debugFlashRegions(hw, dirtyRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the frame buffer
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
uint32_t flags = hw.getFlags();
|
uint32_t flags = hw.getFlags();
|
||||||
if (flags & DisplayHardware::SWAP_RECTANGLE) {
|
if (flags & DisplayHardware::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
|
||||||
|
@ -1087,57 +1094,29 @@ void SurfaceFlinger::handleRepaint(const DisplayHardware& hw,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupHardwareComposer(hw);
|
|
||||||
composeSurfaces(hw, dirtyRegion);
|
composeSurfaces(hw, dirtyRegion);
|
||||||
|
|
||||||
// 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::setupHardwareComposer(const DisplayHardware& hw)
|
|
||||||
{
|
|
||||||
HWComposer& hwc(getHwComposer());
|
|
||||||
HWComposer::LayerListIterator cur = hwc.begin();
|
|
||||||
const HWComposer::LayerListIterator end = hwc.end();
|
|
||||||
if (cur == end) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const Vector< sp<LayerBase> >& layers(hw.getVisibleLayersSortedByZ());
|
|
||||||
size_t count = layers.size();
|
|
||||||
|
|
||||||
ALOGE_IF(hwc.getNumLayers() != count,
|
|
||||||
"HAL number of layers (%d) doesn't match surfaceflinger (%d)",
|
|
||||||
hwc.getNumLayers(), count);
|
|
||||||
|
|
||||||
// just to be extra-safe, use the smallest count
|
|
||||||
if (hwc.initCheck() == NO_ERROR) {
|
|
||||||
count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* update the per-frame h/w composer data for each layer
|
|
||||||
* and build the transparent region of the FB
|
|
||||||
*/
|
|
||||||
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
|
|
||||||
const sp<LayerBase>& layer(layers[i]);
|
|
||||||
layer->setPerFrameData(*cur);
|
|
||||||
}
|
|
||||||
status_t err = hwc.prepare();
|
|
||||||
ALOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
|
void SurfaceFlinger::composeSurfaces(const DisplayHardware& hw, const Region& dirty)
|
||||||
{
|
{
|
||||||
HWComposer& hwc(getHwComposer());
|
HWComposer& hwc(getHwComposer());
|
||||||
HWComposer::LayerListIterator cur = hwc.begin();
|
HWComposer::LayerListIterator cur = hwc.begin();
|
||||||
const HWComposer::LayerListIterator end = hwc.end();
|
const HWComposer::LayerListIterator end = hwc.end();
|
||||||
|
|
||||||
const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER);
|
const size_t fbLayerCount = hwc.getLayerCount(HWC_FRAMEBUFFER); // FIXME: this should be per display
|
||||||
if (cur==end || fbLayerCount) {
|
if (cur==end || fbLayerCount) {
|
||||||
// Never touch the framebuffer if we don't have any framebuffer layers
|
|
||||||
|
|
||||||
if (hwc.getLayerCount(HWC_OVERLAY)) {
|
DisplayHardware::makeCurrent(hw, mEGLContext);
|
||||||
|
|
||||||
|
// set the frame buffer
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
// Never touch the framebuffer if we don't have any framebuffer layers
|
||||||
|
if (hwc.getLayerCount(HWC_OVERLAY)) { // FIXME: this should be per display
|
||||||
// when using overlays, we assume a fully transparent framebuffer
|
// when using overlays, we assume a fully transparent framebuffer
|
||||||
// NOTE: we could reduce how much we need to clear, for instance
|
// NOTE: we could reduce how much we need to clear, for instance
|
||||||
// remove where there are opaque FB layers. however, on some
|
// remove where there are opaque FB layers. however, on some
|
||||||
|
|
|
@ -237,7 +237,6 @@ private:
|
||||||
void handlePageFlip();
|
void handlePageFlip();
|
||||||
|
|
||||||
void handleRefresh();
|
void handleRefresh();
|
||||||
void handleWorkList(const DisplayHardware& hw);
|
|
||||||
void handleRepaint(const DisplayHardware& hw, const Region& dirtyRegion);
|
void handleRepaint(const DisplayHardware& hw, const Region& dirtyRegion);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
|
@ -339,7 +338,6 @@ private:
|
||||||
uint32_t layerStack,
|
uint32_t layerStack,
|
||||||
Region& dirtyRegion, Region& opaqueRegion);
|
Region& dirtyRegion, Region& opaqueRegion);
|
||||||
void postFramebuffer();
|
void postFramebuffer();
|
||||||
void setupHardwareComposer(const DisplayHardware& hw);
|
|
||||||
void composeSurfaces(const DisplayHardware& hw, const Region& dirty);
|
void composeSurfaces(const DisplayHardware& hw, const Region& dirty);
|
||||||
void drawWormhole(const Region& region) const;
|
void drawWormhole(const Region& region) const;
|
||||||
GLuint getProtectedTexName() const {
|
GLuint getProtectedTexName() const {
|
||||||
|
|
Loading…
Reference in New Issue