




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、skia庫Skia庫是一個(gè)外部庫,代碼位于external/skia/下面,生成的庫名稱是libskia.so。Skia庫負(fù)責(zé)2維圖形的繪制,繪制的結(jié)果最終一般以位圖的形式存放在內(nèi)存的一塊緩沖區(qū)中。我們可以從它里面幾個(gè)比較重要的類來了解它到底完成什么功能。使用SkCanvas,可以將繪制(drawing)結(jié)果保存到一個(gè)設(shè)備如位圖(bitmap)中,這些繪制操作包含一系列幾何圖形的繪制,如繪制點(diǎn)、線、矩形、多邊形、橢圓和圓弧等幾何圖形。Canvas.cpp調(diào)用了skia庫的API,有的調(diào)用僅僅是對SkCanvas的簡單包裹。繪制的狀態(tài)(State)封裝在Paint類中,如繪制的線條粗細(xì)、線條顏色
2、、區(qū)域如何填充、線條形狀等。SkBitmap是光柵位圖,它包含高度和寬度兩個(gè)整數(shù)以及格式(配置config規(guī)定),也可以通過getAddr()獲取存儲(chǔ)實(shí)際像素(pixel)塊的地址。一副圖形可以通過它的像素位圖來保存,也可以通過保存它的繪制過程通過SkPicture保存起來,然后寫到文件里,最后通過繪制過程恢復(fù)圖形。另外,skia也包括將YUV格式轉(zhuǎn)變?yōu)镴pg的編碼,見YuvToJpegEncoder.cpp。Java部分通過JNI調(diào)用Skia關(guān)系如下,包括但不限于下圖中的四個(gè)類。庫libsurfaceflinger_client.so庫libsurfaceflinger_client.so鏈
3、接到應(yīng)用程序中,也鏈接到server側(cè)(主要因?yàn)閘ayer state管理和內(nèi)存控制塊等類),因此,其大多數(shù)類運(yùn)行在應(yīng)用程序所在進(jìn)程空間中,它通過Binder與與進(jìn)程sufaceflinger進(jìn)行交互。它的代碼位于frameworks/base/libs/surfaceflinger_client下面,SurfaceComposerClient/SurfaceControl如JNI層章節(jié)所述,在創(chuàng)建SurfaceSession(Java)時(shí),會(huì)創(chuàng)建SurfaceComposerClient對象,并將SurfaceComposerClient對象指針保存到SurfaceSession(Java)
4、的mClient中。我們來看下創(chuàng)建SurfaceComposerClient對象時(shí)還發(fā)生了什么?SurfaceComposerClient繼承自RefBase,所以在第一次初始化時(shí),會(huì)執(zhí)行其重載的onFirstRef。在onFirstRef中,會(huì)獲取Composer Service,也就是SurfaceFlinger在client側(cè)的binder-ISurfaceComposer,接著使用它建立client connection連接(實(shí)際上是分配一個(gè)用于兩側(cè)通訊的共享內(nèi)存塊),獲取ISurfaceComposerClient,最后創(chuàng)建layer_state_t,保存窗口狀態(tài),用于兩側(cè)的窗口狀態(tài)
5、通訊。SurfaceComposerClient可以加入到列表中由Composer來維護(hù)。SurfaceControl對象指針保存在Surface(Java)中的mSurfaceControl。SurfaceControl借助于SurfaceComposerClient,實(shí)現(xiàn)對UI控件的一些操作:· show/hide: 顯示隱藏操作 · setSize/setPosition: 設(shè)置大小和位置 · SetLayer:設(shè)置圖層 · freeze/unfreeze:凍結(jié)與去凍結(jié)操作,即是否更新屏幕 · SetAlpha:設(shè)置Alpha通道,即設(shè)置
6、透明等級 · SetMatrix:設(shè)置平移矩陣 · setFlags:設(shè)置其它標(biāo)志 這些SurfaceControl類的功能實(shí)現(xiàn)僅僅是對SurfaceComposerClient的簡單封裝??梢酝ㄟ^SurfaceComposerClient的函數(shù)獲取Display的個(gè)數(shù)、高、寬、旋轉(zhuǎn)方向以及其它信息。它是通過ComposerService中的控制塊信息來實(shí)現(xiàn)的。ScreenshotClient包含屏幕截屏寬(mWidth)和高(mHeight)以及像素格式(PixelFormat),截圖數(shù)據(jù)保存在IMemoryHeap中(mHeap)。它是調(diào)用ISurfaceCompose
7、r的captureScreen函數(shù)來實(shí)現(xiàn)的。SurfaceSurface類繼承自EGLNativeBase模板類,因此它實(shí)際上一個(gè)ANativeWindow,只不過該模板給它添加了引用計(jì)數(shù)功能,并可安全地進(jìn)行類型轉(zhuǎn)換。class Surface: public EGLNativeBase<ANativeWindow, Surface, RefBase>上層應(yīng)用程序各有自己的surface,因此多個(gè)surface會(huì)同時(shí)存在,這些surface在本側(cè)就是SurfaceComposerClient所代表,它們可以添加到Composer類維護(hù)的列表中。SurfaceControl會(huì)使用Su
8、rfaceClient和Surface去完成相應(yīng)功能,SurfaceControl的getSurface函數(shù)會(huì)創(chuàng)建Surface,從而也會(huì)導(dǎo)致SurfaceClient的創(chuàng)建,進(jìn)而相應(yīng)的ISurfaceClientComposer等會(huì)被創(chuàng)建。ISurfaceComposerISurfaceComposer是SurfaceFlinger在client側(cè)的一個(gè)binder,提供的接口用于對整個(gè)屏幕的全局性的管理,如方向旋轉(zhuǎn)、屏幕快照、屏幕事件、屏幕更新的凍結(jié)與去凍結(jié)等。它提供的接口對應(yīng)的枚舉類型有:enum / Note: BOOT_FINISHED must remain this value,
9、 it is called from/ Java by ActivityManagerService.BOOT_FINISHED = IBinder:FIRST_CALL_TRANSACTION,CREATE_CONNECTION,CREATE_CLIENT_CONNECTION,GET_CBLK,OPEN_GLOBAL_TRANSACTION,CLOSE_GLOBAL_TRANSACTION,SET_ORIENTATION,FREEZE_DISPLAY,UNFREEZE_DISPLAY,SIGNAL,CAPTURE_SCREEN,TURN_ELECTRON_BEAM_OFF,TURN_ELE
10、CTRON_BEAM_ON;它是通過Binder進(jìn)行IPC通訊的接口,BpSurfaceComposer是client一側(cè), BnSurfaceComposer是service一側(cè)。它們都繼承自各自的模板類BpInterface和BnInterface,這兩個(gè)模板類完成雙重繼承的功能,一個(gè)繼承IPC通訊的API接口,一個(gè)繼承Binder功能。RefBase用于索引計(jì)數(shù),類IInterface和ISurface定義了IPC通訊的接口API,IBinder/BBinder使雙方具備Binder通訊功能。其中CREATE_CONNECTION和REATE_CLIENT_CONNECTION打開關(guān)閉一
11、個(gè)Transaction,在打開和關(guān)閉的過程中,可以設(shè)置狀態(tài),實(shí)現(xiàn)窗口管理。狀態(tài)變化更改是在一個(gè)事務(wù)(transaction)中進(jìn)行的。其類繼承關(guān)系如下:根據(jù)Binder繼承關(guān)系規(guī)則,client側(cè)的接口調(diào)用通過最終是由Bn側(cè)的子類完成。我們就可以知道它的它動(dòng)態(tài)的調(diào)用關(guān)系如下,左側(cè)的調(diào)用者一般可以通過指向ISurfaceComposer的智能指針將操作將調(diào)用到SurfaceFlinger類的成員函數(shù)。ComposerService對IsurfaceComposer進(jìn)行了包裹,使用它的getComposerService函數(shù)可以獲取IsurfaceComposer。另外,ComposerServ
12、ice還包含了surface_flinger_cblk_t控制塊信息,該內(nèi)存塊位于Ashem內(nèi)存上,由SurfaceFlinger申請,并依據(jù)display硬件信息填充字段值。client端程序通過讀取它,即可得到各display的信息。struct display_cblk_t/dispaly的各項(xiàng)信息uint16_t w;uint16_t h;uint8_t format;uint8_t orientation;uint8_t reserved2;float fps;float density;float xdpi;float ydpi;uint32_t pad2;struct surfa
13、ce_flinger_cblk_t / 4KB max/控制信息塊uint8_t connected;uint8_t reserved3;uint32_t pad7;display_cblk_t displaysSharedBufferStack:NUM_DISPLAY_MAX;/最多4個(gè)display;在SufraceFlinger的readyToRun會(huì)申請內(nèi)存,并依據(jù)DisplayHardWare中得到display信息:/ create the shared control-blockmServerHeap = new MemoryHeapBase(4096,MemoryHeapBas
14、e:READ_ONLY, “SurfaceFlinger read-only heap”);/分配內(nèi)存,沒有指定設(shè)備名稱或描述符fd,默認(rèn)使用AShem上的內(nèi)存LOGE_IF(mServerHeap=0, “cant create shared memory dealer”);mServerCblk = /得到內(nèi)存基址static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase();LOGE_IF(mServerCblk=0, “cant get to shared control blocks address”);new
15、(mServerCblk) surface_flinger_cblk_t;/ initialize primary screen/ (other display should be initialized in the same manner, but / asynchronously, as they could come and go. None of this is supported yet).const GraphicPlane& plane(graphicPlane(dpy);const DisplayHardware& hw = plane.displayHard
16、ware();const uint32_t w = hw.getWidth();const uint32_t h = hw.getHeight();const uint32_t f = hw.getFormat();hw.makeCurrent();/ initialize the shared control blockmServerCblk->connected |= 1<<dpy;display_cblk_t* dcblk = mServerCblk->displays + dpy;memset(dcblk, 0, sizeof(display_cblk_t);/
17、給結(jié)構(gòu)體賦值,同一塊內(nèi)存上,client側(cè)可以立即得到dcblk->w = plane.getWidth();dcblk->h = plane.getHeight();dcblk->format = f;dcblk->orientation = ISurfaceComposer:eOrientationDefault;dcblk->xdpi = hw.getDpiX();dcblk->ydpi = hw.getDpiY();dcblk->fps = hw.getRefreshRate();dcblk->density = hw.getDensit
18、y();IsurfaceComposerClientISurfaceComposerClient用于通過Binder與SurfaceFlinger交互,創(chuàng)建和銷毀ISurface,它也可以獲取控制塊。在SurfaceFlinger側(cè)會(huì)有兩種類型的surface:Client(用于創(chuàng)建銷毀ISurace)和UserClient(用于獲取控制塊進(jìn)行通訊)。它提供的接口對應(yīng)的枚舉類型如下:enum GET_CBLK = IBinder:FIRST_CALL_TRANSACTION,GET_TOKEN,CREATE_SURFACE,DESTROY_SURFACE,SET_STATE;動(dòng)態(tài)調(diào)用關(guān)系圖,調(diào)
19、用者通過對IsurfaceComposerClient的引用,最后由SufaceFlinger進(jìn)程中的Client或UserClient來完成:ISurfaceIsurface提供了一個(gè)與SufaceFlinger側(cè)進(jìn)行IPC交互的接口,它主要功能是操作緩沖區(qū)。我們可以從ISurface這個(gè)純虛類中看出起定義的接口操作:enum REGISTER_BUFFERS = IBinder:FIRST_CALL_TRANSACTION,UNREGISTER_BUFFERS,POST_BUFFER, / one-way transactionCREATE_OVERLAY,REQUEST_BUFFER,S
20、ET_BUFFER_COUNT,;這些枚舉就是所支持的接口操作,相應(yīng)地對應(yīng)著純虛成員函數(shù)。我們可以望文生義理解其含義。如下圖,BpSurface是client一側(cè), BnSurface是service一側(cè)。它們都繼承自各自的模板類BpInterface和BnInterface,這兩個(gè)模板類完成雙重繼承的功能,一個(gè)繼承IPC通訊的API接口,一個(gè)繼承Binder功能。RefBase用于索引計(jì)數(shù),類IInterface和ISurface定義了IPC通訊的接口API,IBinder/BBinder使雙方具備Binder通訊功能。類繼承關(guān)系圖動(dòng)態(tài)調(diào)用關(guān)系如下圖所示:sp<Isurface>
21、Surface flinger制塊在文件SharedBufferStack.h中定義了一個(gè)結(jié)構(gòu)體,它是為了通過共享內(nèi)存的方式快速獲取系統(tǒng)所有display物理信息,這個(gè)控制塊由結(jié)構(gòu)體surface_flinger_cblk_t定義:struct display_cblk_t/顯示控制塊,Android中默認(rèn)支持最多4個(gè)diaplayuint16_t w; /display的寬uint16_t h; /display的高uint8_t format; /格式uint8_t orientation; /旋轉(zhuǎn)方向uint8_t reserved2; /保留字節(jié)float fps; /刷新率float
22、 density; /密度float xdpi;/x方向上的解析度,每英寸的點(diǎn)陣數(shù)(dots/inch)float ydpi;/y方向上的解析度uint32_t pad2;/填充字節(jié);struct surface_flinger_cblk_t / 4KB maxuint8_t connected;/是否連接uint8_t reserved3;/保留字節(jié)uint32_t pad7;/填充字節(jié)display_cblk_t displaysSharedBufferStack:NUM_DISPLAY_MAX;/支持最多4個(gè)的display;Java層在創(chuàng)建一個(gè)SurfaceSession實(shí)例時(shí),建立到
23、server側(cè)的連接,這個(gè)連接的動(dòng)作實(shí)際就是分配內(nèi)存、創(chuàng)建surface_flinger_cblk_t對象并初始化獲得初始值、以及可以跨進(jìn)程訪問的過程。具體過程是:在client一側(cè),創(chuàng)建Surface Session時(shí),會(huì)創(chuàng)建一個(gè)SurfaceComposerClient對象,接著會(huì)調(diào)用SurfaceComposerClient:onFirstRef:void SurfaceComposerClient:onFirstRef()/第一次創(chuàng)建對象時(shí)被調(diào)用sp<ISurfaceComposer> sm(getComposerService();/導(dǎo)致獲取全局控制塊if (sm !=
24、0) sp<ISurfaceComposerClient> conn = sm->createConnection();/創(chuàng)建一個(gè)連接,surface flinger側(cè)會(huì)創(chuàng)建一個(gè)Client對象if (conn != 0) mClient = conn;Composer:addClient(this);mPrebuiltLayerState = new layer_state_t;mStatus = NO_ERROR;在上面的代碼中,先在ComposerService的構(gòu)造函數(shù)中獲取surface flinger控制塊。ComposerService(也就是ISurfaceC
25、omposer的Wrapper)構(gòu)造函數(shù)獲取surface flinger控制塊的過程如下:ComposerService:ComposerService(): Singleton<ComposerService>() const String16 name(“SurfaceFlinger”);while (getService(name, &mComposerService) != NO_ERROR) usleep(250000);mServerCblkMemory = mComposerService->getCblk();/獲取IMemoryHeapmServe
26、rCblk = static_cast<surface_flinger_cblk_t volatile *>(mServerCblkMemory->getBase();/在IMemoryHeap中的基址指針轉(zhuǎn)換為surface_flinger_cblk_t指針另外,SurfaceComposerClient的onFirstRef會(huì)創(chuàng)建一個(gè)connection,它的目的是創(chuàng)建代理對象,用于Binder IPC通訊,ISurfaceComposerClient接口強(qiáng)指針指向該代理對象。在server側(cè),它只是調(diào)用Client(也就是ISurfaceComposerClient接口
27、在server側(cè)的真正實(shí)現(xiàn)者)構(gòu)造函數(shù)創(chuàng)建一個(gè)Client對象進(jìn)行類型轉(zhuǎn)換后返回。而實(shí)際的內(nèi)存分配是在server側(cè)創(chuàng)建SurfaceFlinger后準(zhǔn)備運(yùn)行其工作線程時(shí)完成的,見SurfaceFlinger:readyToRun函數(shù):status_t SurfaceFlinger:readyToRun()LOGI( “SurfaceFlingers main thread ready to run. ”“Initializing graphics H/W”);/ we only support one display currentlyint dpy = 0;/ initialize the
28、 main displayGraphicPlane& plane(graphicPlane(dpy);DisplayHardware* const hw = new DisplayHardware(this, dpy);plane.setDisplayHardware(hw);/ create the shared control-block/創(chuàng)建共享控制塊,因未指定在何處分配內(nèi)存,默認(rèn)的是ashmem上mServerHeap = new MemoryHeapBase(4096,MemoryHeapBase:READ_ONLY, “SurfaceFlinger read-only he
29、ap”);LOGE_IF(mServerHeap=0, “cant create shared memory dealer”);mServerCblk = static_cast<surface_flinger_cblk_t*> (mServerHeap->getBase();/獲取基址LOGE_IF(mServerCblk=0, “cant get to shared control blocks address”);new(mServerCblk) surface_flinger_cblk_t;/ initialize primary screen/ (other dis
30、play should be initialized in the same manner, but/ asynchronously, as they could come and go. None of this is supported yet).const GraphicPlane& plane(graphicPlane(dpy);const DisplayHardware& hw = plane.displayHardware();const uint32_t w = hw.getWidth();const uint32_t h = hw.getHeight();con
31、st uint32_t f = hw.getFormat();hw.makeCurrent();/ initialize the shared control blockmServerCblk->connected |= 1<<dpy;/下面是為共享控制塊賦值display_cblk_t* dcblk = mServerCblk->displays + dpy;memset(dcblk, 0, sizeof(display_cblk_t);dcblk->w = plane.getWidth();dcblk->h = plane.getHeight();dcb
32、lk->format = f;dcblk->orientation = ISurfaceComposer:eOrientationDefault;dcblk->xdpi = hw.getDpiX();dcblk->ydpi = hw.getDpiY();dcblk->fps = hw.getRefreshRate();dcblk->density = hw.getDensity();/省略部分代碼它為該控制塊在ashmem上分配內(nèi)存并對其初始化賦值。SharedClient控制塊在SurfaceControl的getSurface() 時(shí),會(huì)創(chuàng)建一個(gè)Surf
33、ace,接著調(diào)用SurfaceClient的構(gòu)造函數(shù),由于SurfaceClient是singleton,即系統(tǒng)中只有一個(gè)實(shí)例,因此,在其第一次創(chuàng)建時(shí)調(diào)用了構(gòu)造函數(shù),而在其構(gòu)造函數(shù)中調(diào)用了createClientConnection,這個(gè)就是建立連接的過程,就是分配內(nèi)存控制塊的過程。在client側(cè),其代碼如下:SurfaceClient(): Singleton<SurfaceClient>(), mStatus(NO_INIT)sp<ISurfaceComposer> /獲取Composer servicesf(ComposerService:getComposer
34、Service();mComposerService = sf;mClient = sf->createClientConnection();/創(chuàng)建client連接if (mClient != NULL) /創(chuàng)建成功的話mControlMemory = mClient->getControlBlock();/獲取內(nèi)存塊if (mControlMemory != NULL) mControl = static_cast<SharedClient *>(mControlMemory->getBase();/得到基地址,并轉(zhuǎn)換為SharedClient指針,然后賦值給m
35、Controlif (mControl) mStatus = NO_ERROR;在server側(cè),它調(diào)用UserClient的構(gòu)造函數(shù):UserClient:UserClient(const sp<SurfaceFlinger>& flinger): ctrlblk(0), mBitmap(0), mFlinger(flinger)const int pgsize = getpagesize();/獲取內(nèi)存頁大小const int cblksize = /控制塊大小,即進(jìn)行頁對齊后的SharedClient大小(sizeof(SharedClient)+(pgsize-1)
36、&(pgsize-1);mCblkHeap = new MemoryHeapBase(cblksize, 0,/在ashmem上分配內(nèi)存“SurfaceFlinger Client control-block”);ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase();/指針類型轉(zhuǎn)換if (ctrlblk) / construct the shared structure in-place.new(ctrlblk) SharedClient;/調(diào)用構(gòu)造函數(shù)初始化內(nèi)存塊對象也就是說,建立一個(gè)clientCon
37、nection的過程,也就是在server側(cè):在堆上分配一塊頁對齊的內(nèi)存塊,它被用來存儲(chǔ)SharedClient對象;之后,client側(cè)同樣也擁有該塊內(nèi)存,同樣也被解釋為SharedClient對象指針。TODO:它們是跨進(jìn)程的,所以通過IMemoryHeap這個(gè)binder接口來操作。那么SharedClient是何方神圣呢?在頭文件SharedBufferStack.h中有代碼注釋:“These classes manage a stack of buffers in shared memory.SharedClient: represents a client with several
38、 stacksSharedBufferStack: represents a stack of buffersSharedBufferClient: manipulates the SharedBufferStack from the client sideSharedBufferServer: manipulates the SharedBufferStack from the server sideBuffers can be dequeued until there are none available, they can be lockedunless they are in use
39、by the server, which is only the case for the lastdequeue-able buffer. When these various conditions are not met, the callerwaits until the condition is met.”我們先來看一下比較重要的一個(gè)類SharedBufferStackclass SharedBufferStack/省略部分代碼struct SmallRect /定義了一個(gè)矩形:左上角和右下角的坐標(biāo)uint16_t l, t, r, b;/定義了一個(gè)平面區(qū)域,包含了若干(不超過5個(gè))矩形struct FlatRegion / 52 bytes = 4 * (1 + 2*N)static const unsig
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 化工產(chǎn)品批發(fā)商銷售目標(biāo)制定與實(shí)現(xiàn)考核試卷
- 呼吸機(jī)與睡眠輔助考核試卷
- 2025年中國男士辦公休閑拖鞋市場調(diào)查研究報(bào)告
- 2025年中國電子防潮保險(xiǎn)箱市場調(diào)查研究報(bào)告
- 2025年中國電動(dòng)車直槽無刷電機(jī)市場調(diào)查研究報(bào)告
- 2025年中國生食品市場調(diào)查研究報(bào)告
- 礦權(quán)交易市場拓展協(xié)議
- 裝修項(xiàng)目聲環(huán)境治理協(xié)議
- 骨科老年患者圍手術(shù)期譫妄護(hù)理實(shí)踐方案的構(gòu)建及應(yīng)用
- 紅肉蘋果優(yōu)新品種篩選及其呈色機(jī)制解析
- 新大象版科學(xué)三年級下冊全冊知識(shí)點(diǎn) (復(fù)習(xí)用)
- 《提案與方案優(yōu)化設(shè)計(jì)》課件-第二部分 平面布局方案設(shè)計(jì)
- 2024年黑龍江省專升本考試生理學(xué)護(hù)理學(xué)專業(yè)測試題含解析
- 奧特康唑膠囊-臨床用藥解讀
- 《新能源發(fā)電技術(shù)第2版》 課件全套 朱永強(qiáng) 第1-10章 能源概述- 分布式發(fā)電與能源互補(bǔ)
- 認(rèn)識(shí)統(tǒng)計(jì)年報(bào)基本概念與作用
- 2024年內(nèi)蒙古化工職業(yè)學(xué)院高職單招(英語/數(shù)學(xué)/語文)筆試歷年參考題庫含答案解析
- 民盟入盟申請書(通用6篇)
- XX精神科醫(yī)生述職報(bào)告(四篇合集)
- 給家里人做一頓飯
- 《嬰兒撫觸》課件
評論
0/150
提交評論