android_view_Surface.cpp revision 54a181b1a2b1517a9479b21fbf7705a688232faf
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_view_Surface.h"
37#include <utils/misc.h>
38
39
40// ----------------------------------------------------------------------------
41
42namespace android {
43
44enum {
45    // should match Parcelable.java
46    PARCELABLE_WRITE_RETURN_VALUE = 0x0001
47};
48
49// ----------------------------------------------------------------------------
50
51static const char* const OutOfResourcesException =
52    "android/view/Surface$OutOfResourcesException";
53
54struct sso_t {
55    jfieldID client;
56};
57static sso_t sso;
58
59struct so_t {
60    jfieldID surfaceControl;
61    jfieldID surface;
62    jfieldID saveCount;
63    jfieldID canvas;
64};
65static so_t so;
66
67struct ro_t {
68    jfieldID l;
69    jfieldID t;
70    jfieldID r;
71    jfieldID b;
72};
73static ro_t ro;
74
75struct po_t {
76    jfieldID x;
77    jfieldID y;
78};
79static po_t po;
80
81struct co_t {
82    jfieldID surfaceFormat;
83};
84static co_t co;
85
86struct no_t {
87    jfieldID native_canvas;
88    jfieldID native_region;
89    jfieldID native_parcel;
90};
91static no_t no;
92
93
94static __attribute__((noinline))
95void 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
107static 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
114static 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
124static 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
137static 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
144static 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
158static 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
183sp<ANativeWindow> android_Surface_getNativeWindow(
184        JNIEnv* env, jobject clazz) {
185    return getSurface(env, clazz).get();
186}
187
188static 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
202static 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
232static 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, 0));
241    setSurface(env, clazz, sur);
242}
243
244static 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
253static 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
263static void Surface_release(JNIEnv* env, jobject clazz, uintptr_t *ostack)
264{
265    setSurfaceControl(env, clazz, 0);
266    setSurface(env, clazz, 0);
267}
268
269static 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
279static 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
295static 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
374static 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
401static 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
408static void Surface_openTransaction(
409        JNIEnv* env, jobject clazz)
410{
411    SurfaceComposerClient::openGlobalTransaction();
412}
413
414static void Surface_closeTransaction(
415        JNIEnv* env, jobject clazz)
416{
417    SurfaceComposerClient::closeGlobalTransaction();
418}
419
420static 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
429static 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
438static 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
447static 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
457static 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
467static 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
477static 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
487static 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
497static 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
507static 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
517static 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
527static 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
550static 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
560static 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
571static 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
584static 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
610static 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    const sp<Surface>& curr(getSurface(env, clazz));
620    sp<Surface> sur(Surface::readFromParcel(*parcel, curr));
621    setSurface(env, clazz, sur);
622}
623
624static void Surface_writeToParcel(
625        JNIEnv* env, jobject clazz, jobject argParcel, jint flags)
626{
627    Parcel* parcel = (Parcel*)env->GetIntField(
628            argParcel, no.native_parcel);
629
630    if (parcel == NULL) {
631        doThrow(env, "java/lang/NullPointerException", NULL);
632        return;
633    }
634
635    const sp<SurfaceControl>& control(getSurfaceControl(env, clazz));
636    SurfaceControl::writeSurfaceToParcel(control, parcel);
637    if (flags & PARCELABLE_WRITE_RETURN_VALUE) {
638        setSurfaceControl(env, clazz, 0);
639    }
640}
641
642// ----------------------------------------------------------------------------
643// ----------------------------------------------------------------------------
644// ----------------------------------------------------------------------------
645
646const char* const kSurfaceSessionClassPathName = "android/view/SurfaceSession";
647const char* const kSurfaceClassPathName = "android/view/Surface";
648static void nativeClassInit(JNIEnv* env, jclass clazz);
649
650static JNINativeMethod gSurfaceSessionMethods[] = {
651    {"init",     "()V",  (void*)SurfaceSession_init },
652    {"destroy",  "()V",  (void*)SurfaceSession_destroy },
653    {"kill",     "()V",  (void*)SurfaceSession_kill },
654};
655
656static JNINativeMethod gSurfaceMethods[] = {
657    {"nativeClassInit",     "()V",  (void*)nativeClassInit },
658    {"init",                "(Landroid/view/SurfaceSession;ILjava/lang/String;IIIII)V",  (void*)Surface_init },
659    {"init",                "(Landroid/os/Parcel;)V",  (void*)Surface_initParcel },
660    {"getIdentity",         "()I",  (void*)Surface_getIdentity },
661    {"destroy",             "()V",  (void*)Surface_destroy },
662    {"release",             "()V",  (void*)Surface_release },
663    {"copyFrom",            "(Landroid/view/Surface;)V",  (void*)Surface_copyFrom },
664    {"isValid",             "()Z",  (void*)Surface_isValid },
665    {"lockCanvasNative",    "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;",  (void*)Surface_lockCanvas },
666    {"unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvasAndPost },
667    {"unlockCanvas",        "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas },
668    {"openTransaction",     "()V",  (void*)Surface_openTransaction },
669    {"closeTransaction",    "()V",  (void*)Surface_closeTransaction },
670    {"setOrientation",      "(III)V", (void*)Surface_setOrientation },
671    {"freezeDisplay",       "(I)V", (void*)Surface_freezeDisplay },
672    {"unfreezeDisplay",     "(I)V", (void*)Surface_unfreezeDisplay },
673    {"setLayer",            "(I)V", (void*)Surface_setLayer },
674    {"setPosition",         "(II)V",(void*)Surface_setPosition },
675    {"setSize",             "(II)V",(void*)Surface_setSize },
676    {"hide",                "()V",  (void*)Surface_hide },
677    {"show",                "()V",  (void*)Surface_show },
678    {"freeze",              "()V",  (void*)Surface_freeze },
679    {"unfreeze",            "()V",  (void*)Surface_unfreeze },
680    {"setFlags",            "(II)V",(void*)Surface_setFlags },
681    {"setTransparentRegionHint","(Landroid/graphics/Region;)V", (void*)Surface_setTransparentRegion },
682    {"setAlpha",            "(F)V", (void*)Surface_setAlpha },
683    {"setMatrix",           "(FFFF)V",  (void*)Surface_setMatrix },
684    {"setFreezeTint",       "(I)V",  (void*)Surface_setFreezeTint },
685    {"readFromParcel",      "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel },
686    {"writeToParcel",       "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel },
687};
688
689void nativeClassInit(JNIEnv* env, jclass clazz)
690{
691    so.surface = env->GetFieldID(clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I");
692    so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I");
693    so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I");
694    so.canvas    = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;");
695
696    jclass surfaceSession = env->FindClass("android/view/SurfaceSession");
697    sso.client = env->GetFieldID(surfaceSession, "mClient", "I");
698
699    jclass canvas = env->FindClass("android/graphics/Canvas");
700    no.native_canvas = env->GetFieldID(canvas, "mNativeCanvas", "I");
701    co.surfaceFormat = env->GetFieldID(canvas, "mSurfaceFormat", "I");
702
703    jclass region = env->FindClass("android/graphics/Region");
704    no.native_region = env->GetFieldID(region, "mNativeRegion", "I");
705
706    jclass parcel = env->FindClass("android/os/Parcel");
707    no.native_parcel = env->GetFieldID(parcel, "mObject", "I");
708
709    jclass rect = env->FindClass("android/graphics/Rect");
710    ro.l = env->GetFieldID(rect, "left", "I");
711    ro.t = env->GetFieldID(rect, "top", "I");
712    ro.r = env->GetFieldID(rect, "right", "I");
713    ro.b = env->GetFieldID(rect, "bottom", "I");
714
715    jclass point = env->FindClass("android/graphics/Point");
716    po.x = env->GetFieldID(point, "x", "I");
717    po.y = env->GetFieldID(point, "y", "I");
718}
719
720int register_android_view_Surface(JNIEnv* env)
721{
722    int err;
723    err = AndroidRuntime::registerNativeMethods(env, kSurfaceSessionClassPathName,
724            gSurfaceSessionMethods, NELEM(gSurfaceSessionMethods));
725
726    err |= AndroidRuntime::registerNativeMethods(env, kSurfaceClassPathName,
727            gSurfaceMethods, NELEM(gSurfaceMethods));
728    return err;
729}
730
731};
732
733