Merge "call into hwcomposer HAL when present" into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
90dc48b17f
@@ -5,6 +5,7 @@ LOCAL_SRC_FILES:= \
|
|||||||
clz.cpp.arm \
|
clz.cpp.arm \
|
||||||
DisplayHardware/DisplayHardware.cpp \
|
DisplayHardware/DisplayHardware.cpp \
|
||||||
DisplayHardware/DisplayHardwareBase.cpp \
|
DisplayHardware/DisplayHardwareBase.cpp \
|
||||||
|
DisplayHardware/HWComposer.cpp \
|
||||||
BlurFilter.cpp.arm \
|
BlurFilter.cpp.arm \
|
||||||
GLExtensions.cpp \
|
GLExtensions.cpp \
|
||||||
Layer.cpp \
|
Layer.cpp \
|
||||||
|
|||||||
@@ -36,11 +36,11 @@
|
|||||||
|
|
||||||
#include "DisplayHardware/DisplayHardware.h"
|
#include "DisplayHardware/DisplayHardware.h"
|
||||||
|
|
||||||
#include <hardware/copybit.h>
|
|
||||||
#include <hardware/overlay.h>
|
#include <hardware/overlay.h>
|
||||||
#include <hardware/gralloc.h>
|
#include <hardware/gralloc.h>
|
||||||
|
|
||||||
#include "GLExtensions.h"
|
#include "GLExtensions.h"
|
||||||
|
#include "HWComposer.h"
|
||||||
|
|
||||||
using namespace android;
|
using namespace android;
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ DisplayHardware::DisplayHardware(
|
|||||||
const sp<SurfaceFlinger>& flinger,
|
const sp<SurfaceFlinger>& flinger,
|
||||||
uint32_t dpy)
|
uint32_t dpy)
|
||||||
: DisplayHardwareBase(flinger, dpy),
|
: DisplayHardwareBase(flinger, dpy),
|
||||||
mFlags(0)
|
mFlags(0), mHwc(0)
|
||||||
{
|
{
|
||||||
init(dpy);
|
init(dpy);
|
||||||
}
|
}
|
||||||
@@ -262,6 +262,17 @@ void DisplayHardware::init(uint32_t dpy)
|
|||||||
|
|
||||||
// Unbind the context from this thread
|
// Unbind the context from this thread
|
||||||
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
|
||||||
|
|
||||||
|
// initialize the H/W composer
|
||||||
|
mHwc = new HWComposer();
|
||||||
|
if (mHwc->initCheck() == NO_ERROR) {
|
||||||
|
mHwc->setFrameBuffer(mDisplay, mSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HWComposer& DisplayHardware::getHwComposer() const {
|
||||||
|
return *mHwc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -317,7 +328,12 @@ void DisplayHardware::flip(const Region& dirty) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
mPageFlipCount++;
|
mPageFlipCount++;
|
||||||
eglSwapBuffers(dpy, surface);
|
|
||||||
|
if (mHwc->initCheck() == NO_ERROR) {
|
||||||
|
mHwc->commit();
|
||||||
|
} else {
|
||||||
|
eglSwapBuffers(dpy, surface);
|
||||||
|
}
|
||||||
checkEGLErrors("eglSwapBuffers");
|
checkEGLErrors("eglSwapBuffers");
|
||||||
|
|
||||||
// for debugging
|
// for debugging
|
||||||
|
|||||||
@@ -34,12 +34,11 @@
|
|||||||
#include "DisplayHardware/DisplayHardwareBase.h"
|
#include "DisplayHardware/DisplayHardwareBase.h"
|
||||||
|
|
||||||
struct overlay_control_device_t;
|
struct overlay_control_device_t;
|
||||||
struct framebuffer_device_t;
|
|
||||||
struct copybit_image_t;
|
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
class FramebufferNativeWindow;
|
class FramebufferNativeWindow;
|
||||||
|
class HWComposer;
|
||||||
|
|
||||||
class DisplayHardware : public DisplayHardwareBase
|
class DisplayHardware : public DisplayHardwareBase
|
||||||
{
|
{
|
||||||
@@ -81,6 +80,9 @@ public:
|
|||||||
EGLDisplay getEGLDisplay() const { return mDisplay; }
|
EGLDisplay getEGLDisplay() const { return mDisplay; }
|
||||||
overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
|
overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
|
||||||
|
|
||||||
|
// Hardware Composer
|
||||||
|
HWComposer& getHwComposer() const;
|
||||||
|
|
||||||
status_t compositionComplete() const;
|
status_t compositionComplete() const;
|
||||||
|
|
||||||
Rect bounds() const {
|
Rect bounds() const {
|
||||||
@@ -107,6 +109,8 @@ private:
|
|||||||
GLint mMaxViewportDims;
|
GLint mMaxViewportDims;
|
||||||
GLint mMaxTextureSize;
|
GLint mMaxTextureSize;
|
||||||
|
|
||||||
|
HWComposer* mHwc;
|
||||||
|
|
||||||
sp<FramebufferNativeWindow> mNativeWindow;
|
sp<FramebufferNativeWindow> mNativeWindow;
|
||||||
overlay_control_device_t* mOverlayEngine;
|
overlay_control_device_t* mOverlayEngine;
|
||||||
};
|
};
|
||||||
|
|||||||
93
services/surfaceflinger/DisplayHardware/HWComposer.cpp
Normal file
93
services/surfaceflinger/DisplayHardware/HWComposer.cpp
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <utils/Errors.h>
|
||||||
|
|
||||||
|
#include <hardware/hardware.h>
|
||||||
|
|
||||||
|
#include <cutils/log.h>
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
#include "HWComposer.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HWComposer::HWComposer()
|
||||||
|
: mModule(0), mHwc(0), mList(0),
|
||||||
|
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
|
||||||
|
{
|
||||||
|
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
|
||||||
|
LOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
|
||||||
|
if (err == 0) {
|
||||||
|
err = hwc_open(mModule, &mHwc);
|
||||||
|
LOGE_IF(err, "%s device failed to initialize (%s)",
|
||||||
|
HWC_HARDWARE_COMPOSER, strerror(-err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HWComposer::~HWComposer() {
|
||||||
|
free(mList);
|
||||||
|
if (mHwc) {
|
||||||
|
hwc_close(mHwc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t HWComposer::initCheck() const {
|
||||||
|
return mHwc ? NO_ERROR : NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
|
||||||
|
mDpy = (hwc_display_t)dpy;
|
||||||
|
mSur = (hwc_surface_t)sur;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t HWComposer::createWorkList(size_t numLayers) {
|
||||||
|
if (mHwc && (!mList || mList->numHwLayers < numLayers)) {
|
||||||
|
free(mList);
|
||||||
|
size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
|
||||||
|
mList = (hwc_layer_list_t*)malloc(size);
|
||||||
|
mList->flags = HWC_GEOMETRY_CHANGED;
|
||||||
|
mList->numHwLayers = numLayers;
|
||||||
|
}
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t HWComposer::prepare() const {
|
||||||
|
int err = mHwc->prepare(mHwc, mList);
|
||||||
|
return (status_t)err;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t HWComposer::commit() const {
|
||||||
|
int err = mHwc->set(mHwc, mDpy, mSur, mList);
|
||||||
|
mList->flags &= ~HWC_GEOMETRY_CHANGED;
|
||||||
|
return (status_t)err;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWComposer::iterator HWComposer::begin() {
|
||||||
|
return mList ? &(mList->hwLayers[0]) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWComposer::iterator HWComposer::end() {
|
||||||
|
return mList ? &(mList->hwLayers[mList->numHwLayers]) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
}; // namespace android
|
||||||
70
services/surfaceflinger/DisplayHardware/HWComposer.h
Normal file
70
services/surfaceflinger/DisplayHardware/HWComposer.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANDROID_SF_HWCOMPOSER_H
|
||||||
|
#define ANDROID_SF_HWCOMPOSER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
|
#include <hardware/hwcomposer.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class HWComposer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
HWComposer();
|
||||||
|
~HWComposer();
|
||||||
|
|
||||||
|
status_t initCheck() const;
|
||||||
|
|
||||||
|
// tells the HAL what the framebuffer is
|
||||||
|
void setFrameBuffer(EGLDisplay dpy, EGLSurface sur);
|
||||||
|
|
||||||
|
// create a work list for numLayers layer
|
||||||
|
status_t createWorkList(size_t numLayers);
|
||||||
|
|
||||||
|
// Asks the HAL what it can do
|
||||||
|
status_t prepare() const;
|
||||||
|
|
||||||
|
// commits the list
|
||||||
|
status_t commit() const;
|
||||||
|
|
||||||
|
|
||||||
|
typedef hwc_layer_t const * const_iterator;
|
||||||
|
typedef hwc_layer_t* iterator;
|
||||||
|
|
||||||
|
iterator begin();
|
||||||
|
iterator end();
|
||||||
|
|
||||||
|
private:
|
||||||
|
hw_module_t const* mModule;
|
||||||
|
hwc_composer_device_t* mHwc;
|
||||||
|
hwc_layer_list_t* mList;
|
||||||
|
hwc_display_t mDpy;
|
||||||
|
hwc_surface_t mSur;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
}; // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_SF_HWCOMPOSER_H
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
#include "SurfaceFlinger.h"
|
#include "SurfaceFlinger.h"
|
||||||
#include "DisplayHardware/DisplayHardware.h"
|
#include "DisplayHardware/DisplayHardware.h"
|
||||||
|
#include "DisplayHardware/HWComposer.h"
|
||||||
|
|
||||||
|
|
||||||
#define DEBUG_RESIZE 0
|
#define DEBUG_RESIZE 0
|
||||||
@@ -177,6 +178,62 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
|
|||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Layer::setGeometry(hwc_layer_t* hwcl)
|
||||||
|
{
|
||||||
|
hwcl->compositionType = HWC_FRAMEBUFFER;
|
||||||
|
hwcl->hints = 0;
|
||||||
|
hwcl->flags = 0;
|
||||||
|
hwcl->transform = 0;
|
||||||
|
hwcl->blending = HWC_BLENDING_NONE;
|
||||||
|
|
||||||
|
// we can't do alpha-fade with the hwc HAL
|
||||||
|
const State& s(drawingState());
|
||||||
|
if (s.alpha < 0xFF) {
|
||||||
|
hwcl->flags = HWC_SKIP_LAYER;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can only handle simple transformation
|
||||||
|
if (mOrientation & Transform::ROT_INVALID) {
|
||||||
|
hwcl->flags = HWC_SKIP_LAYER;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hwcl->transform = mOrientation;
|
||||||
|
|
||||||
|
if (needsBlending()) {
|
||||||
|
hwcl->blending = mPremultipliedAlpha ?
|
||||||
|
HWC_BLENDING_PREMULT : HWC_BLENDING_COVERAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hwcl->displayFrame.left = mTransformedBounds.left;
|
||||||
|
hwcl->displayFrame.top = mTransformedBounds.top;
|
||||||
|
hwcl->displayFrame.right = mTransformedBounds.right;
|
||||||
|
hwcl->displayFrame.bottom = mTransformedBounds.bottom;
|
||||||
|
|
||||||
|
hwcl->visibleRegionScreen.rects =
|
||||||
|
reinterpret_cast<hwc_rect_t const *>(
|
||||||
|
visibleRegionScreen.getArray(
|
||||||
|
&hwcl->visibleRegionScreen.numRects));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Layer::setPerFrameData(hwc_layer_t* hwcl) {
|
||||||
|
sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
|
||||||
|
if (buffer == NULL) {
|
||||||
|
// this situation can happen if we ran out of memory for instance.
|
||||||
|
// not much we can do. continue to use whatever texture was bound
|
||||||
|
// to this context.
|
||||||
|
hwcl->handle = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
hwcl->handle = const_cast<native_handle_t*>(buffer->handle);
|
||||||
|
// TODO: set the crop value properly
|
||||||
|
hwcl->sourceCrop.left = 0;
|
||||||
|
hwcl->sourceCrop.top = 0;
|
||||||
|
hwcl->sourceCrop.right = buffer->width;
|
||||||
|
hwcl->sourceCrop.bottom = buffer->height;
|
||||||
|
}
|
||||||
|
|
||||||
void Layer::reloadTexture(const Region& dirty)
|
void Layer::reloadTexture(const Region& dirty)
|
||||||
{
|
{
|
||||||
sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
|
sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ public:
|
|||||||
bool isFixedSize() const;
|
bool isFixedSize() const;
|
||||||
|
|
||||||
// LayerBase interface
|
// LayerBase interface
|
||||||
|
virtual void setGeometry(hwc_layer_t* hwcl);
|
||||||
|
virtual void setPerFrameData(hwc_layer_t* hwcl);
|
||||||
virtual void onDraw(const Region& clip) const;
|
virtual void onDraw(const Region& clip) const;
|
||||||
virtual uint32_t doTransaction(uint32_t transactionFlags);
|
virtual uint32_t doTransaction(uint32_t transactionFlags);
|
||||||
virtual void lockPageFlip(bool& recomputeVisibleRegions);
|
virtual void lockPageFlip(bool& recomputeVisibleRegions);
|
||||||
|
|||||||
@@ -307,6 +307,15 @@ void LayerBase::drawRegion(const Region& reg) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LayerBase::setGeometry(hwc_layer_t* hwcl) {
|
||||||
|
hwcl->flags |= HWC_SKIP_LAYER;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerBase::setPerFrameData(hwc_layer_t* hwcl) {
|
||||||
|
hwcl->compositionType = HWC_FRAMEBUFFER;
|
||||||
|
hwcl->handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void LayerBase::draw(const Region& clip) const
|
void LayerBase::draw(const Region& clip) const
|
||||||
{
|
{
|
||||||
// reset GL state
|
// reset GL state
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
|
|
||||||
#include <pixelflinger/pixelflinger.h>
|
#include <pixelflinger/pixelflinger.h>
|
||||||
|
|
||||||
|
#include <hardware/hwcomposer.h>
|
||||||
|
|
||||||
#include "Transform.h"
|
#include "Transform.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
@@ -108,6 +110,10 @@ public:
|
|||||||
|
|
||||||
virtual const char* getTypeId() const { return "LayerBase"; }
|
virtual const char* getTypeId() const { return "LayerBase"; }
|
||||||
|
|
||||||
|
virtual void setGeometry(hwc_layer_t* hwcl);
|
||||||
|
|
||||||
|
virtual void setPerFrameData(hwc_layer_t* hwcl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* draw - performs some global clipping optimizations
|
* draw - performs some global clipping optimizations
|
||||||
* and calls onDraw().
|
* and calls onDraw().
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#include "SurfaceFlinger.h"
|
#include "SurfaceFlinger.h"
|
||||||
|
|
||||||
#include "DisplayHardware/DisplayHardware.h"
|
#include "DisplayHardware/DisplayHardware.h"
|
||||||
|
#include "DisplayHardware/HWComposer.h"
|
||||||
|
|
||||||
/* ideally AID_GRAPHICS would be in a semi-public header
|
/* ideally AID_GRAPHICS would be in a semi-public header
|
||||||
* or there would be a way to map a user/group name to its id
|
* or there would be a way to map a user/group name to its id
|
||||||
@@ -76,6 +77,7 @@ SurfaceFlinger::SurfaceFlinger()
|
|||||||
mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
|
mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
|
||||||
mDump("android.permission.DUMP"),
|
mDump("android.permission.DUMP"),
|
||||||
mVisibleRegionsDirty(false),
|
mVisibleRegionsDirty(false),
|
||||||
|
mHwWorkListDirty(false),
|
||||||
mDeferReleaseConsole(false),
|
mDeferReleaseConsole(false),
|
||||||
mFreezeDisplay(false),
|
mFreezeDisplay(false),
|
||||||
mFreezeCount(0),
|
mFreezeCount(0),
|
||||||
@@ -368,6 +370,11 @@ bool SurfaceFlinger::threadLoop()
|
|||||||
// post surfaces (if needed)
|
// post surfaces (if needed)
|
||||||
handlePageFlip();
|
handlePageFlip();
|
||||||
|
|
||||||
|
if (UNLIKELY(mHwWorkListDirty)) {
|
||||||
|
// build the h/w work list
|
||||||
|
handleWorkList();
|
||||||
|
}
|
||||||
|
|
||||||
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
||||||
if (LIKELY(hw.canDraw() && !isFrozen())) {
|
if (LIKELY(hw.canDraw() && !isFrozen())) {
|
||||||
// repaint the framebuffer (if needed)
|
// repaint the framebuffer (if needed)
|
||||||
@@ -443,6 +450,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
|
|||||||
handleTransactionLocked(transactionFlags, ditchedLayers);
|
handleTransactionLocked(transactionFlags, ditchedLayers);
|
||||||
mLastTransactionTime = systemTime() - now;
|
mLastTransactionTime = systemTime() - now;
|
||||||
mDebugInTransaction = 0;
|
mDebugInTransaction = 0;
|
||||||
|
mHwWorkListDirty = true;
|
||||||
// here the transaction has been committed
|
// here the transaction has been committed
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,6 +458,7 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
|
|||||||
* Clean-up all layers that went away
|
* Clean-up all layers that went away
|
||||||
* (do this without the lock held)
|
* (do this without the lock held)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const size_t count = ditchedLayers.size();
|
const size_t count = ditchedLayers.size();
|
||||||
for (size_t i=0 ; i<count ; i++) {
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
if (ditchedLayers[i] != 0) {
|
if (ditchedLayers[i] != 0) {
|
||||||
@@ -683,8 +692,8 @@ void SurfaceFlinger::commitTransaction()
|
|||||||
void SurfaceFlinger::handlePageFlip()
|
void SurfaceFlinger::handlePageFlip()
|
||||||
{
|
{
|
||||||
bool visibleRegions = mVisibleRegionsDirty;
|
bool visibleRegions = mVisibleRegionsDirty;
|
||||||
LayerVector& currentLayers = const_cast<LayerVector&>(
|
LayerVector& currentLayers(
|
||||||
mDrawingState.layersSortedByZ);
|
const_cast<LayerVector&>(mDrawingState.layersSortedByZ));
|
||||||
visibleRegions |= lockPageFlip(currentLayers);
|
visibleRegions |= lockPageFlip(currentLayers);
|
||||||
|
|
||||||
const DisplayHardware& hw = graphicPlane(0).displayHardware();
|
const DisplayHardware& hw = graphicPlane(0).displayHardware();
|
||||||
@@ -707,6 +716,7 @@ void SurfaceFlinger::handlePageFlip()
|
|||||||
|
|
||||||
mWormholeRegion = screenRegion.subtract(opaqueRegion);
|
mWormholeRegion = screenRegion.subtract(opaqueRegion);
|
||||||
mVisibleRegionsDirty = false;
|
mVisibleRegionsDirty = false;
|
||||||
|
mHwWorkListDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlockPageFlip(currentLayers);
|
unlockPageFlip(currentLayers);
|
||||||
@@ -737,6 +747,21 @@ void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::handleWorkList()
|
||||||
|
{
|
||||||
|
mHwWorkListDirty = false;
|
||||||
|
HWComposer& hwc(graphicPlane(0).displayHardware().getHwComposer());
|
||||||
|
if (hwc.initCheck() == NO_ERROR) {
|
||||||
|
const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
|
||||||
|
const size_t count = currentLayers.size();
|
||||||
|
hwc.createWorkList(count);
|
||||||
|
HWComposer::iterator cur(hwc.begin());
|
||||||
|
HWComposer::iterator last(hwc.end());
|
||||||
|
for (size_t i=0 ; (i<count) && (cur!=last) ; ++i, ++cur) {
|
||||||
|
currentLayers[i]->setGeometry(cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::handleRepaint()
|
void SurfaceFlinger::handleRepaint()
|
||||||
{
|
{
|
||||||
@@ -801,15 +826,63 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
|
|||||||
// draw something...
|
// draw something...
|
||||||
drawWormhole();
|
drawWormhole();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t err = NO_ERROR;
|
||||||
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
|
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
|
||||||
const size_t count = layers.size();
|
const size_t count = layers.size();
|
||||||
|
|
||||||
|
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
||||||
|
HWComposer& hwc(hw.getHwComposer());
|
||||||
|
HWComposer::iterator cur(hwc.begin());
|
||||||
|
HWComposer::iterator last(hwc.end());
|
||||||
|
|
||||||
|
// update the per-frame h/w composer data for each layer
|
||||||
|
if (cur != last) {
|
||||||
|
for (size_t i=0 ; i<count && cur!=last ; ++i, ++cur) {
|
||||||
|
layers[i]->setPerFrameData(cur);
|
||||||
|
}
|
||||||
|
err = hwc.prepare();
|
||||||
|
LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
||||||
|
}
|
||||||
|
|
||||||
|
// and then, render the layers targeted at the framebuffer
|
||||||
|
Region transparent(hw.bounds());
|
||||||
for (size_t i=0 ; i<count ; ++i) {
|
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]);
|
const sp<LayerBase>& layer(layers[i]);
|
||||||
|
transparent.subtractSelf(layer->visibleRegionScreen);
|
||||||
const Region clip(dirty.intersect(layer->visibleRegionScreen));
|
const Region clip(dirty.intersect(layer->visibleRegionScreen));
|
||||||
if (!clip.isEmpty()) {
|
if (!clip.isEmpty()) {
|
||||||
layer->draw(clip);
|
layer->draw(clip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// finally clear everything we didn't draw as a result of calling
|
||||||
|
// prepare (this leaves the FB transparent).
|
||||||
|
transparent.andSelf(dirty);
|
||||||
|
if (!transparent.isEmpty()) {
|
||||||
|
glClearColor(0,0,0,0);
|
||||||
|
Region::const_iterator it = transparent.begin();
|
||||||
|
Region::const_iterator const end = transparent.end();
|
||||||
|
const int32_t height = hw.getHeight();
|
||||||
|
while (it != end) {
|
||||||
|
const Rect& r(*it++);
|
||||||
|
const GLint sy = height - (r.top + r.height());
|
||||||
|
glScissor(r.left, sy, r.width(), r.height());
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::unlockClients()
|
void SurfaceFlinger::unlockClients()
|
||||||
|
|||||||
@@ -296,6 +296,7 @@ private:
|
|||||||
void handlePageFlip();
|
void handlePageFlip();
|
||||||
bool lockPageFlip(const LayerVector& currentLayers);
|
bool lockPageFlip(const LayerVector& currentLayers);
|
||||||
void unlockPageFlip(const LayerVector& currentLayers);
|
void unlockPageFlip(const LayerVector& currentLayers);
|
||||||
|
void handleWorkList();
|
||||||
void handleRepaint();
|
void handleRepaint();
|
||||||
void postFramebuffer();
|
void postFramebuffer();
|
||||||
void composeSurfaces(const Region& dirty);
|
void composeSurfaces(const Region& dirty);
|
||||||
@@ -370,6 +371,7 @@ private:
|
|||||||
Region mInvalidRegion;
|
Region mInvalidRegion;
|
||||||
Region mWormholeRegion;
|
Region mWormholeRegion;
|
||||||
bool mVisibleRegionsDirty;
|
bool mVisibleRegionsDirty;
|
||||||
|
bool mHwWorkListDirty;
|
||||||
bool mDeferReleaseConsole;
|
bool mDeferReleaseConsole;
|
||||||
bool mFreezeDisplay;
|
bool mFreezeDisplay;
|
||||||
int32_t mFreezeCount;
|
int32_t mFreezeCount;
|
||||||
|
|||||||
Reference in New Issue
Block a user