19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17fae5cb2b356a1fef172b43066180a7ab4c32dbacMathias Agopian#define LOG_TAG "Surface"
18fae5cb2b356a1fef172b43066180a7ab4c32dbacMathias Agopian
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown#include "android_os_Parcel.h"
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_util_Binder.h"
23a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn#include "android/graphics/GraphicsJNI.h"
2464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown#include "android/graphics/Region.h"
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn#include <binder/IMemory.h>
278335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian
280b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brown#include <gui/ISurfaceComposer.h>
298335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <gui/Surface.h>
308335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <gui/SurfaceComposerClient.h>
310de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg#include <gui/SurfaceTexture.h>
328335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian
3364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown#include <ui/DisplayInfo.h>
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ui/Rect.h>
358335f1ccccedb6655d96d9d5b697a7f0938235ddMathias Agopian#include <ui/Region.h>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
378b73ae4a1e5321753e54354e5202a38c5560fea9Mathias Agopian#include <EGL/egl.h>
388b73ae4a1e5321753e54354e5202a38c5560fea9Mathias Agopian
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <SkCanvas.h>
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <SkBitmap.h>
416158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian#include <SkRegion.h>
421f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn#include <SkPixelRef.h>
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
458451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include "JNIHelp.h"
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
47289b9b62372ef52a06113b83dfb870e2c2fb325aDianne Hackborn#include <android_runtime/android_view_Surface.h>
4864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown#include <android_runtime/android_view_SurfaceSession.h>
490de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg#include <android_runtime/android_graphics_SurfaceTexture.h>
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/misc.h>
519e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown#include <utils/Log.h>
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown#include <ScopedUtfChars.h>
5464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char* const OutOfResourcesException =
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "android/view/Surface$OutOfResourcesException";
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6364a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic struct {
6464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jclass clazz;
6564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID mNativeSurface;
6664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID mNativeSurfaceControl;
6764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID mGenerationId;
6864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID mCanvas;
6964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID mCanvasSaveCount;
70cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    jmethodID ctor;
7164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown} gSurfaceClassInfo;
7264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
7364a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic struct {
7464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID left;
7564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID top;
7664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID right;
7764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID bottom;
7864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown} gRectClassInfo;
7964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
8064a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic struct {
8164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID mNativeCanvas;
8264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID mSurfaceFormat;
8364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown} gCanvasClassInfo;
8464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
8564a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic struct {
8664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID width;
8764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID height;
8864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID refreshRate;
8964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID density;
9064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID xDpi;
9164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jfieldID yDpi;
9295429c3d1b8113c23b0aad3b74d724dccfad7fa9Jamie Gennis    jfieldID secure;
9364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown} gPhysicalDisplayInfoClassInfo;
94050316184b01c0d1a01c46afae7429b89a27c31btedbo
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9664a55af0ac700baecb0877235eb42caac59a3560Jeff Brownclass ScreenshotPixelRef : public SkPixelRef {
9764a55af0ac700baecb0877235eb42caac59a3560Jeff Brownpublic:
9864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    ScreenshotPixelRef(SkColorTable* ctable) {
9964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        fCTable = ctable;
10064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        SkSafeRef(ctable);
10164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        setImmutable();
10264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    virtual ~ScreenshotPixelRef() {
10564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        SkSafeUnref(fCTable);
10664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    status_t update(const sp<IBinder>& display, int width, int height,
10964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            int minLayer, int maxLayer, bool allLayers) {
11064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        status_t res = (width > 0 && height > 0)
11164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                ? (allLayers
11264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                        ? mScreenshot.update(display, width, height)
11364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                        : mScreenshot.update(display, width, height, minLayer, maxLayer))
11464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                : mScreenshot.update(display);
11564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        if (res != NO_ERROR) {
11664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            return res;
11764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        }
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return NO_ERROR;
12064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
12164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
12264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    uint32_t getWidth() const {
12364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return mScreenshot.getWidth();
12464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    uint32_t getHeight() const {
12764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return mScreenshot.getHeight();
12864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    uint32_t getStride() const {
13164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return mScreenshot.getStride();
13264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    uint32_t getFormat() const {
13564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return mScreenshot.getFormat();
13664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13864a55af0ac700baecb0877235eb42caac59a3560Jeff Brownprotected:
13964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    // overrides from SkPixelRef
14064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    virtual void* onLockPixels(SkColorTable** ct) {
14164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        *ct = fCTable;
14264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return (void*)mScreenshot.getPixels();
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    virtual void onUnlockPixels() {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
14864a55af0ac700baecb0877235eb42caac59a3560Jeff Brownprivate:
14964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    ScreenshotClient mScreenshot;
15064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    SkColorTable*    fCTable;
15164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
15264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    typedef SkPixelRef INHERITED;
15364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown};
15464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15864a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject surfaceObj) {
15964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return reinterpret_cast<SurfaceControl*>(
16064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl));
16117f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian}
16217f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian
16364a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void setSurfaceControl(JNIEnv* env, jobject surfaceObj,
16464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        const sp<SurfaceControl>& surface) {
16564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    SurfaceControl* const p = reinterpret_cast<SurfaceControl*>(
16664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl));
16717f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    if (surface.get()) {
16864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        surface->incStrong(surfaceObj);
16917f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    }
17017f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    if (p) {
17164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        p->decStrong(surfaceObj);
17217f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    }
17364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl,
17464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            reinterpret_cast<jint>(surface.get()));
17517f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian}
17617f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian
17764a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic sp<Surface> getSurface(JNIEnv* env, jobject surfaceObj) {
17864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<Surface> result(android_view_Surface_getSurface(env, surfaceObj));
17964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (result == NULL) {
18069d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian        /*
18169d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian         * if this method is called from the WindowManager's process, it means
18269d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian         * the client is is not remote, and therefore is allowed to have
1838451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes         * a Surface (data), so we create it here.
18469d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian         * If we don't have a SurfaceControl, it means we're in a different
18569d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian         * process.
18669d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian         */
1878451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
18864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        SurfaceControl* const control = reinterpret_cast<SurfaceControl*>(
18964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl));
19069d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian        if (control) {
19169d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian            result = control->getSurface();
19264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            if (result != NULL) {
19364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                result->incStrong(surfaceObj);
19464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface,
19564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                        reinterpret_cast<jint>(result.get()));
19669d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian            }
19769d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian        }
19869d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian    }
19969d62097e8195c947de7e4cdc4a491181aa56e61Mathias Agopian    return result;
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20264a55af0ac700baecb0877235eb42caac59a3560Jeff Brownsp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) {
20364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return getSurface(env, surfaceObj);
2048b73ae4a1e5321753e54354e5202a38c5560fea9Mathias Agopian}
2058b73ae4a1e5321753e54354e5202a38c5560fea9Mathias Agopian
20664a55af0ac700baecb0877235eb42caac59a3560Jeff Brownbool android_view_Surface_isInstanceOf(JNIEnv* env, jobject obj) {
20764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return env->IsInstanceOf(obj, gSurfaceClassInfo.clazz);
208050316184b01c0d1a01c46afae7429b89a27c31btedbo}
209050316184b01c0d1a01c46afae7429b89a27c31btedbo
21064a55af0ac700baecb0877235eb42caac59a3560Jeff Brownsp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) {
21164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return reinterpret_cast<Surface*>(
21264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface));
2134e8a5c922c287ec97fec847194e930f8598a1941tedbo}
2144e8a5c922c287ec97fec847194e930f8598a1941tedbo
21564a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void setSurface(JNIEnv* env, jobject surfaceObj, const sp<Surface>& surface) {
21664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    Surface* const p = reinterpret_cast<Surface*>(
21764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface));
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (surface.get()) {
21964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        surface->incStrong(surfaceObj);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (p) {
22264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        p->decStrong(surfaceObj);
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface,
22564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            reinterpret_cast<jint>(surface.get()));
22664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
2272a83f001fdb189f945e82e81e717ba204824b112Romain Guy    // This test is conservative and it would be better to compare the ISurfaces
2282a83f001fdb189f945e82e81e717ba204824b112Romain Guy    if (p && p != surface.get()) {
22964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        jint generationId = env->GetIntField(surfaceObj,
23064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                gSurfaceClassInfo.mGenerationId);
2312a83f001fdb189f945e82e81e717ba204824b112Romain Guy        generationId++;
23264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        env->SetIntField(surfaceObj,
23364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                gSurfaceClassInfo.mGenerationId, generationId);
2342a83f001fdb189f945e82e81e717ba204824b112Romain Guy    }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
237cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownstatic sp<ISurfaceTexture> getISurfaceTexture(JNIEnv* env, jobject surfaceObj) {
238cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    if (surfaceObj) {
239cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        sp<Surface> surface(getSurface(env, surfaceObj));
240cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        if (surface != NULL) {
241cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            return surface->getSurfaceTexture();
242cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        }
243cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
244cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    return NULL;
245cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown}
246cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
247cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brownjobject android_view_Surface_createFromISurfaceTexture(JNIEnv* env,
248cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        const sp<ISurfaceTexture>& surfaceTexture) {
249cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    if (surfaceTexture == NULL) {
250cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        return NULL;
251cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
252cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
253cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    sp<Surface> surface(new Surface(surfaceTexture));
254cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    if (surface == NULL) {
255cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        return NULL;
256cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
257cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
258cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, gSurfaceClassInfo.ctor);
259cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    if (surfaceObj == NULL) {
260cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        if (env->ExceptionCheck()) {
261cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            ALOGE("Could not create instance of Surface from ISurfaceTexture.");
262cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            LOGE_EX(env);
263cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown            env->ExceptionClear();
264cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        }
265cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        return NULL;
266cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    }
267cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
268cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    setSurface(env, surfaceObj, surface);
269cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    return surfaceObj;
270cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown}
271cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
272cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ----------------------------------------------------------------------------
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
27564a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeCreate(JNIEnv* env, jobject surfaceObj, jobject sessionObj,
27664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        jstring nameStr, jint w, jint h, jint format, jint flags) {
27764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    ScopedUtfChars name(env, nameStr);
27864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface = client->createSurface(
28164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            String8(name.c_str()), w, h, format, flags);
28264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) {
2838451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        jniThrowException(env, OutOfResourcesException, NULL);
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
28764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    setSurfaceControl(env, surfaceObj, surface);
28864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown}
2892e76c992bfa955cb637417005941e3e93810a99dDaniel Lam
29064a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeCreateFromSurfaceTexture(JNIEnv* env, jobject surfaceObj,
29164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        jobject surfaceTextureObj) {
29264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceTexture> st(SurfaceTexture_getSurfaceTexture(env, surfaceTextureObj));
2932e76c992bfa955cb637417005941e3e93810a99dDaniel Lam    if (st == NULL) {
2942e76c992bfa955cb637417005941e3e93810a99dDaniel Lam        jniThrowException(env, "java/lang/IllegalArgumentException",
2952e76c992bfa955cb637417005941e3e93810a99dDaniel Lam                "SurfaceTexture has already been released");
2962e76c992bfa955cb637417005941e3e93810a99dDaniel Lam        return;
2972e76c992bfa955cb637417005941e3e93810a99dDaniel Lam    }
29864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
2992e76c992bfa955cb637417005941e3e93810a99dDaniel Lam    sp<ISurfaceTexture> bq = st->getBufferQueue();
3002e76c992bfa955cb637417005941e3e93810a99dDaniel Lam
3012e76c992bfa955cb637417005941e3e93810a99dDaniel Lam    sp<Surface> surface(new Surface(bq));
3020de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg    if (surface == NULL) {
3030de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg        jniThrowException(env, OutOfResourcesException, NULL);
3040de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg        return;
3050de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg    }
3060de171b0d490a5928d54d2fb67c912d140aac643Ted Bonkenburg
30764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    setSurface(env, surfaceObj, surface);
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31064a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeRelease(JNIEnv* env, jobject surfaceObj) {
31164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    setSurfaceControl(env, surfaceObj, NULL);
31264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    setSurface(env, surfaceObj, NULL);
3138138cb49e47f9a9905a316a217757710185c66aaMarco Nelissen}
3148138cb49e47f9a9905a316a217757710185c66aaMarco Nelissen
31564a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeDestroy(JNIEnv* env, jobject surfaceObj) {
31664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surfaceControl(getSurfaceControl(env, surfaceObj));
31764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (SurfaceControl::isValid(surfaceControl)) {
31864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        surfaceControl->clear();
319402c34649f514669517c2208e35caa58ff8bb2b9Mathias Agopian    }
32064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    setSurfaceControl(env, surfaceObj, NULL);
32164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    setSurface(env, surfaceObj, NULL);
322402c34649f514669517c2208e35caa58ff8bb2b9Mathias Agopian}
323402c34649f514669517c2208e35caa58ff8bb2b9Mathias Agopian
32464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic jboolean nativeIsValid(JNIEnv* env, jobject surfaceObj) {
32564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surfaceControl(getSurfaceControl(env, surfaceObj));
32664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surfaceControl != NULL) {
32717f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian        return SurfaceControl::isValid(surfaceControl) ? JNI_TRUE : JNI_FALSE;
32817f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    }
32964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
33064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<Surface> surface(getSurface(env, surfaceObj));
331402c34649f514669517c2208e35caa58ff8bb2b9Mathias Agopian    return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
33464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic jint nativeGetIdentity(JNIEnv* env, jobject surfaceObj) {
33564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> control(getSurfaceControl(env, surfaceObj));
33664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (control != NULL) {
33764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return jint(control->getIdentity());
33864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
33964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
34064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<Surface> surface(getSurface(env, surfaceObj));
34164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface != NULL) {
34264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return jint(surface->getIdentity());
34364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
34464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
34564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return -1;
34664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown}
34764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
34864a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jobject surfaceObj) {
34964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<Surface> surface(getSurface(env, surfaceObj));
350c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian    if (!Surface::isValid(surface)) {
351c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian        doThrowIAE(env);
35264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return JNI_FALSE;
353c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian    }
35464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
35564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    int value = 0;
35664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
357c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian    anw->query(anw, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value);
35864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return value;
359c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian}
360c14bacf1fb511472138eeb5dc84a9423fc003214Mathias Agopian
36164a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
362f1e5b0d4e5d0d2a78c234cd0cbd3005a74a79429Mathias Agopian    /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        we can map to SkBitmap::kARGB_8888_Config, and optionally call
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    */
3668138cb49e47f9a9905a316a217757710185c66aaMarco Nelissen    switch (format) {
3678138cb49e47f9a9905a316a217757710185c66aaMarco Nelissen    case PIXEL_FORMAT_RGBX_8888:    return SkBitmap::kARGB_8888_Config;
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case PIXEL_FORMAT_RGBA_8888:    return SkBitmap::kARGB_8888_Config;
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case PIXEL_FORMAT_RGBA_4444:    return SkBitmap::kARGB_4444_Config;
3708138cb49e47f9a9905a316a217757710185c66aaMarco Nelissen    case PIXEL_FORMAT_RGB_565:      return SkBitmap::kRGB_565_Config;
3718138cb49e47f9a9905a316a217757710185c66aaMarco Nelissen    case PIXEL_FORMAT_A_8:          return SkBitmap::kA8_Config;
3728138cb49e47f9a9905a316a217757710185c66aaMarco Nelissen    default:                        return SkBitmap::kNo_Config;
3738138cb49e47f9a9905a316a217757710185c66aaMarco Nelissen    }
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
37664a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRectObj) {
37764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<Surface> surface(getSurface(env, surfaceObj));
378fea12b87f2988f20ea87314c4a1b47e1a0f4d95eRomain Guy    if (!Surface::isValid(surface)) {
3798451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
38064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return NULL;
381fea12b87f2988f20ea87314c4a1b47e1a0f4d95eRomain Guy    }
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // get dirty region
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Region dirtyRegion;
38564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (dirtyRectObj) {
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Rect dirty;
38764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        dirty.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left);
38864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        dirty.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top);
38964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        dirty.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right);
39064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        dirty.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom);
3916158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        if (!dirty.isEmpty()) {
3928451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes            dirtyRegion.set(dirty);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
39564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        dirtyRegion.set(Rect(0x3FFF, 0x3FFF));
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Surface::SurfaceInfo info;
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = surface->lock(&info, &dirtyRegion);
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err < 0) {
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        const char* const exception = (err == NO_MEMORY) ?
40264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                OutOfResourcesException :
40364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown                "java/lang/IllegalArgumentException";
4048451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        jniThrowException(env, exception, NULL);
40564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return NULL;
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Associate a SkCanvas object to this surface
40964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jobject canvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas);
41064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetIntField(canvasObj, gCanvasClassInfo.mSurfaceFormat, info.format);
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
41264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    SkCanvas* nativeCanvas = reinterpret_cast<SkCanvas*>(
41364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas));
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkBitmap bitmap;
4151473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    ssize_t bpr = info.s * bytesPerPixel(info.format);
4161473f46cbc82aa6f0ba744cc896a36923823d55bMathias Agopian    bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr);
417f1e5b0d4e5d0d2a78c234cd0cbd3005a74a79429Mathias Agopian    if (info.format == PIXEL_FORMAT_RGBX_8888) {
418f1e5b0d4e5d0d2a78c234cd0cbd3005a74a79429Mathias Agopian        bitmap.setIsOpaque(true);
419f1e5b0d4e5d0d2a78c234cd0cbd3005a74a79429Mathias Agopian    }
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (info.w > 0 && info.h > 0) {
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bitmap.setPixels(info.bits);
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // be safe with an empty bitmap.
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bitmap.setPixels(NULL);
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nativeCanvas->setBitmapDevice(bitmap);
4278451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
4286158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian    SkRegion clipReg;
4296158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian    if (dirtyRegion.isRect()) { // very common case
430a8a0aa8b922c45fb4633f51610f264a19f9bd825Mathias Agopian        const Rect b(dirtyRegion.getBounds());
4316158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        clipReg.setRect(b.left, b.top, b.right, b.bottom);
4326158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian    } else {
4336158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        size_t count;
4346158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        Rect const* r = dirtyRegion.getArray(&count);
4356158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        while (count) {
4366158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian            clipReg.op(r->left, r->top, r->right, r->bottom, SkRegion::kUnion_Op);
4376158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian            r++, count--;
4386158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        }
4396158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian    }
4406158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian
4416158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian    nativeCanvas->clipRegion(clipReg);
4428451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int saveCount = nativeCanvas->save();
44464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount, saveCount);
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
44664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (dirtyRectObj) {
4476158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        const Rect& bounds(dirtyRegion.getBounds());
44864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        env->SetIntField(dirtyRectObj, gRectClassInfo.left, bounds.left);
44964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        env->SetIntField(dirtyRectObj, gRectClassInfo.top, bounds.top);
45064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        env->SetIntField(dirtyRectObj, gRectClassInfo.right, bounds.right);
45164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, bounds.bottom);
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4538451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
45464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return canvasObj;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
45764a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jobject canvasObj) {
45864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    jobject ownCanvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas);
45964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (!env->IsSameObject(ownCanvasObj, canvasObj)) {
4608451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4638451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
46464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<Surface> surface(getSurface(env, surfaceObj));
46564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (!Surface::isValid(surface)) {
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
46764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // detach the canvas from the surface
47064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    SkCanvas* nativeCanvas = reinterpret_cast<SkCanvas*>(
47164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown            env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas));
47264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    int saveCount = env->GetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount);
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nativeCanvas->restoreToCount(saveCount);
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    nativeCanvas->setBitmapDevice(SkBitmap());
47564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount, 0);
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // unlock surface
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    status_t err = surface->unlockAndPost();
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (err < 0) {
4808451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
48464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,
48564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
48664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
48764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (displayToken == NULL) {
48864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return NULL;
489a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn    }
490a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn
4911f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
49264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (pixels->update(displayToken, width, height,
4930b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brown            minLayer, maxLayer, allLayers) != NO_ERROR) {
4941f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn        delete pixels;
49564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return NULL;
496a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn    }
497a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn
4981f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    uint32_t w = pixels->getWidth();
4991f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    uint32_t h = pixels->getHeight();
5001f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    uint32_t s = pixels->getStride();
5011f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    uint32_t f = pixels->getFormat();
5021f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    ssize_t bpr = s * android::bytesPerPixel(f);
5031f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn
5041f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    SkBitmap* bitmap = new SkBitmap();
5051f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    bitmap->setConfig(convertPixelFormat(f), w, h, bpr);
5061f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    if (f == PIXEL_FORMAT_RGBX_8888) {
5071f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn        bitmap->setIsOpaque(true);
5081f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    }
5091f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn
5101f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    if (w > 0 && h > 0) {
5111f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn        bitmap->setPixelRef(pixels)->unref();
5121f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn        bitmap->lockPixels();
5131f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    } else {
5141f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn        // be safe with an empty bitmap.
5151f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn        delete pixels;
5161f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn        bitmap->setPixels(NULL);
5171f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn    }
5181f5b195ed0f7f4a3398903fc064af1788c108badDianne Hackborn
519a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn    return GraphicsJNI::createBitmap(env, bitmap, false, NULL);
520a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn}
521a111187a5b4dc5d287e29ced7d65e8d20edca140Dianne Hackborn
52264a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
52364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    SurfaceComposerClient::openGlobalTransaction();
524d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn}
525d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn
52664a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeCloseTransaction(JNIEnv* env, jclass clazz) {
52764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    SurfaceComposerClient::closeGlobalTransaction();
528d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn}
529d2835935d2df8be70d1b37d3ef3b2fe0155b3422Dianne Hackborn
530b6ce6e42cc89864354c7ecb9ae80504a6c9dddcfJamie Gennisstatic void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
531b6ce6e42cc89864354c7ecb9ae80504a6c9dddcfJamie Gennis    SurfaceComposerClient::setAnimationTransaction();
532b6ce6e42cc89864354c7ecb9ae80504a6c9dddcfJamie Gennis}
533b6ce6e42cc89864354c7ecb9ae80504a6c9dddcfJamie Gennis
53464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetLayer(JNIEnv* env, jobject surfaceObj, jint zorder) {
53564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
53664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
53764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
53817f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    status_t err = surface->setLayer(zorder);
53964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
5408451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
5418451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
54464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetPosition(JNIEnv* env, jobject surfaceObj, jfloat x, jfloat y) {
54564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
54664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
54764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
54817f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    status_t err = surface->setPosition(x, y);
54964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
5508451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
5518451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
55464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetSize(JNIEnv* env, jobject surfaceObj, jint w, jint h) {
55564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
55664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
55764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
55817f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    status_t err = surface->setSize(w, h);
55964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
5608451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
5618451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
56464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetFlags(JNIEnv* env, jobject surfaceObj, jint flags, jint mask) {
56564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
56664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
56864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    status_t err = surface->setFlags(flags, mask);
56964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
5708451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
5718451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
57464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetTransparentRegionHint(JNIEnv* env, jobject surfaceObj, jobject regionObj) {
57564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
57664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
57764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
57864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
57964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (!region) {
5808451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
58164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return;
5828451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
58464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    const SkIRect& b(region->getBounds());
5856158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian    Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom));
58664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (region->isComplex()) {
58764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        SkRegion::Iterator it(*region);
5886158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        while (!it.done()) {
5896158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian            const SkIRect& r(it.rect());
5906158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian            reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom);
5916158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian            it.next();
5926158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian        }
5936158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian    }
5948451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
5956158b1bf0364da1582468a98ec09d004ba99deecMathias Agopian    status_t err = surface->setTransparentRegionHint(reg);
59664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
5978451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
5988451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60164a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetAlpha(JNIEnv* env, jobject surfaceObj, jfloat alpha) {
60264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
60364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
60464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
60517f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    status_t err = surface->setAlpha(alpha);
60664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
6078451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
6088451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
61164a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetMatrix(JNIEnv* env, jobject surfaceObj,
61264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) {
61364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
61464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
61564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
61617f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy);
61764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
6188451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes        doThrowIAE(env);
6198451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
62264a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetWindowCrop(JNIEnv* env, jobject surfaceObj, jobject cropObj) {
62364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    const sp<SurfaceControl>& surface(getSurfaceControl(env, surfaceObj));
62464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
62564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
62664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    Rect crop;
62764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (cropObj) {
62864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        crop.left = env->GetIntField(cropObj, gRectClassInfo.left);
62964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        crop.top = env->GetIntField(cropObj, gRectClassInfo.top);
63064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        crop.right = env->GetIntField(cropObj, gRectClassInfo.right);
63164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        crop.bottom = env->GetIntField(cropObj, gRectClassInfo.bottom);
63278b8ef3f3ad8ab935f677d8d672db0d97bff8119Jamie Gennis    } else {
63364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        crop.left = crop.top = crop.right = crop.bottom = 0;
63478b8ef3f3ad8ab935f677d8d672db0d97bff8119Jamie Gennis    }
63578b8ef3f3ad8ab935f677d8d672db0d97bff8119Jamie Gennis
63664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    status_t err = surface->setCrop(crop);
63764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
63878b8ef3f3ad8ab935f677d8d672db0d97bff8119Jamie Gennis        doThrowIAE(env);
63978b8ef3f3ad8ab935f677d8d672db0d97bff8119Jamie Gennis    }
64078b8ef3f3ad8ab935f677d8d672db0d97bff8119Jamie Gennis}
64178b8ef3f3ad8ab935f677d8d672db0d97bff8119Jamie Gennis
64264a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetLayerStack(JNIEnv* env, jobject surfaceObj, jint layerStack) {
64364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
64464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (surface == NULL) return;
64564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
6460b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brown    status_t err = surface->setLayerStack(layerStack);
64764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (err < 0 && err != NO_INIT) {
6480b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brown        doThrowIAE(env);
6490b722fe9ce98d97dbcb6fefd170b85ab7037e528Jeff Brown    }
6509de4936c99b979f6010440b043edc6d6142d1980Craig Mautner}
6519de4936c99b979f6010440b043edc6d6142d1980Craig Mautner
65264a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
65364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
65464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return javaObjectForIBinder(env, token);
65564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown}
65617f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian
6577bbf8163fb83afc54b353a8def52bfb87ecce047Jamie Gennisstatic jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
6587bbf8163fb83afc54b353a8def52bfb87ecce047Jamie Gennis        jboolean secure) {
65964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    ScopedUtfChars name(env, nameObj);
6607bbf8163fb83afc54b353a8def52bfb87ecce047Jamie Gennis    sp<IBinder> token(SurfaceComposerClient::createDisplay(
6617bbf8163fb83afc54b353a8def52bfb87ecce047Jamie Gennis            String8(name.c_str()), bool(secure)));
66264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return javaObjectForIBinder(env, token);
66364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown}
66464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
66564a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
666cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        jobject tokenObj, jobject surfaceObj) {
66764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
66864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (token == NULL) return;
66964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
670cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    sp<ISurfaceTexture> surfaceTexture(getISurfaceTexture(env, surfaceObj));
671cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    SurfaceComposerClient::setDisplaySurface(token, surfaceTexture);
67264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown}
67364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
67464a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
67564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        jobject tokenObj, jint layerStack) {
67664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
67764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (token == NULL) return;
67864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
67964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    SurfaceComposerClient::setDisplayLayerStack(token, layerStack);
68064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown}
68164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
68263f1c43fbef157397869475ef30d23e631b88bbeMathias Agopianstatic void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
683cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown        jobject tokenObj, jint orientation, jobject layerStackRectObj, jobject displayRectObj) {
68464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
68564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (token == NULL) return;
68664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
687cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    Rect layerStackRect;
688cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    layerStackRect.left = env->GetIntField(layerStackRectObj, gRectClassInfo.left);
689cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    layerStackRect.top = env->GetIntField(layerStackRectObj, gRectClassInfo.top);
690cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    layerStackRect.right = env->GetIntField(layerStackRectObj, gRectClassInfo.right);
691cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    layerStackRect.bottom = env->GetIntField(layerStackRectObj, gRectClassInfo.bottom);
69264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
693cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    Rect displayRect;
694cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    displayRect.left = env->GetIntField(displayRectObj, gRectClassInfo.left);
695cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    displayRect.top = env->GetIntField(displayRectObj, gRectClassInfo.top);
696cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    displayRect.right = env->GetIntField(displayRectObj, gRectClassInfo.right);
697cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    displayRect.bottom = env->GetIntField(displayRectObj, gRectClassInfo.bottom);
69864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
699cbad976b2a36a0895ca94510d5208a86f66cf596Jeff Brown    SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect);
70064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown}
70164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
70264a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic jboolean nativeGetDisplayInfo(JNIEnv* env, jclass clazz,
70364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        jobject tokenObj, jobject infoObj) {
70464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
70564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (token == NULL) return JNI_FALSE;
70664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
70764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    DisplayInfo info;
70864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (SurfaceComposerClient::getDisplayInfo(token, &info)) {
70964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        return JNI_FALSE;
71064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    }
71164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
71264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w);
71364a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h);
71464a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps);
71564a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density);
71664a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi);
71764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi);
71895429c3d1b8113c23b0aad3b74d724dccfad7fa9Jamie Gennis    env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure);
71964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    return JNI_TRUE;
72064a55af0ac700baecb0877235eb42caac59a3560Jeff Brown}
72164a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
7229e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brownstatic void nativeBlankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
7239e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
7249e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    if (token == NULL) return;
7259e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
7269e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    ALOGD_IF_SLOW(100, "Excessive delay in blankDisplay() while turning screen off");
7279e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    SurfaceComposerClient::blankDisplay(token);
7289e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown}
7299e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
7309e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brownstatic void nativeUnblankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
7319e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
7329e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    if (token == NULL) return;
7339e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
7349e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    ALOGD_IF_SLOW(100, "Excessive delay in unblankDisplay() while turning screen on");
7359e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown    SurfaceComposerClient::unblankDisplay(token);
7369e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown}
7379e316a1a2a8d734315bbd56a85308f9657a92913Jeff Brown
73864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown// ----------------------------------------------------------------------------
73964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown
74064a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeCopyFrom(JNIEnv* env, jobject surfaceObj, jobject otherObj) {
74117f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian    /*
74217f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian     * This is used by the WindowManagerService just after constructing
74317f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian     * a Surface and is necessary for returning the Surface reference to
74417f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian     * the caller. At this point, we should only have a SurfaceControl.
74517f638b39f2e8b610ecfa1290e5bc42ab7700c98Mathias Agopian     */
746fae5cb2b356a1fef172b43066180a7ab4c32dbacMathias Agopian
74764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
74864a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> other(getSurfaceControl(env, otherObj));
74964a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    if (!SurfaceControl::isSameSurface(surface, other)) {
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // we reassign the surface only if it's a different one
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // otherwise we would loose our client-side state.
75264a55af0ac700baecb0877235eb42caac59a3560Jeff Brown        setSurfaceControl(env, surfaceObj, other);
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
75664a55af0ac700baecb0877235eb42caac59a3560Jeff Brownstatic void nativeTransferFrom(JNIEnv* env, jobject surfaceObj, jobject otherObj) {
75764a55af0ac700baecb0877235eb42caac59a3560Jeff Brown    sp<SurfaceControl> control(getSurfaceControl(env, otherObj));
758