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