Surface
SurfaceControl surface控制
SurfaceSession surface 会话类,维护
android/frameworks/base/core/java/android/view/Surface.java
public class Surface implements Parcelable {
private static final String TAG = "Surface";
....
private static native long nativeCreateFromSurfaceControl(long surfaceControlNativeObject);
private static native long nativeGetFromSurfaceControl(long surfaceControlNativeObject);
private static native long nativeLockCanvas(long nativeObject, Canvas canvas, Rect dirty)
throws OutOfResourcesException;
private static native void nativeUnlockCanvasAndPost(long nativeObject, Canvas canvas);
private static native boolean nativeIsValid(long nativeObject);
private static native void nativeAllocateBuffers(long nativeObject);
private static native int nativeGetWidth(long nativeObject);
private static native int nativeGetHeight(long nativeObject);
private static native long nativeGetNextFrameNumber(long nativeObject);
private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer);
private final CloseGuard mCloseGuard = CloseGuard.get();
final Object mLock = new Object(); // protects the native state
private String mName;
// 这个就可以说是 java surface 最关键的一个东西
long mNativeObject; // package scope only for SurfaceControl access
private final Canvas mCanvas = new CompatibleCanvas();
public Canvas lockCanvas(Rect inOutDirty) throws Surface.OutOfResourcesException, IllegalArgumentException {
....
mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty);
return mCanvas;
}
}
private void unlockSwCanvasAndPost(Canvas canvas) {
......
nativeUnlockCanvasAndPost(mLockedObject, canvas);
} finally {
nativeRelease(mLockedObject);
mLockedObject = 0;
}
}
public Surface(SurfaceTexture surfaceTexture) {
...
mName = surfaceTexture.toString();
setNativeObjectLocked(nativeCreateFromSurfaceTexture(surfaceTexture));
}
}
public void createFrom(SurfaceControl other) {
....
long surfaceControlPtr = other.mNativeObject;
long newNativeObject = nativeCreateFromSurfaceControl(surfaceControlPtr);
....
setNativeObjectLocked(newNativeObject);
}
}
private void setNativeObjectLocked(long ptr) {
if (mNativeObject != ptr) {
....
mNativeObject = ptr;
....
}
}
...
}
frameworks/base/core/java/android/view/SurfaceSession.java
surface session创建时,绑定的是 C 的 SurfaceComposerClient Surface合成器
public final class SurfaceSession {
//Note: This field is accessed by native code.privatelongmNativeClient; // SurfaceComposerClient*
private static native long nativeCreate();
private static native long nativeCreateScoped(longsurfacePtr);
private static native void nativeDestroy(longptr);
private static native void nativeKill(longptr);
/** Create a new connection with the surface flinger. */
publicSurfaceSession() {
mNativeClient = nativeCreate();
}
publicSurfaceSession(Surfaceroot) {
mNativeClient = nativeCreateScoped(root.mNativeObject);
}
/* no user serviceable parts here ... */
@Overrideprotectedvoidfinalize() throwsThrowable {
try {
if (mNativeClient != 0) {
nativeDestroy(mNativeClient);
}
} finally {
super.finalize();
}
}
/**
* Forcibly detach native resources associated with this object.
* Unlike destroy(), after this call any surfaces that were created
* from the session will no longer work.
*/publicvoidkill() {
nativeKill(mNativeClient);
}
}
android/frameworks/base/core/java/android/view/SurfaceControl.java
public final class SurfaceControl implements Parcelable {
private static final String TAG = "SurfaceControl";
}
JNI 层
android/frameworks/base/core/jni/android_view_Surface.cpp
#define LOG_TAG "Surface"
#include <stdio.h>
namespace android {
static const char* const OutOfResourcesException =
"android/view/Surface$OutOfResourcesException";
static struct {
jclass clazz;
jfieldID mNativeObject;
jfieldID mLock;
jmethodID ctor;
} gSurfaceClassInfo;
static struct {
jfieldID left;
jfieldID top;
jfieldID right;
jfieldID bottom;
} gRectClassInfo;
static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
if (!isSurfaceValid(surface)) {
doThrowIAE(env);
return 0;
}
if (convertPixelFormat(ANativeWindow_getFormat(surface.get())) == kUnknown_SkColorType) {
native_window_set_buffers_format(surface.get(), PIXEL_FORMAT_RGBA_8888);
}
Rect dirtyRect(Rect::EMPTY_RECT);
Rect* dirtyRectPtr = NULL;
if (dirtyRectObj) {
dirtyRect.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
dirtyRect.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
dirtyRect.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
dirtyRect.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
dirtyRectPtr = &dirtyRect;
}
ANativeWindow_Buffer outBuffer;
status_t err = surface->lock(&outBuffer, dirtyRectPtr);
if (err < 0) {
const char* const exception = (err == NO_MEMORY) ?
OutOfResourcesException :
"java/lang/IllegalArgumentException";
jniThrowException(env, exception, NULL);
return 0;
}
SkImageInfo info = SkImageInfo::Make(outBuffer.width, outBuffer.height,
convertPixelFormat(outBuffer.format),
outBuffer.format == PIXEL_FORMAT_RGBX_8888
? kOpaque_SkAlphaType : kPremul_SkAlphaType);
SkBitmap bitmap;
ssize_t bpr = outBuffer.stride * bytesPerPixel(outBuffer.format);
bitmap.setInfo(info, bpr);
if (outBuffer.width > 0 && outBuffer.height > 0) {
bitmap.setPixels(outBuffer.bits);
} else {
// be safe with an empty bitmap.
bitmap.setPixels(NULL);
}
Canvas* nativeCanvas = GraphicsJNI::getNativeCanvas(env, canvasObj);
nativeCanvas->setBitmap(bitmap);
if (dirtyRectPtr) {
nativeCanvas->clipRect(dirtyRect.left, dirtyRect.top,
dirtyRect.right, dirtyRect.bottom, SkClipOp::kIntersect);
}
if (dirtyRectObj) {
env->SetIntField(dirtyRectObj, gRectClassInfo.left, dirtyRect.left);
env->SetIntField(dirtyRectObj, gRectClassInfo.top, dirtyRect.top);
env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right);
env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom);
}
// Create another reference to the surface and return it. This reference
// should be passed to nativeUnlockCanvasAndPost in place of mNativeObject,
// because the latter could be replaced while the surface is locked.
sp<Surface> lockedSurface(surface);
lockedSurface->incStrong(&sRefBaseOwner);
return (jlong) lockedSurface.get();
}
}
C Surface
framework/native/libs/gui
Surface.cpp
SurfaceComposerClient.cpp
SurfaceControl.cpp
ISurfaceComposerClient.cpp
BufferQueue.cpp
ISurfaceComposer.cpp
/AOSP/frameworks/native/libs/ui
GraphicBufferAllocator.cpp
GraphicBuffer.cpp
GraphicBufferMapper.cpp
FrameBufferNativeWindow.cpp
FrameSatatus.cpp
Rect.cpp
Region.cpp
UiConfig.cpp
GraphicBufferAllocator 通过hw_get_module()&gralloc_open与硬件提供的设备交互
ex: /hardware/qcom/display/libgralloc/alloc_controller.cpp etc.
/AOSP/frameworks/native/libs/gui
IGraphicBufferAlloc.cpp
IGraphicBufferConsumer.cpp
IGraphicBufferProducer.cpp
BufferQueueConsumer.cpp
BufferQueueCore.cpp
BufferQueue.cpp ISurfaceComposerClient.cpp
BufferQueueProducer.cpp ISurfaceComposer.cpp
BufferSlot.cpp LayerState.cpp
GLConsumer.cpp SurfaceComposerClient.cpp
GraphicBufferAlloc.cpp SurfaceControl.cpp
GuiConfig.cpp Surface.cpp
SurfaceComposerClient 中成员变量 sp<ISurfaceComposerClient> mClient;与surface.cpp binder通信
/AOSP/frameworks/native/services/surfaceflinger
surfaceflinger.rc SurfaceFlingerConsumer.cpp
FrameTracker.cpp SurfaceFlingerConsumer.h
FrameTracker.h SurfaceFlinger.cpp
Layer.cpp SurfaceFlinger.h
DisplayDevice.cpp LayerDim.cpp
DisplayDevice.h LayerDim.h
DisplayHardware Layer.h
DispSync.cpp main_surfaceflinger.cpp
DispSync.h MessageQueue.cpp MessageQueue.h
surfaceflinger管理surface及layer
AOSP/frameworks/base/core/java/android/view
Display.aidl Display.java
DisplayInfo.aidl DisplayInfo.java
Surface.aidl Surface.java
SurfaceControl.java
SurfaceHolder.java
SurfaceSession.java
SurfaceView.java
TextureView.java
GraphicBuffer.aidl
GraphicBuffer.java
ViewRootImpl.java
WindowId.java WindowInfo.aidl
IWindow.aidl WindowInfo.java
IWindowFocusObserver.aidl WindowInsets.java
IWindowId.aidl Window.java
IWindowManager.aidl WindowManager.aidl WindowManager.java
IWindowSession.aidl WindowManagerGlobal.java
IWindowSessionCallback.aidl WindowManagerImpl.java
WindowManagerPolicy.java