Implement Raster Backend on Android Viewer App
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2041193004 Review-Url: https://codereview.chromium.org/2041193004
This commit is contained in:
parent
93e3fff79e
commit
d94ad5823b
@ -1,6 +1,7 @@
|
||||
package org.skia.viewer;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
@ -30,6 +31,7 @@ public class StateAdapter extends BaseAdapter implements AdapterView.OnItemSelec
|
||||
static final String NAME = "name";
|
||||
static final String VALUE = "value";
|
||||
static final String OPTIONS = "options";
|
||||
private static final String BACKEND_STATE_NAME = "Backend";
|
||||
|
||||
ViewerActivity mViewerActivity;
|
||||
LinearLayout mLayout;
|
||||
@ -146,6 +148,21 @@ public class StateAdapter extends BaseAdapter implements AdapterView.OnItemSelec
|
||||
stateItem.setTag(null); // Reset the tag to let updateDrawer update this item view.
|
||||
mViewerActivity.onStateChanged(stateName, stateValue);
|
||||
}
|
||||
|
||||
// Due to the current Android limitation, we're required to recreate the SurfaceView for
|
||||
// switching to/from the Raster backend.
|
||||
// (Although we can switch between GPU backend without recreating the SurfaceView.)
|
||||
final Object oldValue = stateItem.getTag(R.integer.value_tag_key);
|
||||
if (stateName.equals(BACKEND_STATE_NAME)
|
||||
&& oldValue != null && !stateValue.equals(oldValue)) {
|
||||
LinearLayout mainLayout = (LinearLayout) mViewerActivity.findViewById(R.id.mainLayout);
|
||||
mainLayout.removeAllViews();
|
||||
SurfaceView surfaceView = new SurfaceView(mViewerActivity);
|
||||
surfaceView.setId(R.id.surfaceView);
|
||||
surfaceView.getHolder().addCallback(mViewerActivity);
|
||||
surfaceView.setOnTouchListener(mViewerActivity);
|
||||
mainLayout.addView(surfaceView);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,7 +32,6 @@ public class ViewerActivity
|
||||
private ListView mDrawerList;
|
||||
private StateAdapter mStateAdapter;
|
||||
|
||||
private SurfaceView mView;
|
||||
private ViewerApplication mApplication;
|
||||
|
||||
private native void onSurfaceCreated(long handle, Surface surface);
|
||||
@ -74,10 +73,9 @@ public class ViewerActivity
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
mView = (SurfaceView) findViewById(R.id.surfaceView);
|
||||
mView.getHolder().addCallback(this);
|
||||
|
||||
mView.setOnTouchListener(this);
|
||||
SurfaceView surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
|
||||
surfaceView.getHolder().addCallback(this);
|
||||
surfaceView.setOnTouchListener(this);
|
||||
|
||||
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
|
||||
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
|
||||
|
@ -57,7 +57,8 @@ DEFINE_bool(vulkan, true, "Run with Vulkan.");
|
||||
|
||||
const char *kBackendTypeStrings[sk_app::Window::kBackendTypeCount] = {
|
||||
" [OpenGL]",
|
||||
" [Vulkan]"
|
||||
" [Vulkan]",
|
||||
" [Raster]"
|
||||
};
|
||||
|
||||
const char* kName = "name";
|
||||
|
29
tools/viewer/sk_app/RasterWindowContext.h
Normal file
29
tools/viewer/sk_app/RasterWindowContext.h
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef RasterWindowContext_DEFINED
|
||||
#define RasterWindowContext_DEFINED
|
||||
|
||||
#include "WindowContext.h"
|
||||
|
||||
namespace sk_app {
|
||||
|
||||
class RasterWindowContext : public WindowContext {
|
||||
public:
|
||||
// This is defined in the platform .cpp file
|
||||
static RasterWindowContext* Create(void* platformData, const DisplayParams& params);
|
||||
|
||||
// Explicitly convert nullptr to GrBackendContext is needed for compiling
|
||||
GrBackendContext getBackendContext() override { return (GrBackendContext) nullptr; }
|
||||
|
||||
protected:
|
||||
bool isGpuContext() override { return false; }
|
||||
};
|
||||
|
||||
} // namespace sk_app
|
||||
|
||||
#endif
|
@ -42,8 +42,9 @@ public:
|
||||
enum BackendType {
|
||||
kNativeGL_BackendType,
|
||||
kVulkan_BackendType,
|
||||
kRaster_BackendType,
|
||||
|
||||
kLast_BackendType = kVulkan_BackendType
|
||||
kLast_BackendType = kRaster_BackendType
|
||||
};
|
||||
enum {
|
||||
kBackendTypeCount = kLast_BackendType + 1
|
||||
|
69
tools/viewer/sk_app/android/RasterWindowContext_android.cpp
Normal file
69
tools/viewer/sk_app/android/RasterWindowContext_android.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "RasterWindowContext_android.h"
|
||||
|
||||
#include "SkSurface.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
#include "Window_android.h"
|
||||
|
||||
namespace sk_app {
|
||||
|
||||
RasterWindowContext* RasterWindowContext::Create(void* platformData, const DisplayParams& params) {
|
||||
RasterWindowContext* ctx = new RasterWindowContext_android(platformData, params);
|
||||
if (!ctx->isValid()) {
|
||||
delete ctx;
|
||||
ctx = nullptr;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
RasterWindowContext_android::RasterWindowContext_android(
|
||||
void* platformData, const DisplayParams& params) {
|
||||
fDisplayParams = params;
|
||||
ContextPlatformData_android* androidPlatformData =
|
||||
reinterpret_cast<ContextPlatformData_android*>(platformData);
|
||||
fNativeWindow = androidPlatformData->fNativeWindow;
|
||||
fWidth = ANativeWindow_getWidth(fNativeWindow);
|
||||
fHeight = ANativeWindow_getHeight(fNativeWindow);
|
||||
int32_t format;
|
||||
switch(params.fColorType) {
|
||||
case kRGBA_8888_SkColorType:
|
||||
format = WINDOW_FORMAT_RGBA_8888;
|
||||
break;
|
||||
case kRGB_565_SkColorType:
|
||||
format = WINDOW_FORMAT_RGB_565;
|
||||
break;
|
||||
default:
|
||||
SkDEBUGFAIL("Unsupported Android color type");
|
||||
}
|
||||
ANativeWindow_setBuffersGeometry(fNativeWindow, fWidth, fHeight, format);
|
||||
}
|
||||
|
||||
sk_sp<SkSurface> RasterWindowContext_android::getBackbufferSurface() {
|
||||
if (nullptr == fBackbufferSurface) {
|
||||
ANativeWindow_lock(fNativeWindow, &fBuffer, &fBounds);
|
||||
const int bytePerPixel = fBuffer.format == WINDOW_FORMAT_RGB_565 ? 2 : 4;
|
||||
SkImageInfo info = SkImageInfo::Make(fWidth, fHeight,
|
||||
fDisplayParams.fColorType,
|
||||
kOpaque_SkAlphaType,
|
||||
fDisplayParams.fProfileType);
|
||||
fBackbufferSurface = SkSurface::MakeRasterDirect(
|
||||
info, fBuffer.bits, fBuffer.stride * bytePerPixel, nullptr);
|
||||
}
|
||||
return fBackbufferSurface;
|
||||
}
|
||||
|
||||
|
||||
void RasterWindowContext_android::swapBuffers() {
|
||||
ANativeWindow_unlockAndPost(fNativeWindow);
|
||||
fBackbufferSurface.reset(nullptr);
|
||||
}
|
||||
|
||||
} // namespace sk_app
|
43
tools/viewer/sk_app/android/RasterWindowContext_android.h
Normal file
43
tools/viewer/sk_app/android/RasterWindowContext_android.h
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
/*
|
||||
* Copyright 2016 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef RasterWindowContext_android_DEFINED
|
||||
#define RasterWindowContext_android_DEFINED
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#include "../RasterWindowContext.h"
|
||||
|
||||
namespace sk_app {
|
||||
|
||||
class RasterWindowContext_android : public RasterWindowContext {
|
||||
public:
|
||||
friend RasterWindowContext* RasterWindowContext::Create(
|
||||
void* platformData, const DisplayParams&);
|
||||
|
||||
sk_sp<SkSurface> getBackbufferSurface() override;
|
||||
void swapBuffers() override;
|
||||
|
||||
bool isValid() override { return SkToBool(fNativeWindow); }
|
||||
void resize(uint32_t w, uint32_t h) override {
|
||||
SkDEBUGFAIL("Resize is currently unsupported.");
|
||||
}
|
||||
void setDisplayParams(const DisplayParams& params) override {
|
||||
SkDEBUGFAIL("setDisplayParams is currently unsupported.");
|
||||
}
|
||||
|
||||
private:
|
||||
RasterWindowContext_android(void* platformData, const DisplayParams& params);
|
||||
sk_sp<SkSurface> fBackbufferSurface = nullptr;
|
||||
ANativeWindow* fNativeWindow = nullptr;
|
||||
ANativeWindow_Buffer fBuffer;
|
||||
ARect fBounds;
|
||||
};
|
||||
|
||||
} // namespace sk_app
|
||||
|
||||
#endif
|
@ -8,6 +8,7 @@
|
||||
#include "Window_android.h"
|
||||
#include "../GLWindowContext.h"
|
||||
#include "../VulkanWindowContext.h"
|
||||
#include "../RasterWindowContext.h"
|
||||
|
||||
namespace sk_app {
|
||||
|
||||
@ -49,11 +50,7 @@ bool Window_android::attach(BackendType attachType, const DisplayParams& params)
|
||||
fBackendType = attachType;
|
||||
fDisplayParams = params;
|
||||
|
||||
if (fNativeWindow) {
|
||||
this->initDisplay(fNativeWindow);
|
||||
}
|
||||
// If fNativeWindow is not set,
|
||||
// we delay the creation of fWindowContext until Android informs us that
|
||||
// We delay the creation of fWindowContext until Android informs us that
|
||||
// the native window is ready to use.
|
||||
// The creation will be done in initDisplay, which is initiated by kSurfaceCreated event.
|
||||
return true;
|
||||
@ -61,14 +58,15 @@ bool Window_android::attach(BackendType attachType, const DisplayParams& params)
|
||||
|
||||
void Window_android::initDisplay(ANativeWindow* window) {
|
||||
SkASSERT(window);
|
||||
fNativeWindow = window;
|
||||
ContextPlatformData_android platformData;
|
||||
platformData.fNativeWindow = window;
|
||||
switch (fBackendType) {
|
||||
case kNativeGL_BackendType:
|
||||
fWindowContext = GLWindowContext::Create((void*)&platformData, fDisplayParams);
|
||||
break;
|
||||
|
||||
case kRaster_BackendType:
|
||||
fWindowContext = RasterWindowContext::Create((void*)&platformData, fDisplayParams);
|
||||
break;
|
||||
case kVulkan_BackendType:
|
||||
default:
|
||||
fWindowContext = VulkanWindowContext::Create((void*)&platformData, fDisplayParams);
|
||||
@ -78,7 +76,6 @@ void Window_android::initDisplay(ANativeWindow* window) {
|
||||
|
||||
void Window_android::onDisplayDestroyed() {
|
||||
detach();
|
||||
fNativeWindow = nullptr;
|
||||
}
|
||||
|
||||
void Window_android::onInval() {
|
||||
|
@ -44,9 +44,6 @@ public:
|
||||
void setContentRect(int l, int t, int r, int b) { fContentRect.set(l,t,r,b); }
|
||||
|
||||
private:
|
||||
// We need fNativeWindow for attaching with another backend.
|
||||
// (in that case, attach is called without initDisplay being called later)
|
||||
ANativeWindow* fNativeWindow = nullptr;
|
||||
SkiaAndroidApp* fSkiaAndroidApp = nullptr;
|
||||
SkRect fContentRect;
|
||||
DisplayParams fDisplayParams;
|
||||
|
Loading…
Reference in New Issue
Block a user