Merge "Fix a couple issues with the new hwcomposer HAL" into gingerbread

This commit is contained in:
Mathias Agopian
2010-08-12 15:07:29 -07:00
committed by Android (Google) Code Review
3 changed files with 63 additions and 50 deletions

View File

@@ -34,7 +34,7 @@ namespace android {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
HWComposer::HWComposer() HWComposer::HWComposer()
: mModule(0), mHwc(0), mList(0), : mModule(0), mHwc(0), mList(0), mCapacity(0),
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE) mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
{ {
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
@@ -63,10 +63,13 @@ void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
} }
status_t HWComposer::createWorkList(size_t numLayers) { status_t HWComposer::createWorkList(size_t numLayers) {
if (mHwc && (!mList || mList->numHwLayers < numLayers)) { if (mHwc) {
if (!mList || mCapacity < numLayers) {
free(mList); free(mList);
size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t); size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
mList = (hwc_layer_list_t*)malloc(size); mList = (hwc_layer_list_t*)malloc(size);
mCapacity = numLayers;
}
mList->flags = HWC_GEOMETRY_CHANGED; mList->flags = HWC_GEOMETRY_CHANGED;
mList->numHwLayers = numLayers; mList->numHwLayers = numLayers;
} }
@@ -84,12 +87,12 @@ status_t HWComposer::commit() const {
return (status_t)err; return (status_t)err;
} }
HWComposer::iterator HWComposer::begin() { size_t HWComposer::getNumLayers() const {
return mList ? &(mList->hwLayers[0]) : NULL; return mList ? mList->numHwLayers : 0;
} }
HWComposer::iterator HWComposer::end() { hwc_layer_t* HWComposer::getLayers() const {
return mList ? &(mList->hwLayers[mList->numHwLayers]) : NULL; return mList ? mList->hwLayers : 0;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@@ -49,16 +49,14 @@ public:
status_t commit() const; status_t commit() const;
typedef hwc_layer_t const * const_iterator; size_t getNumLayers() const;
typedef hwc_layer_t* iterator; hwc_layer_t* getLayers() const;
iterator begin();
iterator end();
private: private:
hw_module_t const* mModule; hw_module_t const* mModule;
hwc_composer_device_t* mHwc; hwc_composer_device_t* mHwc;
hwc_layer_list_t* mList; hwc_layer_list_t* mList;
size_t mCapacity;
hwc_display_t mDpy; hwc_display_t mDpy;
hwc_surface_t mSur; hwc_surface_t mSur;
}; };

View File

@@ -755,10 +755,9 @@ void SurfaceFlinger::handleWorkList()
const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ); const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
const size_t count = currentLayers.size(); const size_t count = currentLayers.size();
hwc.createWorkList(count); hwc.createWorkList(count);
HWComposer::iterator cur(hwc.begin()); hwc_layer_t* const cur(hwc.getLayers());
HWComposer::iterator last(hwc.end()); for (size_t i=0 ; cur && i<count ; i++) {
for (size_t i=0 ; (i<count) && (cur!=last) ; ++i, ++cur) { currentLayers[i]->setGeometry(&cur[i]);
currentLayers[i]->setGeometry(cur);
} }
} }
} }
@@ -829,47 +828,41 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
status_t err = NO_ERROR; status_t err = NO_ERROR;
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ); const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
const size_t count = layers.size(); size_t count = layers.size();
const DisplayHardware& hw(graphicPlane(0).displayHardware()); const DisplayHardware& hw(graphicPlane(0).displayHardware());
HWComposer& hwc(hw.getHwComposer()); HWComposer& hwc(hw.getHwComposer());
HWComposer::iterator cur(hwc.begin()); hwc_layer_t* const cur(hwc.getLayers());
HWComposer::iterator last(hwc.end());
// update the per-frame h/w composer data for each layer LOGE_IF(cur && hwc.getNumLayers() != count,
if (cur != last) { "HAL number of layers (%d) doesn't match surfaceflinger (%d)",
for (size_t i=0 ; i<count && cur!=last ; ++i, ++cur) { hwc.getNumLayers(), count);
layers[i]->setPerFrameData(cur);
// just to be extra-safe, use the smallest count
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
*/
Region transparent;
if (cur) {
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(layers[i]);
layer->setPerFrameData(&cur[i]);
if (cur[i].hints & HWC_HINT_CLEAR_FB) {
if (!(layer->needsBlending())) {
transparent.orSelf(layer->visibleRegionScreen);
}
}
} }
err = hwc.prepare(); err = hwc.prepare();
LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err)); LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
} }
// and then, render the layers targeted at the framebuffer /*
Region transparent(hw.bounds()); * clear the area of the FB that need to be transparent
for (size_t i=0 ; i<count ; ++i) { */
// see if we need to skip this layer
if (!err && cur != last) {
if (!((cur->compositionType == HWC_FRAMEBUFFER) ||
(cur->flags & HWC_SKIP_LAYER))) {
++cur;
continue;
}
++cur;
}
// draw the layer into the framebuffer
const sp<LayerBase>& layer(layers[i]);
transparent.subtractSelf(layer->visibleRegionScreen);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
if (!clip.isEmpty()) {
layer->draw(clip);
}
}
// finally clear everything we didn't draw as a result of calling
// prepare (this leaves the FB transparent).
transparent.andSelf(dirty); transparent.andSelf(dirty);
if (!transparent.isEmpty()) { if (!transparent.isEmpty()) {
glClearColor(0,0,0,0); glClearColor(0,0,0,0);
@@ -883,6 +876,25 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
} }
/*
* and then, render the layers targeted at the framebuffer
*/
for (size_t i=0 ; i<count ; i++) {
if (cur) {
if (!(cur[i].compositionType == HWC_FRAMEBUFFER) ||
cur[i].flags & HWC_SKIP_LAYER) {
// skip layers handled by the HAL
continue;
}
}
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
if (!clip.isEmpty()) {
layer->draw(clip);
}
}
} }
void SurfaceFlinger::unlockClients() void SurfaceFlinger::unlockClients()