OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / core / jni / android_view_Surface.cpp
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define LOG_TAG "Surface"
18
19 #include <stdio.h>
20
21 #include "android_util_Binder.h"
22
23 #include <surfaceflinger/SurfaceComposerClient.h>
24 #include <surfaceflinger/Surface.h>
25 #include <ui/Region.h>
26 #include <ui/Rect.h>
27
28 #include <EGL/egl.h>
29
30 #include <SkCanvas.h>
31 #include <SkBitmap.h>
32 #include <SkRegion.h>
33
34 #include "jni.h"
35 #include <android_runtime/AndroidRuntime.h>
36 #include <android_runtime/android_view_Surface.h>
37 #include <utils/misc.h>
38
39
40 // ----------------------------------------------------------------------------
41
42 namespace android {
43
44 enum {
45     // should match Parcelable.java
46     PARCELABLE_WRITE_RETURN_VALUE = 0x0001
47 };
48
49 // ----------------------------------------------------------------------------
50
51 static const char* const OutOfResourcesException =
52     "android/view/Surface$OutOfResourcesException";
53
54 struct sso_t {
55     jfieldID client;
56 };
57 static sso_t sso;
58
59 struct so_t {
60     jfieldID surfaceControl;
61     jfieldID surface;
62     jfieldID saveCount;
63     jfieldID canvas;
64 };
65 static so_t so;
66
67 struct ro_t {
68     jfieldID l;
69     jfieldID t;
70     jfieldID r;
71     jfieldID b;
72 };
73 static ro_t ro;
74
75 struct po_t {
76     jfieldID x;
77     jfieldID y;
78 };
79 static po_t po;
80
81 struct co_t {
82     jfieldID surfaceFormat;
83 };
84 static co_t co;
85
86 struct no_t {
87     jfieldID native_canvas;
88     jfieldID native_region;
89     jfieldID native_parcel;
90 };
91 static no_t no;
92
93
94 static __attribute__((noinline))
95 void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
96 {
97     if (!env->ExceptionOccurred()) {
98         jclass npeClazz = env->FindClass(exc);
99         env->ThrowNew(npeClazz, msg);
100     }
101 }
102
103 // ----------------------------------------------------------------------------
104 // ----------------------------------------------------------------------------
105 // ----------------------------------------------------------------------------
106
107 static void SurfaceSession_init(JNIEnv* env, jobject clazz)
108 {
109     sp<SurfaceComposerClient> client = new SurfaceComposerClient;
110     client->incStrong(clazz);
111     env->SetIntField(clazz, sso.client, (int)client.get());
112 }
113
114 static void SurfaceSession_destroy(JNIEnv* env, jobject clazz)
115 {
116     SurfaceComposerClient* client =
117             (SurfaceComposerClient*)env->GetIntField(clazz, sso.client);
118     if (client != 0) {
119         client->decStrong(clazz);
120         env->SetIntField(clazz, sso.client, 0);
121     }
122 }
123
124 static void SurfaceSession_kill(JNIEnv* env, jobject clazz)
125 {
126     SurfaceComposerClient* client =
127             (SurfaceComposerClient*)env->GetIntField(clazz, sso.client);
128     if (client != 0) {
129         client->dispose();
130         client->decStrong(clazz);
131         env->SetIntField(clazz, sso.client, 0);
132     }
133 }
134
135 // ----------------------------------------------------------------------------
136
137 static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject clazz)
138 {
139     SurfaceControl* const p = 
140         (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
141     return sp<SurfaceControl>(p);
142 }
143
144 static void setSurfaceControl(JNIEnv* env, jobject clazz, 
145         const sp<SurfaceControl>& surface)
146 {
147     SurfaceControl* const p = 
148         (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
149     if (surface.get()) {
150         surface->incStrong(clazz);
151     }
152     if (p) {
153         p->decStrong(clazz);
154     }
155     env->SetIntField(clazz, so.surfaceControl, (int)surface.get());
156 }
157
158 static sp<Surface> getSurface(JNIEnv* env, jobject clazz)
159 {
160     sp<Surface> result((Surface*)env->GetIntField(clazz, so.surface));
161     if (result == 0) {
162         /*
163          * if this method is called from the WindowManager's process, it means
164          * the client is is not remote, and therefore is allowed to have
165          * a Surface (data), so we create it here. 
166          * If we don't have a SurfaceControl, it means we're in a different
167          * process.
168          */
169         
170         SurfaceControl* const control = 
171             (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl);
172         if (control) {
173             result = control->getSurface();
174             if (result != 0) {
175                 result->incStrong(clazz);
176                 env->SetIntField(clazz, so.surface, (int)result.get());
177             }
178         }
179     }
180     return result;
181 }
182
183 sp<ANativeWindow> android_Surface_getNativeWindow(
184         JNIEnv* env, jobject clazz) {
185     return getSurface(env, clazz).get();
186 }
187
188 static void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface)
189 {
190     Surface* const p = (Surface*)env->GetIntField(clazz, so.surface);
191     if (surface.get()) {
192         surface->incStrong(clazz);
193     }
194     if (p) {
195         p->decStrong(clazz);
196     }
197     env->SetIntField(clazz, so.surface, (int)surface.get());
198 }
199
200 // ----------------------------------------------------------------------------
201
202 static void Surface_init(
203         JNIEnv* env, jobject clazz, 
204         jobject session,
205         jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jint flags)
206 {
207     if (session == NULL) {
208         doThrow(env, "java/lang/NullPointerException");
209         return;
210     }
211     
212     SurfaceComposerClient* client =
213             (SurfaceComposerClient*)env->GetIntField(session, sso.client);
214
215     sp<SurfaceControl> surface;
216     if (jname == NULL) {
217         surface = client->createSurface(pid, dpy, w, h, format, flags);
218     } else {
219         const jchar* str = env->GetStringCritical(jname, 0);
220         const String8 name(str, env->GetStringLength(jname));
221         env->ReleaseStringCritical(jname, str);
222         surface = client->createSurface(pid, name, dpy, w, h, format, flags);
223     }
224
225     if (surface == 0) {
226         doThrow(env, OutOfResourcesException);
227         return;
228     }
229     setSurfaceControl(env, clazz, surface);
230 }
231
232 static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel)
233 {
234     Parcel* parcel = (Parcel*)env->GetIntField(argParcel, no.native_parcel);
235     if (parcel == NULL) {
236         doThrow(env, "java/lang/NullPointerException", NULL);
237         return;
238     }
239
240     sp<Surface> sur(Surface::readFromParcel(*parcel));
241     setSurface(env, clazz, sur);
242 }
243
244 static jint Surface_getIdentity(JNIEnv* env, jobject clazz)
245 {
246     const sp<SurfaceControl>& control(getSurfaceControl(env, clazz));
247     if (control != 0) return (jint) control->getIdentity();
248     const sp<Surface>& surface(getSurface(env, clazz));
249     if (surface != 0) return (jint) surface->getIdentity();
250     return -1;
251 }
252
253 static void Surface_destroy(JNIEnv* env, jobject clazz, uintptr_t *ostack)
254 {
255     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
256     if (SurfaceControl::isValid(surface)) {
257         surface->clear();
258     }
259     setSurfaceControl(env, clazz, 0);
260     setSurface(env, clazz, 0);
261 }
262
263 static void Surface_release(JNIEnv* env, jobject clazz, uintptr_t *ostack)
264 {
265     setSurfaceControl(env, clazz, 0);
266     setSurface(env, clazz, 0);
267 }
268
269 static jboolean Surface_isValid(JNIEnv* env, jobject clazz)
270 {
271     const sp<SurfaceControl>& surfaceControl(getSurfaceControl(env, clazz));
272     if (surfaceControl != 0) {
273         return SurfaceControl::isValid(surfaceControl) ? JNI_TRUE : JNI_FALSE;
274     }
275     const sp<Surface>& surface(getSurface(env, clazz));
276     return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE;
277 }
278
279 static inline SkBitmap::Config convertPixelFormat(PixelFormat format)
280 {
281     /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
282         we can map to SkBitmap::kARGB_8888_Config, and optionally call
283         bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
284     */
285     switch (format) {
286     case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
287     case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
288     case PIXEL_FORMAT_RGBA_4444:    return SkBitmap::kARGB_4444_Config;
289     case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
290     case PIXEL_FORMAT_A_8:          return SkBitmap::kA8_Config;
291     default:                        return SkBitmap::kNo_Config;
292     }
293 }
294
295 static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect)
296 {
297     const sp<Surface>& surface(getSurface(env, clazz));
298     if (!Surface::isValid(surface))
299         return 0;
300
301     // get dirty region
302     Region dirtyRegion;
303     if (dirtyRect) {
304         Rect dirty;
305         dirty.left  = env->GetIntField(dirtyRect, ro.l);
306         dirty.top   = env->GetIntField(dirtyRect, ro.t);
307         dirty.right = env->GetIntField(dirtyRect, ro.r);
308         dirty.bottom= env->GetIntField(dirtyRect, ro.b);
309         if (!dirty.isEmpty()) {
310             dirtyRegion.set(dirty);    
311         }
312     } else {
313         dirtyRegion.set(Rect(0x3FFF,0x3FFF));
314     }
315
316     Surface::SurfaceInfo info;
317     status_t err = surface->lock(&info, &dirtyRegion);
318     if (err < 0) {
319         const char* const exception = (err == NO_MEMORY) ?
320             OutOfResourcesException :
321             "java/lang/IllegalArgumentException";
322         doThrow(env, exception, NULL);
323         return 0;
324     }
325
326     // Associate a SkCanvas object to this surface
327     jobject canvas = env->GetObjectField(clazz, so.canvas);
328     env->SetIntField(canvas, co.surfaceFormat, info.format);
329
330     SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas);
331     SkBitmap bitmap;
332     ssize_t bpr = info.s * bytesPerPixel(info.format);
333     bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr);
334     if (info.format == PIXEL_FORMAT_RGBX_8888) {
335         bitmap.setIsOpaque(true);
336     }
337     if (info.w > 0 && info.h > 0) {
338         bitmap.setPixels(info.bits);
339     } else {
340         // be safe with an empty bitmap.
341         bitmap.setPixels(NULL);
342     }
343     nativeCanvas->setBitmapDevice(bitmap);
344     
345     SkRegion clipReg;
346     if (dirtyRegion.isRect()) { // very common case
347         const Rect b(dirtyRegion.getBounds());
348         clipReg.setRect(b.left, b.top, b.right, b.bottom);
349     } else {
350         size_t count;
351         Rect const* r = dirtyRegion.getArray(&count);
352         while (count) {
353             clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op);
354             r++, count--;
355         }
356     }
357
358     nativeCanvas->clipRegion(clipReg);
359     
360     int saveCount = nativeCanvas->save();
361     env->SetIntField(clazz, so.saveCount, saveCount);
362
363     if (dirtyRect) {
364         const Rect& bounds(dirtyRegion.getBounds());
365         env->SetIntField(dirtyRect, ro.l, bounds.left);
366         env->SetIntField(dirtyRect, ro.t, bounds.top);
367         env->SetIntField(dirtyRect, ro.r, bounds.right);
368         env->SetIntField(dirtyRect, ro.b, bounds.bottom);
369     }
370     
371     return canvas;
372 }
373
374 static void Surface_unlockCanvasAndPost(
375         JNIEnv* env, jobject clazz, jobject argCanvas)
376 {
377     jobject canvas = env->GetObjectField(clazz, so.canvas);
378     if (canvas != argCanvas) {
379         doThrow(env, "java/lang/IllegalArgumentException", NULL);
380         return;
381     }
382     
383     const sp<Surface>& surface(getSurface(env, clazz));
384     if (!Surface::isValid(surface))
385         return;
386
387     // detach the canvas from the surface
388     SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas);
389     int saveCount = env->GetIntField(clazz, so.saveCount);
390     nativeCanvas->restoreToCount(saveCount);
391     nativeCanvas->setBitmapDevice(SkBitmap());
392     env->SetIntField(clazz, so.saveCount, 0);
393
394     // unlock surface
395     status_t err = surface->unlockAndPost();
396     if (err < 0) {
397         doThrow(env, "java/lang/IllegalArgumentException", NULL);
398     }
399 }
400
401 static void Surface_unlockCanvas(
402         JNIEnv* env, jobject clazz, jobject argCanvas)
403 {
404     // XXX: this API has been removed
405     doThrow(env, "java/lang/IllegalArgumentException", NULL);
406 }
407
408 static void Surface_openTransaction(
409         JNIEnv* env, jobject clazz)
410 {
411     SurfaceComposerClient::openGlobalTransaction();
412 }
413
414 static void Surface_closeTransaction(
415         JNIEnv* env, jobject clazz)
416 {
417     SurfaceComposerClient::closeGlobalTransaction();
418 }
419
420 static void Surface_setOrientation(
421         JNIEnv* env, jobject clazz, jint display, jint orientation, jint flags)
422 {
423     int err = SurfaceComposerClient::setOrientation(display, orientation, flags);
424     if (err < 0) {
425         doThrow(env, "java/lang/IllegalArgumentException", NULL);
426     }
427 }
428
429 static void Surface_freezeDisplay(
430         JNIEnv* env, jobject clazz, jint display)
431 {
432     int err = SurfaceComposerClient::freezeDisplay(display, 0);
433     if (err < 0) {
434         doThrow(env, "java/lang/IllegalArgumentException", NULL);
435     }
436 }
437
438 static void Surface_unfreezeDisplay(
439         JNIEnv* env, jobject clazz, jint display)
440 {
441     int err = SurfaceComposerClient::unfreezeDisplay(display, 0);
442     if (err < 0) {
443         doThrow(env, "java/lang/IllegalArgumentException", NULL);
444     }
445 }
446
447 static void Surface_setLayer(
448         JNIEnv* env, jobject clazz, jint zorder)
449 {
450     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
451     if (surface == 0) return;
452     status_t err = surface->setLayer(zorder);
453     if (err<0 && err!=NO_INIT)
454         doThrow(env, "java/lang/IllegalArgumentException", NULL);
455 }
456
457 static void Surface_setPosition(
458         JNIEnv* env, jobject clazz, jint x, jint y)
459 {
460     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
461     if (surface == 0) return;
462     status_t err = surface->setPosition(x, y);
463     if (err<0 && err!=NO_INIT)
464         doThrow(env, "java/lang/IllegalArgumentException", NULL);
465 }
466
467 static void Surface_setSize(
468         JNIEnv* env, jobject clazz, jint w, jint h)
469 {
470     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
471     if (surface == 0) return;
472     status_t err = surface->setSize(w, h);
473     if (err<0 && err!=NO_INIT)
474         doThrow(env, "java/lang/IllegalArgumentException", NULL);
475 }
476
477 static void Surface_hide(
478         JNIEnv* env, jobject clazz)
479 {
480     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
481     if (surface == 0) return;
482     status_t err = surface->hide();
483     if (err<0 && err!=NO_INIT)
484         doThrow(env, "java/lang/IllegalArgumentException", NULL);
485 }
486
487 static void Surface_show(
488         JNIEnv* env, jobject clazz)
489 {
490     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
491     if (surface == 0) return;
492     status_t err = surface->show();
493     if (err<0 && err!=NO_INIT)
494         doThrow(env, "java/lang/IllegalArgumentException", NULL);
495 }
496
497 static void Surface_freeze(
498         JNIEnv* env, jobject clazz)
499 {
500     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
501     if (surface == 0) return;
502     status_t err = surface->freeze();
503     if (err<0 && err!=NO_INIT)
504         doThrow(env, "java/lang/IllegalArgumentException", NULL);
505 }
506
507 static void Surface_unfreeze(
508         JNIEnv* env, jobject clazz)
509 {
510     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
511     if (surface == 0) return;
512     status_t err = surface->unfreeze();
513     if (err<0 && err!=NO_INIT)
514         doThrow(env, "java/lang/IllegalArgumentException", NULL);
515 }
516
517 static void Surface_setFlags(
518         JNIEnv* env, jobject clazz, jint flags, jint mask)
519 {
520     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
521     if (surface == 0) return;
522     status_t err = surface->setFlags(flags, mask);
523     if (err<0 && err!=NO_INIT)
524         doThrow(env, "java/lang/IllegalArgumentException", NULL);
525 }
526
527 static void Surface_setTransparentRegion(
528         JNIEnv* env, jobject clazz, jobject argRegion)
529 {
530     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
531     if (surface == 0) return;
532     SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region);
533     
534     const SkIRect& b(nativeRegion->getBounds());
535     Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom));
536     if (nativeRegion->isComplex()) {
537         SkRegion::Iterator it(*nativeRegion);
538         while (!it.done()) {
539             const SkIRect& r(it.rect());
540             reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom);
541             it.next();
542         }
543     }
544     
545     status_t err = surface->setTransparentRegionHint(reg);
546     if (err<0 && err!=NO_INIT)
547         doThrow(env, "java/lang/IllegalArgumentException", NULL);
548 }
549
550 static void Surface_setAlpha(
551         JNIEnv* env, jobject clazz, jfloat alpha)
552 {
553     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
554     if (surface == 0) return;
555     status_t err = surface->setAlpha(alpha);
556     if (err<0 && err!=NO_INIT)
557         doThrow(env, "java/lang/IllegalArgumentException", NULL);
558 }
559
560 static void Surface_setMatrix(
561         JNIEnv* env, jobject clazz,
562         jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy)
563 {
564     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
565     if (surface == 0) return;
566     status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy);
567     if (err<0 && err!=NO_INIT)
568         doThrow(env, "java/lang/IllegalArgumentException", NULL);
569 }
570
571 static void Surface_setFreezeTint(
572         JNIEnv* env, jobject clazz,
573         jint tint)
574 {
575     const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
576     if (surface == 0) return;
577     status_t err = surface->setFreezeTint(tint);
578     if (err<0 && err!=NO_INIT)
579         doThrow(env, "java/lang/IllegalArgumentException", NULL);
580 }
581
582 // ----------------------------------------------------------------------------
583
584 static void Surface_copyFrom(
585         JNIEnv* env, jobject clazz, jobject other)
586 {
587     if (clazz == other)
588         return;
589
590     if (other == NULL) {
591         doThrow(env, "java/lang/NullPointerException", NULL);
592         return;
593     }
594
595     /*
596      * This is used by the WindowManagerService just after constructing
597      * a Surface and is necessary for returning the Surface reference to
598      * the caller. At this point, we should only have a SurfaceControl.
599      */
600
601     const sp<SurfaceControl>& surface = getSurfaceControl(env, clazz);
602     const sp<SurfaceControl>& rhs = getSurfaceControl(env, other);
603     if (!SurfaceControl::isSameSurface(surface, rhs)) {
604         // we reassign the surface only if it's a different one
605         // otherwise we would loose our client-side state.
606         setSurfaceControl(env, clazz, rhs);
607     }
608 }
609
610 static void Surface_readFromParcel(
611         JNIEnv* env, jobject clazz, jobject argParcel)
612 {
613     Parcel* parcel = (Parcel*)env->GetIntField( argParcel, no.native_parcel);
614     if (parcel == NULL) {
615         doThrow(env, "java/lang/NullPointerException", NULL);
616         return;
617     }
618
619     sp<Surface> sur(Surface::readFromParcel(*parcel));
620     setSurface(env, clazz, sur);
621 }
622
623 static void Surface_writeToParcel(
624         JNIEnv* env, jobject clazz, jobject argParcel, jint flags)
625 {
626     Parcel* parcel = (Parcel*)env->GetIntField(
627             argParcel, no.native_parcel);
628
629     if (parcel == NULL) {
630         doThrow(env, "java/lang/NullPointerException", NULL);
631         return;
632     }
633
634     const sp<SurfaceControl>& control(getSurfaceControl(env, clazz));
635     SurfaceControl::writeSurfaceToParcel(control, parcel);
636     if (flags & PARCELABLE_WRITE_RETURN_VALUE) {
637         setSurfaceControl(env, clazz, 0);
638     }
639 }
640
641 // ----------------------------------------------------------------------------
642 // ----------------------------------------------------------------------------
643 // ----------------------------------------------------------------------------
644
645 const char* const kSurfaceSessionClassPathName = "android/view/SurfaceSession";
646 const char* const kSurfaceClassPathName = "android/view/Surface";
647 static void nativeClassInit(JNIEnv* env, jclass clazz);
648
649 static JNINativeMethod gSurfaceSessionMethods[] = {
650     {"init",     "()V",  (void*)SurfaceSession_init },
651     {"destroy",  "()V",  (void*)SurfaceSession_destroy },
652     {"kill",     "()V",  (void*)SurfaceSession_kill },
653 };
654
655 static JNINativeMethod gSurfaceMethods[] = {
656     {"nativeClassInit",     "()V",  (void*)nativeClassInit },
657     {"init",                "(Landroid/view/SurfaceSession;ILjava/lang/String;IIIII)V",  (void*)Surface_init },
658     {"init",                "(Landroid/os/Parcel;)V",  (void*)Surface_initParcel },
659     {"getIdentity",         "()I",  (void*)Surface_getIdentity },
660     {"destroy",             "()V",  (void*)Surface_destroy },
661     {"release",             "()V",  (void*)Surface_release },
662     {"copyFrom",            "(Landroid/view/Surface;)V",  (void*)Surface_copyFrom },
663     {"isValid",             "()Z",  (void*)Surface_isValid },
664     {"lockCanvasNative",    "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;",  (void*)Surface_lockCanvas },
665     {"unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvasAndPost },
666     {"unlockCanvas",        "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas },
667     {"openTransaction",     "()V",  (void*)Surface_openTransaction },
668     {"closeTransaction",    "()V",  (void*)Surface_closeTransaction },
669     {"setOrientation",      "(III)V", (void*)Surface_setOrientation },
670     {"freezeDisplay",       "(I)V", (void*)Surface_freezeDisplay },
671     {"unfreezeDisplay",     "(I)V", (void*)Surface_unfreezeDisplay },
672     {"setLayer",            "(I)V", (void*)Surface_setLayer },
673     {"setPosition",         "(II)V",(void*)Surface_setPosition },
674     {"setSize",             "(II)V",(void*)Surface_setSize },
675     {"hide",                "()V",  (void*)Surface_hide },
676     {"show",                "()V",  (void*)Surface_show },
677     {"freeze",              "()V",  (void*)Surface_freeze },
678     {"unfreeze",            "()V",  (void*)Surface_unfreeze },
679     {"setFlags",            "(II)V",(void*)Surface_setFlags },
680     {"setTransparentRegionHint","(Landroid/graphics/Region;)V", (void*)Surface_setTransparentRegion },
681     {"setAlpha",            "(F)V", (void*)Surface_setAlpha },
682     {"setMatrix",           "(FFFF)V",  (void*)Surface_setMatrix },
683     {"setFreezeTint",       "(I)V",  (void*)Surface_setFreezeTint },
684     {"readFromParcel",      "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel },
685     {"writeToParcel",       "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel },
686 };
687
688 void nativeClassInit(JNIEnv* env, jclass clazz)
689 {
690     so.surface = env->GetFieldID(clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I");
691     so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I");
692     so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I");
693     so.canvas    = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;");
694
695     jclass surfaceSession = env->FindClass("android/view/SurfaceSession");
696     sso.client = env->GetFieldID(surfaceSession, "mClient", "I");
697
698     jclass canvas = env->FindClass("android/graphics/Canvas");
699     no.native_canvas = env->GetFieldID(canvas, "mNativeCanvas", "I");
700     co.surfaceFormat = env->GetFieldID(canvas, "mSurfaceFormat", "I");
701
702     jclass region = env->FindClass("android/graphics/Region");
703     no.native_region = env->GetFieldID(region, "mNativeRegion", "I");
704
705     jclass parcel = env->FindClass("android/os/Parcel");
706     no.native_parcel = env->GetFieldID(parcel, "mObject", "I");
707
708     jclass rect = env->FindClass("android/graphics/Rect");
709     ro.l = env->GetFieldID(rect, "left", "I");
710     ro.t = env->GetFieldID(rect, "top", "I");
711     ro.r = env->GetFieldID(rect, "right", "I");
712     ro.b = env->GetFieldID(rect, "bottom", "I");
713
714     jclass point = env->FindClass("android/graphics/Point");
715     po.x = env->GetFieldID(point, "x", "I");
716     po.y = env->GetFieldID(point, "y", "I");
717 }
718
719 int register_android_view_Surface(JNIEnv* env)
720 {
721     int err;
722     err = AndroidRuntime::registerNativeMethods(env, kSurfaceSessionClassPathName,
723             gSurfaceSessionMethods, NELEM(gSurfaceSessionMethods));
724
725     err |= AndroidRuntime::registerNativeMethods(env, kSurfaceClassPathName,
726             gSurfaceMethods, NELEM(gSurfaceMethods));
727     return err;
728 }
729
730 };