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