1 /* 2 * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "config.h" 27 28 #include <wtf/java/JavaEnv.h> 29 #include "RenderingQueue.h" 30 #include "RQRef.h" 31 32 #include <wtf/java/JavaRef.h> 33 #include <wtf/HashMap.h> 34 #include <wtf/NeverDestroyed.h> 35 36 #include "com_sun_webkit_graphics_WCRenderQueue.h" 37 38 namespace WebCore { 39 40 typedef HashMap<char*, RefPtr<ByteBuffer> > Addr2ByteBuffer; 41 42 static Addr2ByteBuffer& getAddr2ByteBuffer() 43 { 44 static NeverDestroyed<Addr2ByteBuffer> container; 45 return container.get(); 46 } 47 48 /*static*/ 49 RefPtr<RenderingQueue> RenderingQueue::create( 50 const JLObject &jRQ, 51 int capacity, 52 bool autoFlush) 53 { 54 return adoptRef(new RenderingQueue( 55 jRQ, 56 capacity, 57 autoFlush)); 58 } 59 60 RenderingQueue& RenderingQueue::freeSpace(int size) { 61 if (m_buffer && !m_buffer->hasFreeSpace(size)) { 62 flushBuffer(); 63 if (m_autoFlush) { 64 flush(); 65 } 66 } 67 if (!m_buffer) { 68 m_buffer = RefPtr<ByteBuffer>(ByteBuffer::create(std::max(m_capacity, size))); 69 } 70 return *this; 71 } 72 73 void RenderingQueue::flush() { 74 JNIEnv* env = WebCore_GetJavaEnv(); 75 76 static jmethodID midFwkFlush = env->GetMethodID( 77 PG_GetRenderQueueClass(env), "fwkFlush", "()V"); 78 ASSERT(midFwkFlush); 79 80 env->CallVoidMethod(getWCRenderingQueue(), midFwkFlush); 81 CheckAndClearException(env); 82 } 83 84 void RenderingQueue::disposeGraphics() { 85 JNIEnv* env = WebCore_GetJavaEnv(); 86 // The method is called from the dtor which potentially can be called after VM detach. 87 // So the check for nullptr. 88 if (!env) 89 return; 90 91 static jmethodID midFwkDisposeGraphics = env->GetMethodID( 92 PG_GetRenderQueueClass(env), "fwkDisposeGraphics", "()V"); 93 ASSERT(midFwkDisposeGraphics); 94 95 env->CallVoidMethod(getWCRenderingQueue(), midFwkDisposeGraphics); 96 CheckAndClearException(env); 97 } 98 99 /* 100 * The method is called on Event thread (so, it's not concurrent with JS and the release of resources). 101 */ 102 RenderingQueue& RenderingQueue::flushBuffer() { 103 if (isEmpty()) { 104 return *this; 105 } 106 JNIEnv* env = WebCore_GetJavaEnv(); 107 108 static jmethodID midFwkAddBuffer = env->GetMethodID(PG_GetRenderQueueClass(env), 109 "fwkAddBuffer", "(Ljava/nio/ByteBuffer;)V"); 110 ASSERT(midFwkAddBuffer); 111 112 Addr2ByteBuffer &a2bb = getAddr2ByteBuffer(); 113 a2bb.set(m_buffer->bufferAddress(), m_buffer); 114 env->CallVoidMethod( 115 getWCRenderingQueue(), 116 midFwkAddBuffer, 117 (jobject)(m_buffer->createDirectByteBuffer(env))); 118 CheckAndClearException(env); 119 120 m_buffer = nullptr; 121 122 return *this; 123 } 124 } 125 126 using namespace WebCore; 127 128 extern "C" { 129 130 JNIEXPORT void JNICALL Java_com_sun_webkit_graphics_WCRenderQueue_twkRelease 131 (JNIEnv* env, jobject, jobjectArray bufs) 132 { 133 /* 134 * This method should be called on the Event thread to synchronize with JavaScript 135 * by thread. JavaScript may access resources kept in ByteBuffer::m_refList, 136 * so when a resource is dereferenced (as a result of ByteBuffer destruction) 137 * it should be thread safe. 138 */ 139 Addr2ByteBuffer& a2bb = getAddr2ByteBuffer(); 140 for (int i = 0; i < env->GetArrayLength(bufs); ++i) { 141 char *key = (char *)env->GetDirectBufferAddress( 142 JLObject(env->GetObjectArrayElement(bufs, i))); 143 if (key != 0) { 144 a2bb.remove(key); 145 } 146 } 147 } 148 149 }