此为SurfaceFlinger一个系列文章,旨在通过研读SurfaceFlinger源码弄清楚SF整个业务流程。好吧,废话不多说,SF相关代码位置
还是从类继承关系来看看吧。
class SurfaceFlinger : public BnSurfaceComposer,
private IBinder::DeathRecipient,
#ifdef USE_HWC2
private HWC2::ComposerCallback
#else
private HWComposer::EventHandler
#endif
首先继承了BnSurfaceComposer。其次根据USE_HWC2是否定义,回调有两种实现。先来看看BnSurfaceComposer。如下可以看到这个实际是一个服务端的实现。从枚举类型可以看出,大部分关于UI的操作确实都是SF这块来处理了。所以有必要还是看看到底有那些枚举。
class BnSurfaceComposer: public BnInterface<ISurfaceComposer> {
public:
enum {
// Note: BOOT_FINISHED must remain this value, it is called from
// Java by ActivityManagerService.
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
CREATE_CONNECTION,
UNUSED, // formerly CREATE_GRAPHIC_BUFFER_ALLOC
CREATE_DISPLAY_EVENT_CONNECTION,
CREATE_DISPLAY,
DESTROY_DISPLAY,
GET_BUILT_IN_DISPLAY,
SET_TRANSACTION_STATE,
AUTHENTICATE_SURFACE,
GET_SUPPORTED_FRAME_TIMESTAMPS,
GET_DISPLAY_CONFIGS,
GET_ACTIVE_CONFIG,
SET_ACTIVE_CONFIG,
CONNECT_DISPLAY,
CAPTURE_SCREEN,
CLEAR_ANIMATION_FRAME_STATS,
GET_ANIMATION_FRAME_STATS,
SET_POWER_MODE,
GET_DISPLAY_STATS,
GET_HDR_CAPABILITIES,
GET_DISPLAY_COLOR_MODES,
GET_ACTIVE_COLOR_MODE,
SET_ACTIVE_COLOR_MODE,
ENABLE_VSYNC_INJECTIONS,
INJECT_VSYNC,
CREATE_SCOPED_CONNECTION
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);
};
好了开始看构造方法。初始构造方法主要是初始化了一些变量,并没有调用什么方法。这里着重看下。
void SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
此方法在文章Looper源代码解析<一>已经分析过了。接下来看下提供了哪些服务。
在分析SF的onTransact之前,我们先来分析基类ISurfaceComposer.cpp中的BnSurfaceComposer::onTransact。因为我们随后能够看到SF中onTransact的业务首先是委托给基类来使用。所以我们可以了解到sf的功能进一步委托拆解到了BnSurfaceCompose.
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
//创建连接,使之App需要跟sf创建一条连接。createConnection()稍后分析。
case CREATE_CONNECTION: {
sp<IBinder> b = IInterface::asBinder(createConnection());
//回复给客户端。
reply->writeStrongBinder(b);
return NO_ERROR;
}
//如上差别不大。
case CREATE_SCOPED_CONNECTION: {
sp<IGraphicBufferProducer> bufferProducer =
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
sp<IBinder> b = IInterface::asBinder(createScopedConnection(bufferProducer));
reply->writeStrongBinder(b);
return NO_ERROR;
}
//设置事务的状态。
case SET_TRANSACTION_STATE: {
size_t count = data.readUint32();
if (count > data.dataSize()) {
return BAD_VALUE;
}
ComposerState s;
//实际是ComposerState,暂时不分析这个是啥结构。后续再慢慢展开。
Vector<ComposerState> state;
state.setCapacity(count);
for (size_t i = 0; i < count; i++) {
if (s.read(data) == BAD_VALUE) {
return BAD_VALUE;
}
state.add(s);
}
count = data.readUint32();
if (count > data.dataSize()) {
return BAD_VALUE;
}
DisplayState d;
Vector<DisplayState> displays;
displays.setCapacity(count);
for (size_t i = 0; i < count; i++) {
if (d.read(data) == BAD_VALUE) {
return BAD_VALUE;
}
displays.add(d);
}
uint32_t stateFlags = data.readUint32();
//此方法会跟远程服务端做一次交互。
setTransactionState(state, displays, stateFlags);
return NO_ERROR;
}
case BOOT_FINISHED: {
//告诉远端服务开机结束了。
bootFinished();
return NO_ERROR;
}
//截屏
case CAPTURE_SCREEN: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder();
sp<IGraphicBufferProducer> producer =
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
Rect sourceCrop(Rect::EMPTY_RECT);
data.read(sourceCrop);
uint32_t reqWidth = data.readUint32();
uint32_t reqHeight = data.readUint32();
int32_t minLayerZ = data.readInt32();
int32_t maxLayerZ = data.readInt32();
bool useIdentityTransform = static_cast<bool>(data.readInt32());
int32_t rotation = data.readInt32();
//再次给SF处理。
status_t res = captureScreen(display, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
useIdentityTransform,
static_cast<ISurfaceComposer::Rotation>(rotation));
reply->writeInt32(res);
return NO_ERROR;
}
case AUTHENTICATE_SURFACE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IGraphicBufferProducer> bufferProducer =
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
int32_t result = authenticateSurfaceTexture(bufferProducer) ? 1 : 0;
reply->writeInt32(result);
return NO_ERROR;
}
case GET_SUPPORTED_FRAME_TIMESTAMPS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
std::vector<FrameEvent> supportedTimestamps;
status_t result = getSupportedFrameTimestamps(&supportedTimestamps);
status_t err = reply->writeInt32(result);
if (err != NO_ERROR) {
return err;
}
if (result != NO_ERROR) {
return result;
}
std::vector<int32_t> supported;
supported.reserve(supportedTimestamps.size());
for (FrameEvent s : supportedTimestamps) {
supported.push_back(static_cast<int32_t>(s));
}
return reply->writeInt32Vector(supported);
}
case CREATE_DISPLAY_EVENT_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IDisplayEventConnection> connection(createDisplayEventConnection(
static_cast<ISurfaceComposer::VsyncSource>(data.readInt32())));
reply->writeStrongBinder(IInterface::asBinder(connection));
return NO_ERROR;
}
case CREATE_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
String8 displayName = data.readString8();
bool secure = bool(data.readInt32());
sp<IBinder> display(createDisplay(displayName, secure));
reply->writeStrongBinder(display);
return NO_ERROR;
}
case DESTROY_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder();
destroyDisplay(display);
return NO_ERROR;
}
case GET_BUILT_IN_DISPLAY: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
int32_t id = data.readInt32();
sp<IBinder> display(getBuiltInDisplay(id));
reply->writeStrongBinder(display);
return NO_ERROR;
}
case GET_DISPLAY_CONFIGS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
Vector<DisplayInfo> configs;
sp<IBinder> display = data.readStrongBinder();
status_t result = getDisplayConfigs(display, &configs);
reply->writeInt32(result);
if (result == NO_ERROR) {
reply->writeUint32(static_cast<uint32_t>(configs.size()));
for (size_t c = 0; c < configs.size(); ++c) {
memcpy(reply->writeInplace(sizeof(DisplayInfo)),
&configs[c], sizeof(DisplayInfo));
}
}
return NO_ERROR;
}
case GET_DISPLAY_STATS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
DisplayStatInfo stats;
sp<IBinder> display = data.readStrongBinder();
status_t result = getDisplayStats(display, &stats);
reply->writeInt32(result);
if (result == NO_ERROR) {
memcpy(reply->writeInplace(sizeof(DisplayStatInfo)),
&stats, sizeof(DisplayStatInfo));
}
return NO_ERROR;
}
case GET_ACTIVE_CONFIG: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder();
int id = getActiveConfig(display);
reply->writeInt32(id);
return NO_ERROR;
}
case SET_ACTIVE_CONFIG: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder();
int id = data.readInt32();
status_t result = setActiveConfig(display, id);
reply->writeInt32(result);
return NO_ERROR;
}
case GET_DISPLAY_COLOR_MODES: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
Vector<android_color_mode_t> colorModes;
sp<IBinder> display = nullptr;
status_t result = data.readStrongBinder(&display);
if (result != NO_ERROR) {
ALOGE("getDisplayColorModes failed to readStrongBinder: %d", result);
return result;
}
result = getDisplayColorModes(display, &colorModes);
reply->writeInt32(result);
if (result == NO_ERROR) {
reply->writeUint32(static_cast<uint32_t>(colorModes.size()));
for (size_t i = 0; i < colorModes.size(); ++i) {
reply->writeInt32(colorModes[i]);
}
}
return NO_ERROR;
}
case GET_ACTIVE_COLOR_MODE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = nullptr;
status_t result = data.readStrongBinder(&display);
if (result != NO_ERROR) {
ALOGE("getActiveColorMode failed to readStrongBinder: %d", result);
return result;
}
android_color_mode_t colorMode = getActiveColorMode(display);
result = reply->writeInt32(static_cast<int32_t>(colorMode));
return result;
}
case SET_ACTIVE_COLOR_MODE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = nullptr;
status_t result = data.readStrongBinder(&display);
if (result != NO_ERROR) {
ALOGE("getActiveColorMode failed to readStrongBinder: %d", result);
return result;
}
int32_t colorModeInt = 0;
result = data.readInt32(&colorModeInt);
if (result != NO_ERROR) {
ALOGE("setActiveColorMode failed to readInt32: %d", result);
return result;
}
result = setActiveColorMode(display,
static_cast<android_color_mode_t>(colorModeInt));
result = reply->writeInt32(result);
return result;
}
case CLEAR_ANIMATION_FRAME_STATS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
status_t result = clearAnimationFrameStats();
reply->writeInt32(result);
return NO_ERROR;
}
case GET_ANIMATION_FRAME_STATS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
FrameStats stats;
status_t result = getAnimationFrameStats(&stats);
reply->write(stats);
reply->writeInt32(result);
return NO_ERROR;
}
case SET_POWER_MODE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = data.readStrongBinder();
int32_t mode = data.readInt32();
setPowerMode(display, mode);
return NO_ERROR;
}
case GET_HDR_CAPABILITIES: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IBinder> display = nullptr;
status_t result = data.readStrongBinder(&display);
if (result != NO_ERROR) {
ALOGE("getHdrCapabilities failed to readStrongBinder: %d",
result);
return result;
}
HdrCapabilities capabilities;
result = getHdrCapabilities(display, &capabilities);
reply->writeInt32(result);
if (result == NO_ERROR) {
reply->write(capabilities);
}
return NO_ERROR;
}
case ENABLE_VSYNC_INJECTIONS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
bool enable = false;
status_t result = data.readBool(&enable);
if (result != NO_ERROR) {
ALOGE("enableVSyncInjections failed to readBool: %d", result);
return result;
}
return enableVSyncInjections(enable);
}
case INJECT_VSYNC: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
int64_t when = 0;
status_t result = data.readInt64(&when);
if (result != NO_ERROR) {
ALOGE("enableVSyncInjections failed to readInt64: %d", result);
return result;
}
return injectVSync(when);
}
default: {
return BBinder::onTransact(code, data, reply, flags);
}
}
}
在这一些列服务中有些是自己处理有些还需要进一步提交了。还是从captureScreen 截屏这个来针对性分析一下。还是从我们看到实际调用父类的captureScreen ,可以看到SF首先给到BnSurfaceComposer 调用,然后BSC又给到了SF调用。
status_t SurfaceFlinger::captureScreen(const sp<IBinder>& display,
const sp<IGraphicBufferProducer>& producer,
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
// if we have secure windows on this display, never allow the screen capture
// unless the producer interface is local (i.e.: we can take a screenshot for
// ourselves).
bool isLocalScreenshot = IInterface::asBinder(producer)->localBinder();
Transform::orientation_flags rotationFlags;
//判断旋转
switch (rotation) {
case ISurfaceComposer::eRotateNone:
rotationFlags = Transform::ROT_0;
break;
case ISurfaceComposer::eRotate90:
rotationFlags = Transform::ROT_90;
break;
case ISurfaceComposer::eRotate180:
rotationFlags = Transform::ROT_180;
break;
case ISurfaceComposer::eRotate270:
rotationFlags = Transform::ROT_270;
break;
default:
rotationFlags = Transform::ROT_0;
ALOGE("Invalid rotation passed to captureScreen(): %d\n", rotation);
break;
}
{ // Autolock scope
Mutex::Autolock lock(mStateLock);
sp<const DisplayDevice> displayDevice(getDisplayDeviceLocked(display));
updateDimensionsLocked(displayDevice, rotationFlags, &reqWidth, &reqHeight);
}
//创建一个Surface
sp<Surface> surface = new Surface(producer, false);
// Put the screenshot Surface into async mode so that
// Layer::headFenceHasSignaled will always return true and we'll latch the
// first buffer regardless of whether or not its acquire fence has
// signaled. This is needed to avoid a race condition in the rotation
// animation. See b/30209608
surface->setAsyncMode(true);
//获取本地屏幕
ANativeWindow* window = surface.get();
status_t result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
if (result != NO_ERROR) {
return result;
}
WindowDisconnector disconnector(window, NATIVE_WINDOW_API_EGL);
ANativeWindowBuffer* buffer = nullptr;
//buffer就是实际存储像素的位置。
result = getWindowBuffer(window, reqWidth, reqHeight,
hasWideColorDisplay && !mForceNativeColorMode,
getRenderEngine().usesWideColor(), &buffer);
if (result != NO_ERROR) {
return result;
}
std::mutex captureMutex;
std::condition_variable captureCondition;
std::unique_lock<std::mutex> captureLock(captureMutex);
int syncFd = -1;
std::optional<status_t> captureResult;
sp<LambdaMessage> message = new LambdaMessage([&]() {
// If there is a refresh pending, bug out early and tell the binder thread to try again
// after the refresh.
if (mRefreshPending) {
ATRACE_NAME("Skipping screenshot for now");
std::unique_lock<std::mutex> captureLock(captureMutex);
captureResult = std::make_optional<status_t>(EAGAIN);
captureCondition.notify_one();
return;
}
status_t result = NO_ERROR;
int fd = -1;
{
Mutex::Autolock _l(mStateLock);
sp<const DisplayDevice> device(getDisplayDeviceLocked(display));
result = captureScreenImplLocked(device, buffer, sourceCrop, reqWidth, reqHeight,
minLayerZ, maxLayerZ, useIdentityTransform,
rotationFlags, isLocalScreenshot, &fd);
}
{
std::unique_lock<std::mutex> captureLock(captureMutex);
syncFd = fd;
captureResult = std::make_optional<status_t>(result);
captureCondition.notify_one();
}
});
//此处正是把上述message投递到MQ,进行Looper处理。
result = postMessageAsync(message);
if (result == NO_ERROR) {
//等待方法执行。如果方法成功执行会唤醒这把锁。那么截屏的逻辑就是在message里面了。
captureCondition.wait(captureLock, [&]() { return captureResult; });
while (*captureResult == EAGAIN) {
captureResult.reset();
result = postMessageAsync(message);
if (result != NO_ERROR) {
return result;
}
captureCondition.wait(captureLock, [&]() { return captureResult; });
}
result = *captureResult;
}
if (result == NO_ERROR) {
// queueBuffer takes ownership of syncFd
result = window->queueBuffer(window, buffer, syncFd);
}
return result;
}
接下来看下消息中的captureScreenImplLocked。此方法细节比较多,后续我单开一篇来分析。
status_t SurfaceFlinger::captureScreenImplLocked(const sp<const DisplayDevice>& hw,
ANativeWindowBuffer* buffer, Rect sourceCrop,
uint32_t reqWidth, uint32_t reqHeight,
int32_t minLayerZ, int32_t maxLayerZ,
bool useIdentityTransform,
Transform::orientation_flags rotation,
bool isLocalScreenshot, int* outSyncFd) {
bool secureLayerIsVisible = false;
for (const auto& layer : mDrawingState.layersSortedByZ) {
const Layer::State& state(layer->getDrawingState());
if (!layer->belongsToDisplay(hw->getLayerStack(), false) ||
(state.z < minLayerZ || state.z > maxLayerZ)) {
continue;
}
layer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer *layer) {
secureLayerIsVisible = secureLayerIsVisible || (layer->isVisible() &&
layer->isSecure());
});
}
int syncFd = -1;
// create an EGLImage from the buffer so we can later
// turn it into a texture
EGLImageKHR image = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT,
EGL_NATIVE_BUFFER_ANDROID, buffer, NULL);
// This will automatically destroy the image if we return before calling its destroy method
ImageHolder imageHolder(mEGLDisplay, image);
// this binds the given EGLImage as a framebuffer for the
// duration of this scope.
RenderEngine::BindImageAsFramebuffer imageBond(getRenderEngine(), image);
// 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
// dependent on the context's EGLConfig.
renderScreenImplLocked(
hw, sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ, true,
useIdentityTransform, rotation);
EGLSyncKHR sync = EGL_NO_SYNC_KHR;
if (!DEBUG_SCREENSHOTS) {
sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
// native fence fd will not be populated until flush() is done.
getRenderEngine().flush();
}
if (sync != EGL_NO_SYNC_KHR) {
// get the sync fd
syncFd = eglDupNativeFenceFDANDROID(mEGLDisplay, sync);
if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
ALOGW("captureScreen: failed to dup sync khr object");
syncFd = -1;
}
eglDestroySyncKHR(mEGLDisplay, sync);
} else {
// fallback path
sync = eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, NULL);
if (sync != EGL_NO_SYNC_KHR) {
EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync,
EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, 2000000000 /*2 sec*/);
EGLint eglErr = eglGetError();
if (result == EGL_TIMEOUT_EXPIRED_KHR) {
ALOGW("captureScreen: fence wait timed out");
} else {
ALOGW_IF(eglErr != EGL_SUCCESS,
"captureScreen: error waiting on EGL fence: %#x", eglErr);
}
eglDestroySyncKHR(mEGLDisplay, sync);
} else {
ALOGW("captureScreen: error creating EGL fence: %#x", eglGetError());
}
}
*outSyncFd = syncFd;
// destroy our image
imageHolder.destroy();
return NO_ERROR;
}
接下来看下SF 自身的onTransact方法。
status_t SurfaceFlinger::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
//首先检查下code是否支持。就看是否符合上述enum的服务类型。
status_t credentialCheck = CheckTransactCodeCredentials(code);
if (credentialCheck != OK) {
return credentialCheck;
}
//首先交给了BnSurfaceComposer处理。这个上面已经有过分析了。
status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
IPCThreadState* ipc = IPCThreadState::self();
const int uid = ipc->getCallingUid();
if (CC_UNLIKELY(uid != AID_SYSTEM
&& !PermissionCache::checkCallingPermission(sHardwareTest))) {
const int pid = ipc->getCallingPid();
ALOGE("Permission Denial: "
"can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
}
int n;
switch (code) {
case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
return NO_ERROR;
case 1002: // SHOW_UPDATES
n = data.readInt32();
mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
case 1004:{ // repaint everything
repaintEverything();
return NO_ERROR;
}
case 1005:{ // force transaction
Mutex::Autolock _l(mStateLock);
setTransactionFlags(
eTransactionNeeded|
eDisplayTransactionNeeded|
eTraversalNeeded);
return NO_ERROR;
}
case 1006:{ // send empty update
signalRefresh();
return NO_ERROR;
}
case 1008: // toggle use of hw composer
n = data.readInt32();
mDebugDisableHWC = n ? 1 : 0;
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
case 1009: // toggle use of transform hint
n = data.readInt32();
mDebugDisableTransformHint = n ? 1 : 0;
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
case 1010: // interrogate.
reply->writeInt32(0);
reply->writeInt32(0);
reply->writeInt32(mDebugRegion);
reply->writeInt32(0);
reply->writeInt32(mDebugDisableHWC);
return NO_ERROR;
case 1013: {
sp<const DisplayDevice> hw(getDefaultDisplayDevice());
reply->writeInt32(hw->getPageFlipCount());
return NO_ERROR;
}
case 1014: {
// daltonize
n = data.readInt32();
switch (n % 10) {
case 1:
mDaltonizer.setType(ColorBlindnessType::Protanomaly);
break;
case 2:
mDaltonizer.setType(ColorBlindnessType::Deuteranomaly);
break;
case 3:
mDaltonizer.setType(ColorBlindnessType::Tritanomaly);
break;
default:
mDaltonizer.setType(ColorBlindnessType::None);
break;
}
if (n >= 10) {
mDaltonizer.setMode(ColorBlindnessMode::Correction);
} else {
mDaltonizer.setMode(ColorBlindnessMode::Simulation);
}
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
}
case 1015: {
// apply a color matrix
n = data.readInt32();
if (n) {
// color matrix is sent as a column-major mat4 matrix
for (size_t i = 0 ; i < 4; i++) {
for (size_t j = 0; j < 4; j++) {
mColorMatrix[i][j] = data.readFloat();
}
}
} else {
mColorMatrix = mat4();
}
// Check that supplied matrix's last row is {0,0,0,1} so we can avoid
// the division by w in the fragment shader
float4 lastRow(transpose(mColorMatrix)[3]);
if (any(greaterThan(abs(lastRow - float4{0, 0, 0, 1}), float4{1e-4f}))) {
ALOGE("The color transform's last row must be (0, 0, 0, 1)");
}
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
}
// This is an experimental interface
// Needs to be shifted to proper binder interface when we productize
case 1016: {
n = data.readInt32();
mPrimaryDispSync.setRefreshSkipCount(n);
return NO_ERROR;
}
case 1017: {
n = data.readInt32();
mForceFullDamage = static_cast<bool>(n);
return NO_ERROR;
}
case 1018: { // Modify Choreographer's phase offset
n = data.readInt32();
mEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
return NO_ERROR;
}
case 1019: { // Modify SurfaceFlinger's phase offset
n = data.readInt32();
mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
return NO_ERROR;
}
case 1020: { // Layer updates interceptor
n = data.readInt32();
if (n) {
ALOGV("Interceptor enabled");
mInterceptor.enable(mDrawingState.layersSortedByZ, mDrawingState.displays);
}
else{
ALOGV("Interceptor disabled");
mInterceptor.disable();
}
return NO_ERROR;
}
case 1021: { // Disable HWC virtual displays
n = data.readInt32();
mUseHwcVirtualDisplays = !n;
return NO_ERROR;
}
case 1022: { // Set saturation boost
mSaturation = std::max(0.0f, std::min(data.readFloat(), 2.0f));
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
}
case 1023: { // Set native mode
mForceNativeColorMode = data.readInt32() == 1;
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
}
case 1024: { // Is wide color gamut rendering/color management supported?
reply->writeBool(hasWideColorDisplay);
return NO_ERROR;
}
}
}
return err;
}
以上具体的获取截屏的方法单开一篇来分析,上述文章只是为了清理下主要逻辑,以求对SF有一个整体的认知。通过从整体到细节的方式逐步了解SF。现在整体回顾下分析过程。
1.SF构造主要是初始化了messagQue,进行通过一个死循环,使SF的消息机制运行起来。
2.由于SF作为一个服务端,我们从它的onTransaction来分析。这里是客户端提交服务的起点。通过分析知道SF在调用onTransation的时候,会首先调用其父类也就是BnSurfaceComposer的onTransaction。
3.通过captureScreen 分析可知,最终的实现逻辑还是在SF中的captureScreenImplLocked。这个方法后续进一步分析。