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