Move inval dedup to Window for wider usages.

It turns out that the inval dedup is not just useful for Android.  Hence
we move it up to the Window level so more OSes such as Linux, Windows
can also use it.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2001153002

Review-Url: https://codereview.chromium.org/2001153002
This commit is contained in:
liyuqian 2016-05-23 10:52:34 -07:00 committed by Commit bot
parent 888dc16684
commit 566c8e4a36
8 changed files with 42 additions and 33 deletions

View File

@ -63,6 +63,7 @@ bool Window::onTouch(int owner, InputState state, float x, float y) {
}
void Window::onPaint() {
markInvalProcessed();
sk_sp<SkSurface> backbuffer = fWindowContext->getBackbufferSurface();
if (backbuffer) {
// draw into the canvas of this surface
@ -92,4 +93,15 @@ void Window::setDisplayParams(const DisplayParams& params) {
fWindowContext->setDisplayParams(params);
}
void Window::inval() {
if (!fIsContentInvalidated) {
fIsContentInvalidated = true;
onInval();
}
}
void Window::markInvalProcessed() {
fIsContentInvalidated = false;
}
} // namespace sk_app

View File

@ -27,7 +27,11 @@ public:
virtual void setTitle(const char*) = 0;
virtual void show() = 0;
virtual void inval() = 0;
// Shedules an invalidation event for window if one is not currently pending.
// Make sure that either onPaint or markInvalReceived is called when the client window consumes
// the the inval event. They unset fIsContentInvalided which allow future onInval.
void inval();
virtual bool scaleContentToFit() const { return false; }
virtual bool supportsContentRect() const { return false; }
@ -164,6 +168,13 @@ protected:
void* fPaintUserData;
WindowContext* fWindowContext = nullptr;
virtual void onInval() = 0;
// Uncheck fIsContentInvalided to allow future inval/onInval.
void markInvalProcessed();
bool fIsContentInvalidated = false; // use this to avoid duplicate invalidate events
};
} // namespace sk_app

View File

@ -64,8 +64,16 @@ void Window_android::onDisplayDestroyed() {
detach();
}
void Window_android::inval() {
fSkiaAndroidApp->inval();
void Window_android::onInval() {
fSkiaAndroidApp->postMessage(Message(kContentInvalidated));
}
void Window_android::paintIfNeeded() {
if (fWindowContext) { // Check if initDisplay has already been called
onPaint();
} else {
markInvalProcessed();
}
}
} // namespace sk_app

View File

@ -27,7 +27,9 @@ public:
void show() override {}
bool attach(BackendType attachType, const DisplayParams& params) override;
void inval() override;
void onInval() override;
void paintIfNeeded();
bool scaleContentToFit() const override { return true; }
bool supportsContentRect() const override { return true; }

View File

@ -70,12 +70,6 @@ void SkiaAndroidApp::setTitle(const char* title) const {
fPThreadEnv->DeleteLocalRef(titleString);
}
void SkiaAndroidApp::paintIfNeeded() {
if (fNativeWindow && fWindow) {
fWindow->onPaint();
}
}
void SkiaAndroidApp::postMessage(const Message& message) const {
SkDEBUGCODE(auto writeSize =) write(fPipes[1], &message, sizeof(message));
SkASSERT(writeSize == sizeof(message));
@ -86,14 +80,6 @@ void SkiaAndroidApp::readMessage(Message* message) const {
SkASSERT(readSize == sizeof(Message));
}
void SkiaAndroidApp::inval() {
SkAutoMutexAcquire ama(fMutex);
if (!fIsContentInvalidated) {
postMessage(Message(kContentInvalidated));
fIsContentInvalidated = true;
}
}
int SkiaAndroidApp::message_callback(int fd, int events, void* data) {
auto skiaAndroidApp = (SkiaAndroidApp*)data;
Message message;
@ -108,9 +94,7 @@ int SkiaAndroidApp::message_callback(int fd, int events, void* data) {
return 0;
}
case kContentInvalidated: {
SkAutoMutexAcquire ama(skiaAndroidApp->fMutex);
skiaAndroidApp->fIsContentInvalidated = false;
skiaAndroidApp->paintIfNeeded();
((Window_android*)skiaAndroidApp->fWindow)->paintIfNeeded();
break;
}
case kSurfaceCreated: {
@ -118,7 +102,7 @@ int SkiaAndroidApp::message_callback(int fd, int events, void* data) {
skiaAndroidApp->fNativeWindow = message.fNativeWindow;
auto window_android = (Window_android*)skiaAndroidApp->fWindow;
window_android->initDisplay(skiaAndroidApp->fNativeWindow);
skiaAndroidApp->paintIfNeeded();
((Window_android*)skiaAndroidApp->fWindow)->paintIfNeeded();
break;
}
case kSurfaceChanged: {
@ -128,7 +112,7 @@ int SkiaAndroidApp::message_callback(int fd, int events, void* data) {
int height = ANativeWindow_getHeight(skiaAndroidApp->fNativeWindow);
auto window_android = (Window_android*)skiaAndroidApp->fWindow;
window_android->setContentRect(0, 0, width, height);
skiaAndroidApp->paintIfNeeded();
window_android->paintIfNeeded();
break;
}
case kSurfaceDestroyed: {

View File

@ -12,7 +12,6 @@
#include <android/native_window_jni.h>
#include "../private/SkMutex.h"
#include "../Application.h"
#include "../Window.h"
@ -49,14 +48,10 @@ struct SkiaAndroidApp {
void postMessage(const Message& message) const;
void readMessage(Message* message) const;
void paintIfNeeded();
// This must be called in SkiaAndroidApp's own pthread because the JNIEnv is thread sensitive
void setTitle(const char* title) const;
// This posts a kContentInvalidated message if there's no such message currently in the queue
void inval();
private:
pthread_t fThread;
ANativeWindow* fNativeWindow;
@ -65,9 +60,6 @@ private:
JNIEnv* fPThreadEnv;
jmethodID fSetTitleMethodID;
bool fIsContentInvalidated = false; // use this to avoid duplicate invalidate events
SkMutex fMutex;
// This must be called in SkiaAndroidApp's own pthread because the JNIEnv is thread sensitive
~SkiaAndroidApp();

View File

@ -284,7 +284,7 @@ bool Window_win::attach(BackendType attachType, const DisplayParams& params) {
return (SkToBool(fWindowContext));
}
void Window_win::inval() {
void Window_win::onInval() {
InvalidateRect(fHWnd, nullptr, false);
}

View File

@ -31,7 +31,7 @@ public:
bool attach(BackendType attachType, const DisplayParams& params) override;
void inval() override;
void onInval() override;
private:
HINSTANCE fHInstance;